diff --git a/fetch-summit-settings.sh b/fetch-summit-settings.sh old mode 100644 new mode 100755 diff --git a/pages/product-information/CartTable.tsx b/pages/product-information/CartTable.tsx new file mode 100644 index 00000000..b8104d8a --- /dev/null +++ b/pages/product-information/CartTable.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { IoAddOutline, IoRemoveOutline } from 'react-icons/io5'; +import CustomTable from './CustomTable'; // adjust path as needed + +type CartItem = { + metal: string; + purity: string; + tone: string; + diamond: string; + size: string; + quantity: number; + total: number; +}; + +type CartTableProps = { + cart: CartItem[]; + handleCartQuantityChange: (index: number, change: number) => void; +}; + +const CartTable: React.FC = ({ cart, handleCartQuantityChange }) => { + const headers = ['Metal', 'Purity', 'Tone', 'Diamond', 'Size', 'Quantity', 'Total']; + + const rows: any[][] = cart.map((item, index) => [ + item.metal, + item.purity, + item.tone, + item.diamond, + item.size, + // Quantity Control (JSX Element) +
+ +
{item.quantity}
+ +
, + item.total.toFixed(2), + ]); + if (cart.length === 0) { + rows.push([ + { + content: 'No items in cart', + props: { + colSpan: 7, + className: 'text-center fw-bold px-4', + }, + }, + ]); + } + + return ; +}; + +export default CartTable; diff --git a/pages/product-information/CustomTable.tsx b/pages/product-information/CustomTable.tsx new file mode 100644 index 00000000..c631812b --- /dev/null +++ b/pages/product-information/CustomTable.tsx @@ -0,0 +1,57 @@ +import React from 'react'; + +type CellContent = + | string + | number + | JSX.Element + | { content: string | number | JSX.Element; props?: React.TdHTMLAttributes }; + +type CustomTableProps = { + headers?: string[]; + rows: CellContent[][]; +}; + +const CustomTable: React.FC = ({ headers = [], rows }) => { + const columnCount = Math.max(...rows.map((row) => row.length), headers.length); + + return ( +
+ + {headers.length > 0 && ( + + + {headers.length === 1 && columnCount > 1 ? ( + + ) : ( + headers.map((header, i) => ) + )} + + + )} + + {rows.map((row, i) => ( + + {row.map((cell, j) => { + if (typeof cell === 'object' && 'content' in cell) { + return ( + + ); + } else { + return ( + + ); + } + })} + + ))} + +
{headers[0]}{header}
+ {cell.content} + + {cell} +
+
+ ); +}; + +export default CustomTable; diff --git a/pages/product-information/index.tsx b/pages/product-information/index.tsx new file mode 100644 index 00000000..3886c89b --- /dev/null +++ b/pages/product-information/index.tsx @@ -0,0 +1,509 @@ +import React, { useState } from 'react'; +import { IoIosArrowBack } from 'react-icons/io'; +import { IoAddOutline, IoRemoveOutline } from 'react-icons/io5'; +import ProductInfoTable from './CustomTable'; +import CartTable from './CartTable'; + +import productInformationStyle from '../../styles/components/productInformation.module.scss'; + +export default function ProductDetails() { + const [selectedMetal, setSelectedMetal] = useState('Gold'); + const [selectedPurity, setSelectedPurity] = useState(''); + const [selectedTone, setSelectedTone] = useState(''); + const [selectedDiamond, setSelectedDiamond] = useState(''); + const [selectedSize, setSelectedSize] = useState(''); + const [quantity, setQuantity] = useState(1); + const [cart, setCart] = useState([]); + const [error, setError] = useState(''); + + const handleMainQuantityChange = (delta: any) => { + setQuantity((prev) => Math.max(1, prev + delta)); + }; + + const handleCartQuantityChange = (itemIndex: any, delta: any) => { + setCart((prevCart) => + prevCart.map((item, idx) => + idx === itemIndex + ? { + ...item, + quantity: Math.max(1, item.quantity + delta), + total: item.unitPrice * Math.max(1, item.quantity + delta), + } + : item + ) + ); + }; + + const handleAddToCart = () => { + if (selectedMetal !== 'Platinum') { + if (!selectedPurity || !selectedTone) { + setError('Please select purity and tone for Gold.'); + return; + } + } + + if (!selectedDiamond || !selectedSize) { + setError('Please select diamond type and size.'); + return; + } + + // Clear error + setError(''); + + alert('Product has been added'); + + // Add item to cart + const unitPrice = selectedMetal === 'Gold' ? 211.22 : 311.22; + const newItem = { + metal: selectedMetal, + purity: selectedMetal !== 'Platinum' ? selectedPurity : '-', + tone: selectedMetal !== 'Platinum' ? selectedTone : '-', + diamond: selectedDiamond, + size: selectedSize, + quantity, + unitPrice, + total: unitPrice * quantity, // This is a number + }; + + setCart([...cart, newItem]); + + setSelectedPurity(''); + setSelectedTone(''); + setSelectedDiamond(''); + setSelectedSize(''); + setQuantity(1); + }; + + const metalHeader = ['Kt', 'Colour', 'Wght', 'Rate', 'Value']; + const metalRows = [ + [22, 'Yellow', 10.5, 5800, (10.5 * 5800).toFixed(2)], + [18, 'White', 7.3, 4500, (7.3 * 4500).toFixed(2)], + ]; + + const diamondHeader = ['Shape', 'Quality', 'Size 1', 'Size 2', 'Pointer', 'Qty', 'Carats', 'Rate', 'Value', 'Setting', 'Rate', 'Value']; + const diamondRows = [ + ['Round', 'VVS', '1.2', '1.4', '0.03', 10, 0.3, 5000, (0.3 * 5000).toFixed(2), 'Prong', 200, (10 * 200).toFixed(2)], + ['Princess', 'VS', '1.5', '1.7', '0.05', 8, 0.4, 5200, (0.4 * 5200).toFixed(2), 'Bezel', 220, (8 * 220).toFixed(2)], + ]; + + const colorStoneHeader = [ + 'Shape', + 'Quality', + 'Size 1', + 'Size 2', + 'Pointer', + 'Qty', + 'Carats', + 'Rate', + 'Value', + 'Setting', + 'Rate', + 'Value', + ]; + + const colorStoneRows = [ + ['Round', 'VVS', '1.2', '1.4', '0.03', 10, 0.3, 5000, (0.3 * 5000).toFixed(2), 'Prong', 200, (10 * 200).toFixed(2)], + ['Princess', 'VS', '1.5', '1.7', '0.05', 8, 0.4, 5200, (0.4 * 5200).toFixed(2), 'Bezel', 220, (8 * 220).toFixed(2)], + ]; + + const accessoriesHeader = [ + 'Shape', + 'Quality', + 'Size 1', + 'Size 2', + 'Per pc wt', + 'Qty', + 'Weight', + 'Rate', + 'Value', + 'Setting', + 'Rate', + 'Value', + ]; + + const accessoriesRows = [ + ['Round', 'VVS', '1.2', '1.4', '0.05', 12, 0.6, 4000, (0.6 * 4000).toFixed(2), 'Prong', 150, (12 * 150).toFixed(2)], + ['Oval', 'VS', '1.3', '1.5', '0.07', 10, 0.7, 4200, (0.7 * 4200).toFixed(2), 'Bezel', 180, (10 * 180).toFixed(2)], + ]; + + const labourHeader = ['Main Kt', 'Lab Cd', 'Qt/Wt', 'Rate', 'Value']; + + const labourRows = [ + ['10.5', 'L123', '0.5', 1000, (0.5 * 1000).toFixed(2)], + ['12.0', 'L456', '0.8', 1200, (0.8 * 1200).toFixed(2)], + ]; + + const summaryHeaders = ['Summary']; + const summaryRows = [ + ['Metal Weight', 'qty', 'value'], + ['Purity', 'qty', 'value'], + ['Tone', 'qty', 'value'], + ['Diamond', 'qty', 'value'], + ['Size', 'qty', 'value'], + ]; + + const customerInfoRows = [ + ['Customer Instructions'], + ['Product Instruction'], + ['Stamping'], + ['Size'], + ['Special Remark'], + ['Sub Remark'], + ['Delivery Date'], + ['Payment Terms'], + ]; + + return ( +
+
+ +
Product Details
+
+ +
+ {/* Left Column */} +
+
+
+ Main Product +
+
+ Side 1 + Side 2 +
+
+
+ + {/* Right Column */} +
+
+
+

JY-2025-001

+
€{selectedMetal === 'Gold' ? '211.22' : '311.22'}
+
+ + {error &&
{error}
} + + +
+ + + + + + {selectedMetal !== 'Platinum' && ( + <> +
+ +
+ {['9Kt', '10Kt', '14Kt', '18Kt'].map((k, i) => ( + + ))} +
+ +
+ +
+ {['Yellow', 'White', 'Rose'].map((tone, i) => ( + + ))} +
+ + )} + +
+ +
+ {['I1', 'SI', 'VS', 'LGD'].map((type, i) => ( + + ))} +
+ +
+ +
+ {['4', '4.5', '5', '5.5', '6', '6.5', '7', '7.5', '8', '8.5'].map((size, i) => ( + + ))} +
+ +
+ {/* Quantity Selector */} +
+ +
+ +
{quantity}
+ +
+
+ + {/* Add to Cart Button */} +
+ +
+
+
+
+
+ + {/* Cart Summary */} +
+
+
+ Side 1 +
Your Cart for Jy-2025-001
+
+ +
Subtotal: €{cart.reduce((acc, item) => acc + (Number(item.total) || 0), 0).toFixed(2)}
+
+ + +
+ + {/* --- Desktop Version: Positioned Summary and Customer Info --- */} +
+ {/* Left: Metal Details */} +
+
+ Side 1 + +
Metal Details
+
+ +
+ + {/* Right: Absolute positioned Summary and Customer Info */} +
+
+ +
+
+ {customerInfoRows.map((item, index) => ( +
+ {item} +
+ ))} +
+
+ + +
+
+
+ + {/* Diamond Details */} + +
+
+ Side 1 +
Diamond Details
+
+ +
+ + {/* Color Stone Details */} + +
+
+ Side 1 +
Color Stone Details
+
+ +
+ + {/* Accessories Details */} + +
+
+ Side 1 +
Accessories Details
+
+ +
+ + {/* Labour Details */} + +
+
+ Side 1 +
Labour Details
+
+ +
+ + {/* --- Mobile Version: Summary and Customer Info at Bottom --- */} +
+
+ +
+
+ {customerInfoRows.map((item, index) => ( +
+ {item} +
+ ))} +
+
+ + +
+
+
+ ); +} diff --git a/services/constants/Colors.tsx b/services/constants/Colors.tsx new file mode 100644 index 00000000..3de994b2 --- /dev/null +++ b/services/constants/Colors.tsx @@ -0,0 +1,19 @@ +export const colors = { + primary: '#fff', + softWhite: '#f8f9fa', + red: '#ff3400', + black: '#000', + lightgray: '#F5F5F5', + mediumGray: '#ddd', + darkGray: '#333', + white: '#fff', + transparent: 'transparent', + lightPink: '#F1E9E9', + darkPink: '#792E2C', + darkBlue: '#082468', + lightBlue: '#E5ECFF', + grey: '#EDECEC', + lightPurple: '#F2EEFC', + cardTextGrey: '#9F9F9F', + softGray: '#F6F6F6', +};