From 8bcd2f99fdd96e32003975e60ad28dd7fffe95d7 Mon Sep 17 00:00:00 2001 From: akrs-code Date: Sat, 20 Jun 2026 00:58:52 +0800 Subject: [PATCH 1/2] resolved conflicts --- frontend/src/App.jsx | 11 + frontend/src/components/RoleBasedSidebar.jsx | 1 + frontend/src/index.css | 6 + frontend/src/layouts/SharedSidebar.jsx | 12 +- frontend/src/pages/buyer/BuyerProfile.jsx | 300 +++++++++++++ frontend/src/pages/buyer/Checkout.jsx | 38 +- frontend/src/pages/buyer/ProductDetail.jsx | 2 +- frontend/src/pages/shared/Login.jsx | 104 +++++ .../src/pages/shared/SellerVerification.jsx | 403 ++++++++++++++++++ frontend/src/pages/shared/Signup.jsx | 192 +++++++++ 10 files changed, 1051 insertions(+), 18 deletions(-) create mode 100644 frontend/src/pages/buyer/BuyerProfile.jsx create mode 100644 frontend/src/pages/shared/Login.jsx create mode 100644 frontend/src/pages/shared/SellerVerification.jsx create mode 100644 frontend/src/pages/shared/Signup.jsx diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index cae85eb..40c9cea 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -5,6 +5,11 @@ import WorkspaceView from './components/WorkspaceView'; import { CartProvider } from './context/CartContext'; +// Auth Pages +import Login from './pages/shared/Login'; +import Signup from './pages/shared/Signup'; +import SellerVerification from './pages/shared/SellerVerification'; + // Buyer Pages import MapDiscovery from './pages/buyer/MapDiscovery'; import Discover from './pages/buyer/Discover'; @@ -14,6 +19,7 @@ import ProductDetail from './pages/buyer/ProductDetail'; import Cart from './pages/buyer/Cart'; import Checkout from './pages/buyer/Checkout'; import Orders from './pages/buyer/Orders'; +import BuyerProfile from './pages/buyer/BuyerProfile'; // Seller Pages import Dashboard from './pages/seller/dashboard'; @@ -23,6 +29,10 @@ const App = () => ( + } /> + } /> + } /> + } />} @@ -51,6 +61,7 @@ const App = () => ( } /> } /> } /> + } /> } /> diff --git a/frontend/src/components/RoleBasedSidebar.jsx b/frontend/src/components/RoleBasedSidebar.jsx index 540b620..6030877 100644 --- a/frontend/src/components/RoleBasedSidebar.jsx +++ b/frontend/src/components/RoleBasedSidebar.jsx @@ -15,6 +15,7 @@ import { Truck, DollarSign, Compass, + User, } from 'lucide-react'; const SidebarNavItem = ({ diff --git a/frontend/src/index.css b/frontend/src/index.css index 3965264..bf60557 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -431,6 +431,9 @@ h6 { --input: rgba(54, 46, 37, 0.15); --ring: #A0522D; + --muted: rgba(54, 46, 37, 0.05); + --muted-foreground: rgba(54, 46, 37, 0.55); + --chart-1: #A0522D; --chart-2: #3D5A3E; --chart-3: #8B6914; @@ -488,6 +491,9 @@ h6 { --input: rgba(245, 240, 232, 0.12); --ring: #C8744C; + --muted: rgba(245, 240, 232, 0.05); + --muted-foreground: rgba(245, 240, 232, 0.55); + --sidebar: #241F1B; --sidebar-foreground: #F5F0E8; diff --git a/frontend/src/layouts/SharedSidebar.jsx b/frontend/src/layouts/SharedSidebar.jsx index 1f7287a..82cdd4b 100644 --- a/frontend/src/layouts/SharedSidebar.jsx +++ b/frontend/src/layouts/SharedSidebar.jsx @@ -1,5 +1,5 @@ import { Link } from 'react-router-dom'; -import { User, X } from 'lucide-react'; +import { User, X, LogOut } from 'lucide-react'; /** * SharedSidebar @@ -65,7 +65,7 @@ export const SharedSidebar = ({ sidebarContent, isSidebarOpen, setIsSidebarOpen {/* Profile footer */} -
+
Profile
+ + + + Sign Out +
diff --git a/frontend/src/pages/buyer/BuyerProfile.jsx b/frontend/src/pages/buyer/BuyerProfile.jsx new file mode 100644 index 0000000..dea4d82 --- /dev/null +++ b/frontend/src/pages/buyer/BuyerProfile.jsx @@ -0,0 +1,300 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { Upload, CheckCircle, Save, MapPin, User, FileText, LogOut, ShieldCheck, Mail, Phone, Camera } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Map, MapMarker, MapControls, MarkerContent, MarkerLabel } from '@/components/ui/map'; + +const BuyerProfile = () => { + const navigate = useNavigate(); + const [isSaved, setIsSaved] = useState(false); + + const [formData, setFormData] = useState(() => { + const saved = localStorage.getItem('buyerProfile'); + if (saved) { + try { return JSON.parse(saved); } catch (e) {} + } + return { + firstName: '', + middleName: '', + lastName: '', + email: '', + phone: '', + address: { + street: '', + city: '', + state: '', + zipCode: '', + }, + idFile: null, + location: { + lng: 121.0215, + lat: 14.5995, + } + }; + }); + + const [mapViewport, setMapViewport] = useState({ + center: [formData.location.lng, formData.location.lat], + zoom: 12, + }); + + const handleInputChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value }); + + const handleAddressChange = (e) => setFormData({ + ...formData, + address: { ...formData.address, [e.target.name]: e.target.value } + }); + + const handleFileChange = (e, field) => { + if (e.target.files && e.target.files[0]) { + setFormData({ ...formData, [field]: e.target.files[0] }); + } + }; + + const handleDragEnd = (e) => setFormData({ + ...formData, + location: { lng: e.lng, lat: e.lat } + }); + + const handleLocate = (coords) => { + setFormData({ + ...formData, + location: { lng: coords.longitude, lat: coords.latitude } + }); + setMapViewport({ center: [coords.longitude, coords.latitude], zoom: 15 }); + }; + + const handleSave = (e) => { + e.preventDefault(); + const dataToSave = { ...formData, idFile: null }; + localStorage.setItem('buyerProfile', JSON.stringify(dataToSave)); + setIsSaved(true); + setTimeout(() => setIsSaved(false), 3000); + }; + + const handleLogout = () => { + // Clear any auth tokens or user context here if they exist + navigate('/login'); + }; + + const initials = `${formData.firstName?.charAt(0) || ''}${formData.lastName?.charAt(0) || ''}`.toUpperCase() || 'U'; + + return ( +
+ {/* Header Banner */} +
+
+
+ +
+
+ + {/* Left Sidebar Profile Summary */} +
+
+ + {/* Avatar */} +
+
+
+ {initials} +
+
+ +
+
+
+
+
+
+ +

+ {formData.firstName || formData.lastName ? `${formData.firstName} ${formData.lastName}` : 'Guest User'} +

+

+ Verified Buyer +

+ +
+ +
+
+
+ +
+ {formData.email || 'No email provided'} +
+
+
+ +
+ {formData.phone || 'No phone provided'} +
+
+ +
+ + +
+
+ + {/* Right Form Content */} +
+
+ + {/* Personal Information */} +
+
+
+ +
+

Personal Details

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + {/* Delivery Address & Location */} +
+
+
+ +
+

Delivery Address

+
+ +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ +
+
+ + Drag pin to adjust +
+
+ + + + +
+
+
+ Deliver Here + + + +
+
+
+ + {/* Verification Document */} +
+
+
+ +
+

Identity Verification

+
+
+ +

For secure transactions, we require a valid government-issued ID.

+ +
+
+
+ +
+
+ +
+

PNG, JPG, PDF up to 10MB

+ + {formData.idFile && ( +
+ + {formData.idFile.name} +
+ )} +
+
+
+
+ +
+ +
+ +
+
+
+
+ ); +}; + +export default BuyerProfile; diff --git a/frontend/src/pages/buyer/Checkout.jsx b/frontend/src/pages/buyer/Checkout.jsx index 82f7462..e22ec99 100644 --- a/frontend/src/pages/buyer/Checkout.jsx +++ b/frontend/src/pages/buyer/Checkout.jsx @@ -66,21 +66,29 @@ const Checkout = () => { const [step, setStep] = useState('delivery'); // 'delivery', 'payment', 'review' const [isProcessing, setIsProcessing] = useState(false); const [paymentMethod, setPaymentMethod] = useState('card'); // 'card', 'gcash', 'cod' - const [formData, setFormData] = useState({ - firstName: '', - lastName: '', - email: '', - phone: '', - address: '', - city: '', - province: '', - zipCode: '', - region: '', - deliveryNotes: '', - cardNumber: '', - cardExpiry: '', - cardCvv: '', - cardholderName: '' + const [formData, setFormData] = useState(() => { + const savedProfile = localStorage.getItem('buyerProfile'); + let parsed = null; + if (savedProfile) { + try { parsed = JSON.parse(savedProfile); } catch (e) {} + } + + return { + firstName: parsed?.firstName || '', + lastName: parsed?.lastName || '', + email: parsed?.email || '', + phone: parsed?.phone || '', + address: parsed?.address?.street || '', + city: parsed?.address?.city || '', + province: parsed?.address?.state || '', + zipCode: parsed?.address?.zipCode || '', + region: '', + deliveryNotes: '', + cardNumber: '', + cardExpiry: '', + cardCvv: '', + cardholderName: parsed ? `${parsed.firstName} ${parsed.lastName}`.trim().toUpperCase() : '' + }; }); const handleChange = (e) => setFormData((p) => ({ ...p, [e.target.name]: e.target.value })); diff --git a/frontend/src/pages/buyer/ProductDetail.jsx b/frontend/src/pages/buyer/ProductDetail.jsx index 2bdedf2..96ba55a 100644 --- a/frontend/src/pages/buyer/ProductDetail.jsx +++ b/frontend/src/pages/buyer/ProductDetail.jsx @@ -57,7 +57,7 @@ const ProductDetail = () => { return (
-
+
{/* Back button */} + +
+

+ Don't have an account?{' '} + + Create one now + +

+
+ +
+
+
+ ); +}; + +export default Login; \ No newline at end of file diff --git a/frontend/src/pages/shared/SellerVerification.jsx b/frontend/src/pages/shared/SellerVerification.jsx new file mode 100644 index 0000000..c6624a9 --- /dev/null +++ b/frontend/src/pages/shared/SellerVerification.jsx @@ -0,0 +1,403 @@ +import React, { useState } from 'react'; +import { Upload, MapPin, Store, FileText, CheckCircle, ArrowRight, ArrowLeft, ShieldCheck, Map as MapIcon, User } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { Map, MapMarker, MapControls, MarkerContent, MarkerLabel } from '@/components/ui/map'; +import { Link } from 'react-router-dom'; + +const SellerVerification = () => { + const [step, setStep] = useState(1); + const [isSubmitted, setIsSubmitted] = useState(false); + const [formData, setFormData] = useState({ + firstName: '', + middleName: '', + lastName: '', + phone: '', + storeName: '', + category: '', + description: '', + address: { + street: '', + city: '', + state: '', + zipCode: '', + }, + permitFile: null, + idFile: null, + location: { + lng: 121.0215, // Manila coordinates + lat: 14.5995, + } + }); + + const handleAddressChange = (e) => { + setFormData({ + ...formData, + address: { + ...formData.address, + [e.target.name]: e.target.value + } + }); + }; + + const [mapViewport, setMapViewport] = useState({ + center: [121.0215, 14.5995], + zoom: 12, + }); + + const handleInputChange = (e) => { + setFormData({ ...formData, [e.target.name]: e.target.value }); + }; + + const handleFileChange = (e, field) => { + if (e.target.files && e.target.files[0]) { + setFormData({ ...formData, [field]: e.target.files[0] }); + } + }; + + const handleDragEnd = (e) => { + setFormData({ + ...formData, + location: { lng: e.lng, lat: e.lat } + }); + }; + + const handleLocate = (coords) => { + setFormData({ + ...formData, + location: { lng: coords.longitude, lat: coords.latitude } + }); + setMapViewport({ + center: [coords.longitude, coords.latitude], + zoom: 15, + }); + }; + + const nextStep = () => setStep(step + 1); + const prevStep = () => setStep(step - 1); + + const handleSubmit = (e) => { + e.preventDefault(); + console.log('Seller Verification Submitted', formData); + setIsSubmitted(true); + }; + + if (isSubmitted) { + return ( +
+
+
+
+ +
+
+

Application Received

+

+ Thank you for applying to become a seller. We are reviewing your documents and store information. You will be notified once your store is approved. +

+
+ + + +
+
+
+ ); + } + + return ( +
+ + {/* Decorative background elements */} +
+
+ +
+
+ +
+
+
= 1 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 2 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 3 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
= 4 ? 'w-8 bg-primary/80' : 'w-4 bg-muted'}`} /> +
+
+ +
+

+ {step === 1 && "Seller Identity"} + {step === 2 && "Store Basics"} + {step === 3 && "Store Location"} + {step === 4 && "Verification Documents"} +

+

+ {step === 1 && "Please provide your authentic legal identification details."} + {step === 2 && "Tell us about the craft you sell."} + {step === 3 && "Where can buyers find your physical store or workshop?"} + {step === 4 && "Upload necessary IDs and permits to verify your identity."} +

+
+ +
e.preventDefault()} className="space-y-8"> + + {/* Step 1: Personal Identity */} + {step === 1 && ( +
+
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ )} + + {/* Step 2: Store Basics */} + {step === 2 && ( +
+
+ + +
+ +
+ + +
+ +
+ +