Skip to content

Commit 7de19e5

Browse files
authored
Merge pull request #1306 from w3bdesign/develop
Improve single product design and responsiveness
2 parents dd438db + 5c824ba commit 7de19e5

File tree

4 files changed

+36
-32
lines changed

4 files changed

+36
-32
lines changed

src/components/Layout/PageTitle.component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface IPageTitleProps {
1313
const PageTitle = ({ title, marginLeft }: IPageTitleProps) => (
1414
<section
1515
className={`container ${
16-
marginLeft ? 'pl-8' : 'pl-4'
16+
marginLeft ? 'p-4' : 'p-0'
1717
} pl-4 mx-auto mt-24 text-center bg-white`}
1818
>
1919
<span className="py-2 text-2xl font-bold tracking-wide text-center text-gray-800 no-underline uppercase hover:no-underline">

src/components/Product/AddToCart.component.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,18 @@ export interface IProduct {
8080
export interface IProductRootObject {
8181
product: IProduct;
8282
variationId?: number;
83+
fullWidth?: boolean;
8384
}
8485

8586
/**
8687
* Handles the Add to cart functionality.
8788
* Uses GraphQL for product data
8889
* @param {IAddToCartProps} product // Product data
90+
* @param {number} variationId // Variation ID
91+
* @param {boolean} fullWidth // Whether the button should be full-width
8992
*/
9093

91-
const AddToCart = ({ product, variationId }: IProductRootObject) => {
94+
const AddToCart = ({ product, variationId, fullWidth = false }: IProductRootObject) => {
9295
const { setCart } = useContext(CartContext);
9396
const [requestError, setRequestError] = useState<boolean>(false);
9497

@@ -146,6 +149,7 @@ const AddToCart = ({ product, variationId }: IProductRootObject) => {
146149
<Button
147150
handleButtonClick={() => handleAddToCart()}
148151
buttonDisabled={addToCartLoading || requestError}
152+
fullWidth={fullWidth}
149153
>
150154
KJØP
151155
</Button>

src/components/Product/SingleProduct.component.tsx

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const SingleProduct = ({ product }: IProductRootObject) => {
5757
<LoadingSpinner />
5858
</div>
5959
) : (
60-
<div className="container flex flex-wrap items-center pt-4 pb-12 mx-auto ">
60+
<div className="container flex flex-wrap items-center pt-4 pb-12 mx-auto">
6161
<div className="grid grid-cols-1 gap-4 md:mt-16 lg:grid-cols-2 xl:grid-cols-2 md:grid-cols-2 sm:grid-cols-2">
6262
{image && (
6363
<img
@@ -78,45 +78,44 @@ const SingleProduct = ({ product }: IProductRootObject) => {
7878
className="h-auto p-8 transition duration-500 ease-in-out transform xl:p-2 md:p-2 lg:p-2 md:hover:grow md:hover:shadow-lg md:hover:scale-105"
7979
/>
8080
)}
81-
<div className="ml-8">
82-
<p className="text-3xl font-bold text-center md:text-left">{name}</p>
83-
<br />
81+
<div className="px-4 md:ml-8">
82+
<h1 className="text-3xl font-bold text-center md:text-left mb-4">
83+
{name}
84+
</h1>
8485
{/* Display sale price when on sale */}
8586
{onSale && (
86-
<div className="flex">
87-
<p className="pt-1 mt-4 text-3xl text-gray-900">
87+
<div className="flex flex-col md:flex-row items-center md:items-start mb-4">
88+
<p className="text-3xl font-bold text-red-600">
8889
{product.variations && filteredVariantPrice(price, '')}
8990
{!product.variations && salePrice}
9091
</p>
91-
<p className="pt-1 pl-8 mt-4 text-2xl text-gray-900 line-through">
92+
<p className="text-xl text-gray-500 line-through md:ml-4">
9293
{product.variations && filteredVariantPrice(price, 'right')}
9394
{!product.variations && regularPrice}
9495
</p>
9596
</div>
9697
)}
9798
{/* Display regular price when not on sale */}
9899
{!onSale && (
99-
<p className="pt-1 mt-4 text-2xl text-gray-900"> {price}</p>
100+
<p className="text-2xl font-bold mb-4">{price}</p>
100101
)}
101-
<br />
102-
<p className="pt-1 mt-4 text-2xl text-gray-900">
103-
{DESCRIPTION_WITHOUT_HTML}
104-
</p>
102+
<p className="text-lg mb-4 text-center md:text-left">{DESCRIPTION_WITHOUT_HTML}</p>
105103
{Boolean(product.stockQuantity) && (
106-
<p
107-
v-if="data.product.stockQuantity"
108-
className="pt-1 mt-4 mb-4 text-2xl text-gray-900"
109-
>
110-
{product.stockQuantity} på lager
111-
</p>
104+
<div className="mb-4 p-2 bg-green-100 border border-green-400 rounded-lg mx-auto md:mx-0 max-w-[14.375rem]">
105+
<p className="text-lg text-green-700 font-semibold text-center md:text-left">
106+
{product.stockQuantity} på lager
107+
</p>
108+
</div>
112109
)}
113110
{product.variations && (
114-
<p className="pt-1 mt-4 text-xl text-gray-900">
115-
<span className="py-2">Varianter</span>
111+
<div className="mb-4">
112+
<label htmlFor="variant" className="block text-lg font-medium mb-2">
113+
Varianter
114+
</label>
116115
<select
117116
id="variant"
118117
name="variant"
119-
className="block w-80 px-6 py-2 bg-white border border-gray-500 rounded-lg focus:outline-none focus:shadow-outline"
118+
className="block w-full px-4 py-2 bg-white border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
120119
onChange={(e) => {
121120
setSelectedVariation(Number(e.target.value));
122121
}}
@@ -133,20 +132,17 @@ const SingleProduct = ({ product }: IProductRootObject) => {
133132
},
134133
)}
135134
</select>
136-
</p>
135+
</div>
137136
)}
138-
<div className="pt-1 mt-2">
139-
{
140-
// Display default AddToCart button if we do not have variations.
141-
// If we do, send the variationId to AddToCart button
142-
}
137+
<div className="w-full p-4 md:p-0">
143138
{product.variations && (
144139
<AddToCart
145140
product={product}
146141
variationId={selectedVariation}
142+
fullWidth={true}
147143
/>
148144
)}
149-
{!product.variations && <AddToCart product={product} />}
145+
{!product.variations && <AddToCart product={product} fullWidth={true} />}
150146
</div>
151147
</div>
152148
</div>

src/components/UI/Button.component.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,25 @@ interface IButtonProps {
77
buttonDisabled?: boolean;
88
color?: TButtonColors;
99
children: ReactNode;
10+
fullWidth?: boolean;
1011
}
1112

1213
/**
1314
* Renders a clickable button
14-
* @function PageTitle
15+
* @function Button
1516
* @param {void} handleButtonClick - Handle button click
1617
* @param {boolean?} buttonDisabled - Is button disabled?
17-
* @param {color?} TButtonColors - Color for button, either red or blue
18+
* @param {TButtonColors?} color - Color for button, either red or blue
1819
* @param {ReactNode} children - Children for button
20+
* @param {boolean?} fullWidth - Whether the button should be full-width on mobile
1921
* @returns {JSX.Element} - Rendered component
2022
*/
2123
const Button = ({
2224
handleButtonClick,
2325
buttonDisabled,
2426
color = 'blue',
2527
children,
28+
fullWidth = false,
2629
}: IButtonProps) => (
2730
<button
2831
onClick={handleButtonClick}
@@ -33,6 +36,7 @@ const Button = ({
3336
? 'bg-blue-500 hover:bg-blue-600'
3437
: 'bg-red-500 hover:bg-red-600'
3538
}
39+
${fullWidth ? 'w-full md:w-auto' : ''}
3640
`}
3741
>
3842
{children}

0 commit comments

Comments
 (0)