Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image gallery #65

Merged
merged 2 commits into from
Feb 5, 2024
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
5 changes: 2 additions & 3 deletions app/Domain/ProductContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ export const ProductProvider = ({ children }) => {
useEffect(() => {
const fetchProducts = async () => {
const data = await getProducts();
console.log("Products: " + data);
setProducts(data);
};

fetchProducts();
}, []);


function getURL(product) {
return pb.files.getUrl(product, product?.img);
function getURL(product,index) {
return pb.files.getUrl(product, product?.img?.[index]);
}


Expand Down
12 changes: 5 additions & 7 deletions app/components/ProductDescription.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export default function ProductDescription({product ,title, description, quantit

const quantityOptions = [];
for (let i = 1; i <= quantity; i++) {
{console.log(i)}
quantityOptions.push(
<option key={i} value={i}>
Qty: {i}
Expand All @@ -27,18 +26,18 @@ export default function ProductDescription({product ,title, description, quantit
}

return (
<div className="flex w-[55%] h-[65%] flex-col items-center justify-evenly ">
<div className="w-7/12 h-4/6 bg-white flex flex-col items-center justify-center rounded-lg ">
<div className="flex w-[60%] h-[80%] flex-col items-center justify-evenly ">
<div className=" w-11/12 lg:w-7/12 h-4/6 bg-white flex flex-col items-center justify-center rounded-lg ">
<div className="w-11/12 h-10">
<h1 className="text-2xl font-bold">{title}</h1>
</div>
</div>
<div className="w-11/12 h-0 border border-black"></div>
<div className="w-11/12 h-8">
<h2 className="text-xl font-bold">${price}</h2>
</div>
<p className="w-11/12 h-56 max-h-56 overflow-hidden py-2">{description}</p>
</div>
<div className="w-7/12 flex flex-row items-center justify-between text-lg font-semibold ">
<div className="w-11/12 lg:w-7/12 flex flex-row items-center justify-between text-lg font-semibold ">
<button
onClick={handleAddToCart}
className="w-3/5 bg-white h-10 rounded-xl border-[1.5px] border-black hover:scale-110 transition-all duration-300 ease-out"
Expand All @@ -50,11 +49,10 @@ export default function ProductDescription({product ,title, description, quantit
className="w-1/3 h-10 rounded-lg bg-ACMDARK text-white border-none px-2 cursor-pointer"
onChange={(e) => setSelectedQuantity(parseInt(e.target.value))}
>
{console.log(quantityOptions)}
{quantityOptions}
</select>
</div>
<button onClick={()=>handleBuy()} className="w-7/12 h-10 text-xl font-semibold rounded-xl bg-ACMDARK text-white hover:scale-110 transition-all duration-300 ease-out ">
<button onClick={()=>handleBuy()} className="w-11/12 lg:w-7/12 h-10 text-xl font-semibold rounded-xl bg-ACMDARK text-white hover:scale-110 transition-all duration-300 ease-out ">
Buy Now
</button>
</div>
Expand Down
11 changes: 7 additions & 4 deletions app/components/cartProduct.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ import Link from "next/link";
import Image from "next/image"
import { useCartProducts } from '../Domain/cartContext'
import pb from "../Domain/pocketbase";
import { useProducts } from "../Domain/ProductContext";

export default function CartProduct({ product }) {
const { addToCart, removeOne, removeAll } = useCartProducts()
const { id, tags, title, price, properties, cartQuantity } = product
let imgUrl = pb.files.getUrl(product, product.img)

const { getURL } = useProducts();
const imgUrl = getURL(product, 0)

function handleEnter(e) {
e.target.style.transform = 'scale(1.1)';

Expand All @@ -20,7 +23,7 @@ export default function CartProduct({ product }) {

return (
<div className={`shadow-2xl w-shadow-lg bg-white text-ACMDARK mb-7 h-44 flex flex-row items-center rounded-2xl w-[88vw]`}>
<Image alt={title} src={imgUrl} width={150} height={150} className="h-32 ml-2" />
<Image alt={title} src={imgUrl} width={150} height={150} className="h-32 ml-2 rounded-lg" />
<div className="ml-10 w-9/12">
<Link href={`products/${id}`} className="font-extrabold text-3xl h-full">{title}</Link>
{properties && properties.map((prop) => (
Expand All @@ -39,7 +42,7 @@ export default function CartProduct({ product }) {
<div className="grid grid-cols-3 divide-x text-align text-lg " >
<div onClick={() => removeOne(id)} onMouseLeave={(e) => handleLeave(e)} onMouseEnter={(e) => handleEnter(e)} style={{ border: '1px solid black' }} className=" duration-200 transition-all ease-in flex items-center justify-center rounded-tl-lg rounded-bl-lg cursor-pointer font-bold">-</div>
<div style={{ border: '1px solid black' }} className=" flex items-center justify-center font-bold">{cartQuantity}</div>
<div onClick={() => addToCart(product,1)} onMouseLeave={(e) => handleLeave(e)} onMouseEnter={(e) => handleEnter(e)} style={{ border: '1px solid black' }} className=" duration-200 transition-all ease-in flex items-center justify-center rounded-tr-lg rounded-br-lg font-bold cursor-pointer">+</div>
<div onClick={() => addToCart(product, 1)} onMouseLeave={(e) => handleLeave(e)} onMouseEnter={(e) => handleEnter(e)} style={{ border: '1px solid black' }} className=" duration-200 transition-all ease-in flex items-center justify-center rounded-tr-lg rounded-br-lg font-bold cursor-pointer">+</div>
</div>
</div>
</div >
Expand Down
57 changes: 57 additions & 0 deletions app/components/imgGallery.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Image from "next/image"
import { useProducts } from "../Domain/ProductContext";
import { useState, useEffect } from "react";

export default function ImageGallery({ product }) {
const [indexHigh, setIndexHigh] = useState(0)
const [progress, setProgress] = useState(100);
const { getURL } = useProducts();

useEffect(() => {
const progressBarInterval = setInterval(() => {
setProgress((prevProgress) => Math.max(prevProgress - 1 / 2, 0));
}, 30);

console.log(progress)
if (progress === 0) {
setIndexHigh((prevIndex) => (prevIndex + 1) % product.img.length);
setProgress(100);
}

return () => {
clearInterval(progressBarInterval);
};

}, [progress, product?.img?.length]);


function handleClick(index) {
setIndexHigh(index)
setProgress(100)
}

return (
<div className="w-[55%] h-[80%] flex flex-col items-center">

<div className="flex flex-col items-center justify-center w-11/12 lg:w-[60%] h-[78%]">
<Image alt="product image" src={getURL(product, indexHigh)} width={100} height={100} className="w-full h-[85%] rounded-lg" />
<div className="w-full h-2 bg-gray-300 rounded mt-2">
<div
className="h-full bg-ACMDARK rounded"
style={{ width: `${progress}%` }}
></div>
</div>
</div>

<div className="flex flex-row items-center justify-evenly w-11/12 h-[22%] ">
{product && product?.img?.map((_, index) => {
return (
<Image onClick={() => handleClick(index)} key={index} alt="product image" src={getURL(product, index)} width={50} height={50} className={`w-[20%] h-[70%] hover:scale-110 transition-all duration-200 ease-out rounded-lg cursor-pointer ${index === indexHigh && "border-solid border-ACMLIGHT border-2"}`} />
)
})}
</div>
</div>
)
}


8 changes: 4 additions & 4 deletions app/components/notification.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export default function Notification({selectedQuantity, setShowNotification,titl

useEffect(() => {
const interval = setInterval(() => {
setProgress((prevProgress) => (prevProgress - 1));
}, 60);
setProgress((prevProgress) => (prevProgress - 1/2));
}, 30);

}, []);

Expand All @@ -17,8 +17,8 @@ export default function Notification({selectedQuantity, setShowNotification,titl
}, [progress, setShowNotification]);

return (
<div className="animate-notification absolute w-1/4 h-[80px] translate-y-[-30vh] flex items-center justify-center flex-col bg-ACMDARK text-white rounded-lg">
<div className="w-11/12 text-xl font-semibold">
<div className="animate-notification px-8 py-1 absolute w-[25vw] lg:w-[30vw] h-24 translate-y-[-31vh] flex items-center justify-center flex-col bg-ACMDARK text-white rounded-lg">
<div className="w-full text-xl font-semibold">
<h1 className="cursor-pointer" onClick={() => setShowNotification(false)}>X</h1>
</div>
<h1 className="text-lg font-semibold mb-2">{title} x{selectedQuantity} add to the cart</h1>
Expand Down
8 changes: 4 additions & 4 deletions app/components/product.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import { useProducts } from "../Domain/ProductContext";
export default function Product({ product, isDarkMode }) {
const [hovered, setHovered] = useState(false);
const { id, title, price } = product
const {removeAll, addToCart, isInCart } = useCartProducts();
const { removeAll, addToCart, isInCart } = useCartProducts();
const { getURL } = useProducts();
let imgUrl = getURL(product)
let imgUrl = getURL(product, 0)

function handleClick(e, product) {
e.preventDefault();
if (isInCart(id)) {
removeAll(id);
} else {
addToCart(product,1);
addToCart(product, 1);
}
}

Expand All @@ -36,7 +36,7 @@ export default function Product({ product, isDarkMode }) {
</div>
<div
className={`bg-white flex flex-col items-center justify-center absolute w-[100%] cursor-pointer rounded-lg transition-all duration-200 text-ACMDARK ease-in
${hovered ? "-translate-y-16 shadow-[0px_-26px_15px_0px_rgba(255,255,255)] h-[35%]" : "translate-y-8 h-5"
${hovered ? "-translate-y-16 shadow-[0px_-26px_9px_0px_rgba(255,255,255)] h-[35%]" : "translate-y-8 h-5"
}`}
>
<h1 className="text-lg bold">{title}</h1>
Expand Down
2 changes: 1 addition & 1 deletion app/components/productlist.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function ProductList({productList, isDarkMode }) {
return (
<div
ref={productList}
className={` ${isDarkMode ? 'bg-ACMDARK' : "bg-white"} text-white flex flex-col items-center justify-center min-h-screen bg-cover bg-center w-full`} >
className={` ${isDarkMode ? 'bg-ACMDARK' : "bg-white"} text-white flex flex-col items-center justify-center min-h-screen bg-cover bg-center w-full py-10`} >
<h1 className={`text-4xl bold ${isDarkMode ? 'text-white' : 'text-ACMDARK'}`} >Products</h1>
<div className="flex flex-col items-center justify-center mt-14">
<ProductFilter page={page} setPage={setPage} isDarkMode={isDarkMode} />
Expand Down
13 changes: 7 additions & 6 deletions app/products/[id]/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import { useEffect, useState } from "react";
import { useTheme } from "../../Domain/ThemeContext";
import { useProducts } from "@/app/Domain/ProductContext";
import Image from "next/image";
import ProductDescription from "@/app/components/ProductDescription";
import Notification from "@/app/components/notification";
import ImageGallery from "@/app/components/imgGallery";


export default function Product({ params }) {
const { isDarkMode } = useTheme();
const { products, getURL } = useProducts();
const { products } = useProducts();
const [product, setProduct] = useState({})
const [showNotification,setShowNotification] = useState(false)
const [selectedQuantity, setSelectedQuantity] = useState(1);
Expand All @@ -22,14 +23,14 @@ export default function Product({ params }) {

return (
<>
<div className={`${isDarkMode ? 'bg-ACMPrimary' : 'bg-ACMBLUE'} flex flex-row items-center justify-center text-ACMDARK h-screen bg-cover bg-center w-full`}>
<div className={`${isDarkMode ? 'bg-ACMPrimary' : 'bg-ACMBLUE'} flex flex-row placeholder: items-center justify-center text-ACMDARK h-screen bg-cover bg-center w-full py-10`}>
{showNotification && <Notification title={product?.title} selectedQuantity={selectedQuantity} setShowNotification={setShowNotification}/>}
<div className="w-full h-full flex flex-row items-center justify-center mt-28">
<Image src={getURL(product)} width={400} height={400} alt={`${product?.title} Image`} />
<ProductDescription selectedQuantity={selectedQuantity} setSelectedQuantity={setSelectedQuantity} setShowNotification={setShowNotification} product={product} title={product?.title} price={product?.price} quantity={product?.quantity} description={product?.description} />
{product && <ImageGallery product={product}/> }
<ProductDescription selectedQuantity={selectedQuantity} setSelectedQuantity={setSelectedQuantity} setShowNotification={setShowNotification} product={product} title={product?.title} price={product?.price} quantity={product?.quantity} description={product?.description} />
</div>

</div>

</>
);
}
48 changes: 48 additions & 0 deletions pb_migrations/1706918425_updated_products.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/// <reference path="../pb_data/types.d.ts" />
migrate((db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("74riiebulb43zi2")

// update
collection.schema.addField(new SchemaField({
"system": false,
"id": "26rk4w9a",
"name": "img",
"type": "file",
"required": false,
"presentable": false,
"unique": false,
"options": {
"maxSelect": 99,
"maxSize": 5242880,
"mimeTypes": [],
"thumbs": [],
"protected": false
}
}))

return dao.saveCollection(collection)
}, (db) => {
const dao = new Dao(db)
const collection = dao.findCollectionByNameOrId("74riiebulb43zi2")

// update
collection.schema.addField(new SchemaField({
"system": false,
"id": "26rk4w9a",
"name": "img",
"type": "file",
"required": false,
"presentable": false,
"unique": false,
"options": {
"maxSelect": 1,
"maxSize": 5242880,
"mimeTypes": [],
"thumbs": [],
"protected": false
}
}))

return dao.saveCollection(collection)
})
Loading