Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/components/Footer/Footer.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
* @returns {JSX.Element} - Rendered component
*/
const Footer = () => (
<footer className="bg-white mb-4 hidden md:block px-4">
<div className="container flex md:flex-wrap flex-col md:flex-row items-center justify-between px-6 py-3 mx-auto mt-0 md:min-w-96 border border-gray-200 rounded lg:max-w-[1490px]">
<div className="text-gray-600 mx-auto">
&copy; {new Date().getFullYear()} Daniel / w3bdesign
<footer className="w-full bg-white border-t border-gray-200 mt-12">
<div className="container mx-auto px-6">
<div className="py-4">
<div className="text-gray-600 text-center">
&copy; {new Date().getFullYear()} Daniel / w3bdesign
</div>
</div>
</div>
</footer>
Expand Down
4 changes: 3 additions & 1 deletion src/components/Header/Header.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const Header = ({ title }: IHeaderProps) => (
key="pagetitle"
/>
</Head>
<Navbar />
<div className="container mx-auto px-6">
<Navbar />
</div>
</>
);

Expand Down
89 changes: 43 additions & 46 deletions src/components/Header/Navbar.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,58 +16,55 @@ import useIsMobile from '@/utils/hooks/useIsMobile';
const Navbar = () => {
const isMobile = useIsMobile();
return (
<header>
<nav id="header" className="top-0 z-50 w-full py-1 bg-white ">
<div className="container flex flex-col md:flex-row items-center justify-between px-6 py-3 mx-auto mt-0 md:min-w-96">
<div
className="order-3 hidden w-full md:flex md:items-center md:w-auto md:order-1"
id="menu"
>
<ul className="items-center justify-between pt-4 text-base text-gray-700 md:flex md:pt-0">
<li>
<header className="border-b border-gray-200">
<nav id="header" className="top-0 z-50 w-full bg-white">
<div className="container mx-auto px-4 sm:px-6 py-4">
{isMobile ? (
// Mobile layout - logo with search below
<div className="flex flex-col space-y-4">
<div className="text-center">
<Link href="/">
<span className="text-lg font-bold tracking-widest text-gray-900">
NETTBUTIKK
</span>
</Link>
</div>
<div className="w-full">
<MobileSearch />
</div>
</div>
) : (
// Desktop layout
<div className="flex items-center justify-between">
<div className="flex items-center space-x-8">
<Link href="/produkter">
<span className="inline-block py-2 pr-4 text-xl font-bold no-underline hover:underline">
Produkter
<span className="text-base uppercase tracking-wider group relative">
<span className="relative inline-block">
<span className="absolute -bottom-1 left-0 w-0 h-px bg-gray-900 group-hover:w-full transition-all duration-500"></span>
Produkter
</span>
</span>
</Link>
</li>
<li>
<Link href="/kategorier">
<span className="inline-block py-2 pr-4 text-xl font-bold no-underline hover:underline">
Kategorier
<span className="text-base uppercase tracking-wider group relative">
<span className="relative inline-block">
<span className="absolute -bottom-1 left-0 w-0 h-px bg-gray-900 group-hover:w-full transition-all duration-500"></span>
Kategorier
</span>
</span>
</Link>
</li>
</ul>
</div>
<div className="order-1 md:order-2 md:hidden lg:block">
<Link href="/">
<span className="flex items-center text-xl font-bold tracking-wide text-gray-800 no-underline hover:no-underline ">
<svg
className="mr-2 text-gray-800 fill-current"
xmlns="https://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
aria-label="Nettbutikk logo"
>
<path
d="M5,22h14c1.103,0,2-0.897,2-2V9c0-0.553-0.447-1-1-1h-3V7c0-2.757-2.243-5-5-5S7,4.243,7,7v1H4C3.447,8,3,8.447,3,9v11 C3,21.103,3.897,22,5,22z M9,7c0-1.654,1.346-3,3-3s3,1.346,3,3v1H9V7z M5,10h2v2h2v-2h6v2h2v-2h2l0.002,10H5V10z"
aria-label="Nettbutikk logo"
/>
</svg>
NETTBUTIKK
</span>
</Link>
</div>
<div
className="flex items-center order-2 md:order-3"
id="nav-content"
>
<AlgoliaSearchBox />
<MobileSearch />
{!isMobile && <Cart />}
</div>
</div>
<Link href="/" className="hidden lg:block">
<span className="text-xl font-bold tracking-widest text-gray-900 hover:text-gray-700 transition-colors">
NETTBUTIKK
</span>
</Link>
<div className="flex items-center space-x-3">
<AlgoliaSearchBox />
<Cart />
</div>
</div>
)}
</div>
</nav>
</header>
Expand Down
39 changes: 25 additions & 14 deletions src/components/Index/Hero.component.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
import Image from 'next/image';
import Link from 'next/link';

/**
* Renders Hero section for Index page
* @function PageTitle
* @function Hero
* @returns {JSX.Element} - Rendered component
*/
const Hero = () => (
<section
id="hero"
className="flex w-full mx-auto bg-right bg-cover mt-14 md:pt-0 md:items-center bg-hero-background h-[24rem] lg:max-w-[1490px]"
>
<div className="container mx-auto">
<div className="flex flex-col items-start justify-center w-full px-6 tracking-wide lg:w-1/2">
<h1 className="p-4 my-4 text-2xl text-white bg-black rounded-lg">
<section className="relative w-full h-[60vh] overflow-hidden">
<div className="absolute inset-0">
<Image
src="/images/hero.jpg"
alt="Hero image"
fill
priority
className="object-cover object-center"
quality={90}
/>
<div className="absolute inset-0 bg-black bg-opacity-30" />
</div>

<div className="relative h-full container mx-auto flex items-center">
<div className="max-w-xl">
<h1 className="text-3xl md:text-4xl lg:text-5xl font-light text-white mb-6">
Stripete Zig Zag Pute Sett
</h1>

<a
className="inline-block px-6 py-3 text-xl leading-relaxed text-white uppercase bg-black rounded-lg hover:underline"
href="#"
<Link
href="/produkter"
className="inline-block px-8 py-4 text-sm tracking-wider uppercase bg-white text-gray-900 hover:bg-gray-100 transition-colors duration-200"
>
se utvalget
</a>
Se Utvalget
</Link>
</div>
</div>
</section>
Expand Down
14 changes: 10 additions & 4 deletions src/components/Layout/Layout.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@ const Layout = ({ children, title }: ILayoutProps) => {

return (
<div className="flex flex-col min-h-screen w-full mx-auto">
<div className="container min-w-[140vw] sm:min-w-[95vw] md:px-4 lg:px-6 py-2 lg:max-w-[1600px] mx-auto">
<Header title={title} />
<PageTitle title={title} />
<main className="flex-grow">{children}</main>
<Header title={title} />
{title === 'Hjem' ? (
<main className="flex-1">{children}</main>
) : (
<div className="container mx-auto px-6 flex-1">
<PageTitle title={title} />
<main>{children}</main>
</div>
)}
<div className="mt-auto">
<Footer />
<Stickynav />
</div>
Expand Down
18 changes: 7 additions & 11 deletions src/components/Layout/PageTitle.component.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
interface IPageTitleProps {
title: string;
marginLeft?: boolean;
}

/**
* Renders page title for each page.
* @function PageTitle
* @param {boolean} marginLeft - Adds extra margin left if true
* @param {string} title - Title for the page. Is set in <title>{title}</title>
* @returns {JSX.Element} - Rendered component
*/
const PageTitle = ({ title, marginLeft }: IPageTitleProps) => (
<section
className={`container ${
marginLeft ? 'p-4' : 'p-0'
} pl-4 mx-auto mt-24 text-center bg-white`}
>
<span className="py-2 text-2xl font-bold tracking-wide text-center text-gray-800 no-underline uppercase hover:no-underline">
{title}
</span>
const PageTitle = ({ title }: IPageTitleProps) => (
<section className="w-full bg-white border-b border-gray-200">
<div className="container mx-auto py-12 px-6">
<h1 className="text-2xl text-center tracking-wider text-gray-900 uppercase">
{title}
</h1>
</div>
</section>
);

Expand Down
60 changes: 27 additions & 33 deletions src/components/Product/DisplayProducts.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ interface IDisplayProductsProps {
*/

const DisplayProducts = ({ products }: IDisplayProductsProps) => (
<section className="container mx-auto bg-white">
<section className="container mx-auto bg-white py-12">
<div
id="product-container"
className="flex flex-wrap items-center mb-[120px] md:mb-0"
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8"
>
{products ? (
products.map(
Expand All @@ -77,67 +77,61 @@ const DisplayProducts = ({ products }: IDisplayProductsProps) => (
}

return (
<div
key={uuidv4()}
className="flex flex-col p-6 md:w-1/2 xl:w-1/4"
>
<div key={uuidv4()} className="group">
<Link
href={`/produkt/${encodeURIComponent(
slug,
)}?id=${encodeURIComponent(databaseId)}`}
>
<span>
<div className="aspect-[3/4] relative overflow-hidden bg-gray-100">
{image ? (
<img
id="product-image"
className="transition duration-500 ease-in-out transform cursor-pointer hover:grow hover:shadow-lg hover:scale-105"
className="w-full h-full object-cover object-center transition duration-300 group-hover:scale-105"
alt={name}
src={image.sourceUrl}
/>
) : (
<img
id="product-image"
className="transition duration-500 ease-in-out transform cursor-pointer hover:grow hover:shadow-lg hover:scale-105"
className="w-full h-full object-cover object-center transition duration-300 group-hover:scale-105"
alt={name}
src={
process.env.NEXT_PUBLIC_PLACEHOLDER_SMALL_IMAGE_URL
}
src={process.env.NEXT_PUBLIC_PLACEHOLDER_SMALL_IMAGE_URL}
/>
)}
</span>
</div>
</Link>
<Link
href={`/produkt/${encodeURIComponent(
slug,
)}?id=${encodeURIComponent(databaseId)}`}
>
<span>
<div className="flex justify-center pt-3">
<p className="font-bold text-center cursor-pointer text-2xl">
<div className="mt-4">
<p className="text-base font-bold text-center cursor-pointer hover:text-gray-600 transition-colors">
{name}
</p>
</div>
</span>
</Link>
{/* Display sale price when on sale */}
{onSale && (
<div className="flex justify-center">
<div className="pt-1 text-gray-900 text-xl">
{variations && filteredVariantPrice(price, '')}
{!variations && salePrice}
<div className="mt-2 text-center">
{onSale ? (
<div className="flex justify-center items-center space-x-2">
<span className="text-red-600">
{variations && filteredVariantPrice(price, '')}
{!variations && salePrice}
</span>
<span className="text-gray-500 text-sm line-through">
{variations && filteredVariantPrice(price, 'right')}
{!variations && regularPrice}
</span>
</div>
<div className="pt-1 ml-2 text-gray-500 line-through text-lg">
{variations && filteredVariantPrice(price, 'right')}
{!variations && regularPrice}
</div>
</div>
)}
{/* Display regular price when not on sale */}
{!onSale && (
<p className="pt-1 text-center text-gray-900 text-xl">
{price}
</p>
)}
) : (
<span className="text-gray-900">
{price}
</span>
)}
</div>
</div>
);
},
Expand Down
32 changes: 18 additions & 14 deletions src/components/Product/SingleProduct.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const SingleProduct = ({ product }: IProductRootObject) => {
if (process.browser) {
DESCRIPTION_WITHOUT_HTML = new DOMParser().parseFromString(
description,
'text/html'
'text/html',
).body.textContent;
}

Expand All @@ -58,17 +58,19 @@ const SingleProduct = ({ product }: IProductRootObject) => {
<div className="container mx-auto px-4 py-8">
<div className="flex flex-col md:grid md:grid-cols-2 md:gap-8">
{/* Image Container */}
<div className="mb-6 md:mb-0">
<img
id="product-image"
src={
image?.sourceUrl ||
process.env.NEXT_PUBLIC_PLACEHOLDER_LARGE_IMAGE_URL ||
placeholderFallBack
}
alt={name}
className="w-full h-auto object-cover transition duration-500 ease-in-out transform md:hover:scale-105"
/>
<div className="mb-6 md:mb-0 group">
<div className="max-w-xl mx-auto aspect-[3/4] relative overflow-hidden bg-gray-100">
<img
id="product-image"
src={
image?.sourceUrl ||
process.env.NEXT_PUBLIC_PLACEHOLDER_LARGE_IMAGE_URL ||
placeholderFallBack
}
alt={name}
className="w-full h-full object-cover object-center transition duration-300 group-hover:scale-105"
/>
</div>
</div>

{/* Product Details Container */}
Expand Down Expand Up @@ -126,14 +128,16 @@ const SingleProduct = ({ product }: IProductRootObject) => {
id="variant"
name="variant"
className="w-full px-4 py-2 bg-white border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
onChange={(e) => setSelectedVariation(Number(e.target.value))}
onChange={(e) =>
setSelectedVariation(Number(e.target.value))
}
>
{product.variations.nodes.map(
({ id, name, databaseId, stockQuantity }) => (
<option key={id} value={databaseId}>
{name.split('- ').pop()} - ({stockQuantity} på lager)
</option>
)
),
)}
</select>
</div>
Expand Down
Loading