diff --git a/client/src/components/CarModifications.js b/client/src/components/CarModifications.js index 05ee3c1..f916ac5 100644 --- a/client/src/components/CarModifications.js +++ b/client/src/components/CarModifications.js @@ -72,6 +72,126 @@ const CarModifications = () => { icon: wheelsIcon, category: 'Wheels', }, + { + id: 7, + name: 'Turbocharger Kit', + description: 'Complete turbo upgrade kit for significant power gains', + price: '€2499', + icon: engineIcon, + category: 'Engine', + }, + { + id: 8, + name: 'Cat-Back Exhaust', + description: 'Performance exhaust system with sport sound', + price: '€799', + icon: exhaustIcon, + category: 'Exhaust', + }, + { + id: 9, + name: 'Coilover Suspension', + description: 'Fully adjustable suspension system for perfect handling', + price: '€1299', + icon: suspensionIcon, + category: 'Suspension', + }, + { + id: 10, + name: 'Big Brake Kit', + description: '6-piston caliper upgrade with larger rotors', + price: '€1499', + icon: brakesIcon, + category: 'Brakes', + }, + { + id: 11, + name: 'Forged Wheels', + description: 'Lightweight forged alloy wheels for better performance', + price: '€1999', + icon: wheelsIcon, + category: 'Wheels', + }, + { + id: 12, + name: 'Stage 2 Tune', + description: 'Advanced ECU remap for maximum power gains', + price: '€499', + icon: engineIcon, + category: 'Engine', + }, + { + id: 13, + name: 'Downpipe', + description: 'High-flow downpipe for improved exhaust flow', + price: '€349', + icon: exhaustIcon, + category: 'Exhaust', + }, + { + id: 14, + name: 'Sway Bars', + description: 'Upgraded sway bars for reduced body roll', + price: '€299', + icon: suspensionIcon, + category: 'Suspension', + }, + { + id: 15, + name: 'Brake Pads', + description: 'High-performance brake pads for better stopping', + price: '€199', + icon: brakesIcon, + category: 'Brakes', + }, + { + id: 16, + name: 'Wheel Bearings', + description: 'Upgraded wheel bearings for smoother rotation', + price: '€249', + icon: wheelsIcon, + category: 'Wheels', + }, + { + id: 17, + name: 'Intercooler Upgrade', + description: 'Larger intercooler for better cooling efficiency', + price: '€699', + icon: engineIcon, + category: 'Engine', + }, + { + id: 18, + name: 'Exhaust Manifold', + description: 'Equal-length exhaust manifold for better flow', + price: '€449', + icon: exhaustIcon, + category: 'Exhaust', + }, + { + id: 19, + name: 'Strut Brace', + description: 'Front strut brace for improved chassis rigidity', + price: '€199', + icon: suspensionIcon, + category: 'Suspension', + }, + { + id: 20, + name: 'Brake Lines', + description: 'Stainless steel braided brake lines', + price: '€149', + icon: brakesIcon, + category: 'Brakes', + }, + { + id: 21, + name: 'Wheel Locks', + description: 'Security wheel locks to prevent theft', + price: '€89', + icon: wheelsIcon, + category: 'Wheels', + } ]; const filteredModifications = modifications.filter((mod) => diff --git a/client/src/components/CustomerManagement.js b/client/src/components/CustomerManagement.js new file mode 100644 index 0000000..f0bf083 --- /dev/null +++ b/client/src/components/CustomerManagement.js @@ -0,0 +1,252 @@ +import React, { useState, useEffect } from 'react'; +import { + Container, + Typography, + Box, + Button, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + TextField, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Paper, + IconButton, + Alert, +} from '@mui/material'; +import EditIcon from '@mui/icons-material/Edit'; +import DeleteIcon from '@mui/icons-material/Delete'; +import AddIcon from '@mui/icons-material/Add'; +import axios from 'axios'; + +const CustomerManagement = () => { + const [customers, setCustomers] = useState([]); + const [open, setOpen] = useState(false); + const [selectedCustomer, setSelectedCustomer] = useState(null); + const [formData, setFormData] = useState({ + name: '', + email: '', + phone: '', + address: '', + carModel: '', + carYear: '', + }); + const [error, setError] = useState(''); + const [success, setSuccess] = useState(''); + + useEffect(() => { + fetchCustomers(); + }, []); + + const fetchCustomers = async () => { + try { + const response = await axios.get('http://localhost:5000/api/customers'); + setCustomers(response.data); + } catch (err) { + setError('Failed to fetch customers'); + } + }; + + const handleOpen = (customer = null) => { + if (customer) { + setSelectedCustomer(customer); + setFormData(customer); + } else { + setSelectedCustomer(null); + setFormData({ + name: '', + email: '', + phone: '', + address: '', + carModel: '', + carYear: '', + }); + } + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + setError(''); + setSuccess(''); + }; + + const handleChange = (e) => { + setFormData({ + ...formData, + [e.target.name]: e.target.value, + }); + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + try { + if (selectedCustomer) { + await axios.put(`http://localhost:5000/api/customers/${selectedCustomer._id}`, formData); + setSuccess('Customer updated successfully'); + } else { + await axios.post('http://localhost:5000/api/customers', formData); + setSuccess('Customer added successfully'); + } + fetchCustomers(); + handleClose(); + } catch (err) { + setError(err.response?.data?.message || 'An error occurred'); + } + }; + + const handleDelete = async (id) => { + if (window.confirm('Are you sure you want to delete this customer?')) { + try { + await axios.delete(`http://localhost:5000/api/customers/${id}`); + setSuccess('Customer deleted successfully'); + fetchCustomers(); + } catch (err) { + setError('Failed to delete customer'); + } + } + }; + + return ( + + + + Customer Management + + + + + {error && ( + + {error} + + )} + + {success && ( + + {success} + + )} + + + + + + Name + Email + Phone + Car Model + Car Year + Actions + + + + {customers.map((customer) => ( + + {customer.name} + {customer.email} + {customer.phone} + {customer.carModel} + {customer.carYear} + + handleOpen(customer)} color="primary"> + + + handleDelete(customer._id)} color="error"> + + + + + ))} + +
+
+ + + + {selectedCustomer ? 'Edit Customer' : 'Add New Customer'} + +
+ + + + + + + + + + + + +
+
+
+ ); +}; + +export default CustomerManagement; \ No newline at end of file diff --git a/models/Customer.js b/models/Customer.js index 5648099..c027459 100644 --- a/models/Customer.js +++ b/models/Customer.js @@ -3,21 +3,34 @@ const mongoose = require('mongoose'); const customerSchema = new mongoose.Schema({ name: { type: String, - required: true + required: true, + trim: true }, email: { type: String, required: true, - unique: true + unique: true, + trim: true, + lowercase: true }, phone: { - type: String + type: String, + required: true, + trim: true }, - carDetails: { - make: String, - model: String, - year: Number, - modifications: [String] + address: { + type: String, + trim: true + }, + carModel: { + type: String, + required: true, + trim: true + }, + carYear: { + type: String, + required: true, + trim: true }, createdAt: { type: Date, @@ -29,4 +42,10 @@ const customerSchema = new mongoose.Schema({ } }); +// Update the updatedAt timestamp before saving +customerSchema.pre('save', function(next) { + this.updatedAt = Date.now(); + next(); +}); + module.exports = mongoose.model('Customer', customerSchema); \ No newline at end of file diff --git a/routes/customers.js b/routes/customers.js index 29ac379..ca15ee8 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -1,73 +1,78 @@ const express = require('express'); const router = express.Router(); const Customer = require('../models/Customer'); +const auth = require('../middleware/auth'); // Get all customers -router.get('/', async (req, res) => { +router.get('/', auth, async (req, res) => { try { const customers = await Customer.find().sort({ name: 1 }); res.json(customers); - } catch (error) { - console.error('Error fetching customers:', error); - res.status(500).json({ message: 'Server error' }); + } catch (err) { + res.status(500).json({ message: err.message }); } }); // Get single customer -router.get('/:id', async (req, res) => { +router.get('/:id', auth, async (req, res) => { try { const customer = await Customer.findById(req.params.id); if (!customer) { return res.status(404).json({ message: 'Customer not found' }); } res.json(customer); - } catch (error) { - console.error('Error fetching customer:', error); - res.status(500).json({ message: 'Server error' }); + } catch (err) { + res.status(500).json({ message: err.message }); } }); // Create customer -router.post('/', async (req, res) => { +router.post('/', auth, async (req, res) => { + const customer = new Customer({ + name: req.body.name, + email: req.body.email, + phone: req.body.phone, + address: req.body.address, + carModel: req.body.carModel, + carYear: req.body.carYear, + }); + try { - const customer = new Customer(req.body); - await customer.save(); - res.status(201).json(customer); - } catch (error) { - console.error('Error creating customer:', error); - res.status(500).json({ message: 'Server error' }); + const newCustomer = await customer.save(); + res.status(201).json(newCustomer); + } catch (err) { + res.status(400).json({ message: err.message }); } }); // Update customer -router.put('/:id', async (req, res) => { +router.put('/:id', auth, async (req, res) => { try { - const customer = await Customer.findByIdAndUpdate( - req.params.id, - { ...req.body, updatedAt: Date.now() }, - { new: true } - ); + const customer = await Customer.findById(req.params.id); if (!customer) { return res.status(404).json({ message: 'Customer not found' }); } - res.json(customer); - } catch (error) { - console.error('Error updating customer:', error); - res.status(500).json({ message: 'Server error' }); + + Object.assign(customer, req.body); + const updatedCustomer = await customer.save(); + res.json(updatedCustomer); + } catch (err) { + res.status(400).json({ message: err.message }); } }); // Delete customer -router.delete('/:id', async (req, res) => { +router.delete('/:id', auth, async (req, res) => { try { - const customer = await Customer.findByIdAndDelete(req.params.id); + const customer = await Customer.findById(req.params.id); if (!customer) { return res.status(404).json({ message: 'Customer not found' }); } - res.json({ message: 'Customer deleted successfully' }); - } catch (error) { - console.error('Error deleting customer:', error); - res.status(500).json({ message: 'Server error' }); + + await customer.remove(); + res.json({ message: 'Customer deleted' }); + } catch (err) { + res.status(500).json({ message: err.message }); } });