├── src
├── index.css
├── images
│ ├── news.jpg
│ ├── shopping2.jpg
│ ├── shopping3.jpg
│ ├── shopping4.jpg
│ └── viva-img.jpg
├── api
│ ├── order.js
│ └── product.js
├── main.jsx
├── components
│ ├── Footer.css
│ ├── Footer.jsx
│ ├── NewsSearch.css
│ ├── Form.css
│ ├── Form.jsx
│ ├── Nav.jsx
│ ├── NewsSearchBar.jsx
│ ├── NewsDisplay.jsx
│ └── ProductList.jsx
├── App.css
├── pages
│ ├── Product.jsx
│ ├── SearchNews.jsx
│ ├── Admin
│ │ ├── ViewProduct.jsx
│ │ └── AddOrEditProduct.jsx
│ ├── Cart.css
│ └── Cart.jsx
├── App.jsx
└── assets
│ └── react.svg
├── .gitignore
├── vite.config.js
├── index.html
├── package.json
├── eslint.config.js
├── public
└── vite.svg
└── README.md
/src/index.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss"
--------------------------------------------------------------------------------
/src/images/news.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sri91524/capstoneproject-frontend/HEAD/src/images/news.jpg
--------------------------------------------------------------------------------
/src/images/shopping2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sri91524/capstoneproject-frontend/HEAD/src/images/shopping2.jpg
--------------------------------------------------------------------------------
/src/images/shopping3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sri91524/capstoneproject-frontend/HEAD/src/images/shopping3.jpg
--------------------------------------------------------------------------------
/src/images/shopping4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sri91524/capstoneproject-frontend/HEAD/src/images/shopping4.jpg
--------------------------------------------------------------------------------
/src/images/viva-img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sri91524/capstoneproject-frontend/HEAD/src/images/viva-img.jpg
--------------------------------------------------------------------------------
/src/api/order.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | const BASE_URL=import.meta.env.VITE_API_BASE_URL
3 |
4 | //Post Order
5 | export async function createOrder(){
6 | const res = await axios.post(`${BASE_URL}/api/product`,{products});
7 | return res.data;
8 | }
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react'
2 | import { createRoot } from 'react-dom/client'
3 | import './index.css'
4 | import App from './App.jsx'
5 | import { BrowserRouter} from 'react-router-dom';
6 |
7 | createRoot(document.getElementById('root')).render(
8 |
9 |
10 |
11 |
12 | ,
13 | )
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 | .env
26 |
27 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import tailwindcss from "@tailwindcss/vite";
4 |
5 | // https://vite.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), tailwindcss()],
8 | server: {
9 | proxy: {
10 | "/api": {
11 | target: "http://localhost:4000",
12 | changeOrigin: true,
13 | },
14 | },
15 | },
16 | })
17 |
--------------------------------------------------------------------------------
/src/components/Footer.css:
--------------------------------------------------------------------------------
1 | footer{
2 | display:flex;
3 | justify-content: center;
4 | align-items: center;
5 | text-align: center;
6 | background-color: black;
7 | color: white;
8 | gap: 30px;
9 | font-size: 1em;
10 | padding: 5px;
11 | margin-bottom: 10px;
12 | }
13 |
14 | footer a{
15 | color:white;
16 | text-decoration: none;
17 | }
18 |
19 | footer a:hover{
20 | text-decoration: underline;
21 | }
--------------------------------------------------------------------------------
/src/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import '../components/Footer.css'
3 |
4 | function Footer(){
5 |
6 | return(
7 |
14 | )
15 | }
16 |
17 | export default Footer;
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Viva Fashions
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@heroicons/react": "^1.0.6",
14 | "@tailwindcss/vite": "^4.0.15",
15 | "axios": "^1.8.4",
16 | "react": "^19.0.0",
17 | "react-dom": "^19.0.0",
18 | "react-icons": "^5.5.0",
19 | "react-router-dom": "^7.4.0",
20 | "tailwindcss": "^4.0.15"
21 | },
22 | "devDependencies": {
23 | "@eslint/js": "^9.21.0",
24 | "@types/react": "^19.0.10",
25 | "@types/react-dom": "^19.0.4",
26 | "@vitejs/plugin-react": "^4.3.4",
27 | "eslint": "^9.21.0",
28 | "eslint-plugin-react-hooks": "^5.1.0",
29 | "eslint-plugin-react-refresh": "^0.4.19",
30 | "globals": "^15.15.0",
31 | "vite": "^6.2.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import reactHooks from 'eslint-plugin-react-hooks'
4 | import reactRefresh from 'eslint-plugin-react-refresh'
5 |
6 | export default [
7 | { ignores: ['dist'] },
8 | {
9 | files: ['**/*.{js,jsx}'],
10 | languageOptions: {
11 | ecmaVersion: 2020,
12 | globals: globals.browser,
13 | parserOptions: {
14 | ecmaVersion: 'latest',
15 | ecmaFeatures: { jsx: true },
16 | sourceType: 'module',
17 | },
18 | },
19 | plugins: {
20 | 'react-hooks': reactHooks,
21 | 'react-refresh': reactRefresh,
22 | },
23 | rules: {
24 | ...js.configs.recommended.rules,
25 | ...reactHooks.configs.recommended.rules,
26 | 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27 | 'react-refresh/only-export-components': [
28 | 'warn',
29 | { allowConstantExport: true },
30 | ],
31 | },
32 | },
33 | ]
34 |
--------------------------------------------------------------------------------
/src/api/product.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | const BASE_URL=import.meta.env.VITE_API_BASE_URL
3 |
4 | //create new product
5 | export async function createProduct(product){
6 | try{
7 | const res = await axios.post(`${BASE_URL}/api/product`,product);
8 | return res.data;
9 | }catch(error){
10 | console.log(`api error -${error}`);
11 | }
12 | }
13 |
14 | //Get all products
15 | export async function getAllProducts(){
16 | const res = await axios.get(`${BASE_URL}/api/product`);
17 | return res.data;
18 | }
19 |
20 | //Get a specific product
21 | export async function getProduct(prodId){
22 | const res = await axios.get(`${BASE_URL}/api/product/${prodId}`);
23 | return res.data;
24 | }
25 |
26 | //update a product
27 | export async function updateProduct(prodId, product){
28 | const res = await axios.patch(`${BASE_URL}/api/product/${prodId}`,product);
29 | return res.data;
30 | }
31 |
32 | //Delete a product
33 | export async function deleteProduct(prodId){
34 | await axios.delete(`${BASE_URL}/api/product/${prodId}`);
35 | }
--------------------------------------------------------------------------------
/src/components/NewsSearch.css:
--------------------------------------------------------------------------------
1 | .search-container {
2 | display: flex;
3 | justify-content: flex-end; /* Aligns the form to the right */
4 | padding-right: 20px; /* Optional: Add some padding to the right */
5 | }
6 |
7 | .form-control {
8 | height: 20px; /* Adjust height of form controls */
9 | padding: 0 6px; /* Adjust padding to maintain the reduced height */
10 | font-size: 12px; /* Adjust font size for consistency */
11 | line-height: 24px; /* Vertically center text inside the controls */
12 | }
13 |
14 | .search-content {
15 | display: flex;
16 | gap: 16px; /* Add space between controls */
17 | align-items: center;
18 | }
19 |
20 | input[type="text"], select {
21 | height: 32px; /* Ensure controls have the same height */
22 | padding: 0 12px; /* Adjust padding */
23 | font-size: 14px; /* Consistent font size */
24 | }
25 |
26 | input[type="submit"] {
27 | height: 32px;
28 | padding: 0 12px;
29 | font-size: 14px;
30 | cursor: pointer;
31 | background-color: rgb(212, 175, 55); /* Button color */
32 | border: none;
33 | border-radius: 4px;
34 | }
--------------------------------------------------------------------------------
/src/components/Form.css:
--------------------------------------------------------------------------------
1 | .form-container {
2 | display: flex;
3 | justify-content: flex-end; /* Aligns the form to the right */
4 | padding-right: 20px; /* Optional: Add some padding to the right */
5 | }
6 |
7 | .form-content {
8 | display: flex;
9 | align-items: center; /* Vertically aligns the items in the form */
10 | gap: 10px; /* Adds spacing between the form elements */
11 | flex-wrap: nowrap; /* Prevents wrapping of form controls */
12 | }
13 |
14 | .form-control {
15 | height: 20px; /* Reduced height for form controls */
16 | padding: 0 6px; /* Reduced padding to maintain the reduced height */
17 | font-size: 12px; /* Adjust font size for consistency */
18 | line-height: 24px; /* Vertically center text inside the controls */
19 | }
20 |
21 | input[type="submit"] {
22 | height: 24px; /* Ensure the button has the same height as form controls */
23 | padding: 0 6px; /* Padding for the button */
24 | cursor: pointer;
25 | font-size: 12px; /* Same font size for consistency */
26 | line-height: 24px; /* Ensure text is vertically aligned inside the button */
27 | display: inline-flex; /* Ensures the button stays inline with other items */
28 | align-items: center; /* Vertically center the button text */
29 | background-color: rgb(212, 175, 55); /* Button color */
30 | border: none; /* Optional: Remove button border */
31 | border-radius: 4px; /* Optional: Add rounded corners */
32 | }
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Form.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import './Form.css'
3 |
4 | function Form(props){
5 |
6 | const [formData, setFormData] = useState({category:"",searchterm:""});
7 | //onchanging form, form data is set
8 | const handleChange = (e) =>{
9 | setFormData({...formData, [e.target.name]:e.target.value});
10 | }
11 | //category and search term will be passed as props to product.jsx page
12 | const handleSubmit = (e) =>{
13 | e.preventDefault();
14 | props.productsearch(formData.category,formData.searchterm);
15 | }
16 |
17 |
18 | return(
19 |
20 |
47 |
48 | )
49 | };
50 |
51 | export default Form;
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .nav{
4 | display: flex;
5 | justify-content:right;
6 | align-items: center;
7 | text-align: center;
8 | background-color: black;
9 | color:white;
10 | gap:30px;
11 | font-size: 1em;
12 |
13 | padding: 5px;
14 | margin-bottom: 10px;
15 | }
16 |
17 | .headertext{
18 | color:rgb(212, 175, 55);
19 | text-align: left;
20 | align-items: left;
21 | font-weight: bold;
22 | margin: 0;
23 | font-size: 24px;
24 | flex: 1;
25 | }
26 | .cartcountbadge{
27 | position: absolute;
28 | top: -2px;
29 | right: 110px;
30 | background-color: rgb(212, 175, 55);
31 | color: white;
32 | border-radius: 50%;
33 | width: 20px;
34 | height: 20px;
35 | display: flex;
36 | justify-content: center;
37 | align-items: center;
38 | font-size: 12px;
39 | margin-right: 30px;
40 | }
41 |
42 |
43 | .img-container{
44 | display: flex;
45 | flex-wrap: wrap;
46 | gap:20px;
47 | justify-content:flex-start;
48 | flex-direction: row;
49 | padding: 20px;
50 | margin:10px;
51 | }
52 |
53 | .title{
54 | font-family: 'Roboto', sans-serif;
55 | font-size: 0.8rem;
56 | text-align: center;
57 | align-items: center;
58 | }
59 |
60 | .hover-image {
61 | transition: transform 0.5s ease; /* Smooth transition for the transform property */
62 | }
63 |
64 | .hover-image:hover {
65 | transform: scale(1.1) !important; /* Slightly scale up the image on hover */
66 | }
67 |
68 | .full-width-image img {
69 | width: 100%; /* Ensures the image spans the full width */
70 | height: 50px; /* Fixed height of the image */
71 | object-fit:contain; /* Ensures the image fills the space without distorting */
72 | border-radius: 50%;
73 | }
--------------------------------------------------------------------------------
/src/pages/Product.jsx:
--------------------------------------------------------------------------------
1 | import Form from '../components/Form';
2 | import ProductList from '../components/ProductList';
3 | import Cart from './Cart'
4 | import { useState,useEffect } from 'react';
5 | const BASE_URL=import.meta.env.VITE_API_BASE_URL
6 |
7 | function Product({addToCart}){
8 |
9 | //to store products in state
10 | const [productResult, setProductResult] = useState([]);
11 | //To set cart items in state
12 | const [cart, setCart] = useState([]);
13 | //to toggle cart visibility
14 | const[isCartOpen, setIsCartOpen] = useState(false);
15 |
16 | // to get list of products from db based on category and search filter
17 | const getProducts = async(prodcategory, prodsearch) =>{
18 | try{
19 | const response = await fetch(`${BASE_URL}/api/product?category=${prodcategory}&search=${prodsearch}`);
20 | const data = await response.json();
21 |
22 | if (!response.ok) {
23 | throw new Error(`HTTP error! Status: ${response.status}`);
24 | }
25 | console.log(data);
26 |
27 | setProductResult(data);
28 |
29 | }catch(e){
30 | console.error(e);
31 | }
32 | }
33 | //Initial load of products without filter
34 | useEffect(() =>{
35 | getProducts('','');
36 | },[])
37 |
38 |
39 |
40 | return (
41 | <>
42 |