├── postcss.config.js
├── vite.config.js
├── tailwind.config.js
├── src
├── Layout.jsx
├── index.css
├── component
│ ├── Footer.jsx
│ ├── Card.jsx
│ ├── Section.jsx
│ └── Navbar.jsx
├── page
│ ├── About.jsx
│ ├── Products.jsx
│ ├── SingleProduct.jsx
│ ├── Contact.jsx
│ └── Home.jsx
└── main.jsx
├── .gitignore
├── README.md
├── index.html
├── package.json
├── eslint.config.js
└── public
└── vite.svg
/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | content: [
4 | "./index.html",
5 | "./src/**/*.{js,jsx,ts,tsx}"
6 | ],
7 | theme: {
8 | extend: {},
9 | },
10 | plugins: [],
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/src/Layout.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Outlet } from 'react-router-dom';
3 | import Navbar from './component/Navbar';
4 |
5 | const Layout = () => {
6 | return (
7 | <>
8 |
9 |
10 | >
11 | )
12 | }
13 |
14 | export default Layout;
15 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | .truncate-title {
6 | overflow: hidden;
7 | text-overflow: ellipsis;
8 | white-space: nowrap;
9 | }
10 |
11 | .truncate-description {
12 | display: -webkit-box;
13 | -webkit-line-clamp: 2;
14 | /* Show two lines */
15 | -webkit-box-orient: vertical;
16 | overflow: hidden;
17 | text-overflow: ellipsis;
18 | }
--------------------------------------------------------------------------------
/src/component/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const Footer = () => {
4 | return (
5 |
12 | );
13 | };
14 |
15 | export default Footer;
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Simple E-Commerce
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "router",
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 | "react": "^18.3.1",
14 | "react-dom": "^18.3.1",
15 | "react-router-dom": "^6.26.2"
16 | },
17 | "devDependencies": {
18 | "@eslint/js": "^9.9.0",
19 | "@types/react": "^18.3.3",
20 | "@types/react-dom": "^18.3.0",
21 | "@vitejs/plugin-react": "^4.3.1",
22 | "autoprefixer": "^10.4.20",
23 | "eslint": "^9.9.0",
24 | "eslint-plugin-react": "^7.35.0",
25 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
26 | "eslint-plugin-react-refresh": "^0.4.9",
27 | "globals": "^15.9.0",
28 | "postcss": "^8.4.45",
29 | "tailwindcss": "^3.4.11",
30 | "vite": "^5.4.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/page/About.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Section from '../component/Section'
3 | import Footer from '../component/Footer'
4 |
5 | const About = () => {
6 | return (
7 | <>
8 |
16 |
17 |
18 |
19 | >
20 | )
21 | }
22 |
23 | export default About
24 |
--------------------------------------------------------------------------------
/src/page/Products.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import CardList from '../component/Card';
4 | import Footer from '../component/Footer';
5 |
6 | const Products = () => {
7 | const [data, setData] = useState(null);
8 | const navigate = useNavigate();
9 |
10 | useEffect(() => {
11 | fetch('https://fakestoreapi.com/products')
12 | .then(res => res.json())
13 | .then(res => {
14 | setData(res);
15 | })
16 | .catch(err => {
17 | console.log(err);
18 | });
19 | }, []);
20 |
21 | const singleUser = (item) => {
22 | navigate(`/singleProduct/${item.id}`);
23 | };
24 | return (
25 | <>
26 |
31 |
32 | >
33 | )
34 | }
35 |
36 | export default Products
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import react from 'eslint-plugin-react'
4 | import reactHooks from 'eslint-plugin-react-hooks'
5 | import reactRefresh from 'eslint-plugin-react-refresh'
6 |
7 | export default [
8 | { ignores: ['dist'] },
9 | {
10 | files: ['**/*.{js,jsx}'],
11 | languageOptions: {
12 | ecmaVersion: 2020,
13 | globals: globals.browser,
14 | parserOptions: {
15 | ecmaVersion: 'latest',
16 | ecmaFeatures: { jsx: true },
17 | sourceType: 'module',
18 | },
19 | },
20 | settings: { react: { version: '18.3' } },
21 | plugins: {
22 | react,
23 | 'react-hooks': reactHooks,
24 | 'react-refresh': reactRefresh,
25 | },
26 | rules: {
27 | ...js.configs.recommended.rules,
28 | ...react.configs.recommended.rules,
29 | ...react.configs['jsx-runtime'].rules,
30 | ...reactHooks.configs.recommended.rules,
31 | 'react/jsx-no-target-blank': 'off',
32 | 'react-refresh/only-export-components': [
33 | 'warn',
34 | { allowConstantExport: true },
35 | ],
36 | },
37 | },
38 | ]
39 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { createRoot } from 'react-dom/client'
2 | import './index.css'
3 | import { createBrowserRouter, RouterProvider } from 'react-router-dom'
4 | import Layout from './Layout'
5 |
6 | import Home from './page/Home'
7 | import About from './page/About'
8 | import Contact from './page/Contact'
9 | import SingleProduct from './page/SingleProduct'
10 | import Products from './page/Products'
11 |
12 |
13 | const router = createBrowserRouter([
14 | {
15 | path: "/",
16 | element: ,
17 | children: [
18 | {
19 | path: "",
20 | element:
21 | },
22 | {
23 | path: "About",
24 | element:
25 | },
26 | {
27 | path: "Contact",
28 | element:
29 | },
30 | {
31 | path: "Products",
32 | element:
33 | },
34 | {
35 | path: "SingleProduct/:id",
36 | element:
37 | },
38 | {
39 | path: "*",
40 | element: Not found
41 | }
42 | ]
43 | }
44 | ]);
45 |
46 | createRoot(document.getElementById('root')).render(
47 |
48 | )
49 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/component/Card.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | const Card = ({data, singleUser}) => {
4 | return (
5 |
6 |
All Products
7 |
8 | {
9 | data ? data.map((item) => (
10 |
14 |
15 |

20 |
21 |
22 | {item.title}
23 |
24 |
25 | {item.description}
26 |
27 |
${item.price}
28 |
29 |
35 |
36 |
37 | )) : (
38 |
Loading...
39 | )
40 | }
41 |
42 |
43 | );
44 | }
45 |
46 | export default Card
47 |
--------------------------------------------------------------------------------
/src/component/Section.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'react-router-dom';
3 |
4 | const Section = ({
5 | title,
6 | subtitle,
7 | text,
8 | buttonText,
9 | buttonLink,
10 | imageSrc,
11 | imageAlt,
12 | reverseOrder = false
13 | }) => {
14 | return (
15 |
16 |
17 |
18 |
19 |
20 |
21 | {title}
22 |
23 | {subtitle &&
{subtitle}
}
24 |
25 | {text}
26 |
27 | {buttonText && (
28 |
32 | {buttonText}
33 |
34 | )}
35 |
36 |
37 |
38 |

43 |
44 |
45 |
46 |
47 | );
48 | };
49 |
50 | export default Section;
51 |
--------------------------------------------------------------------------------
/src/page/SingleProduct.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { useParams } from 'react-router-dom';
3 | import Footer from '../component/Footer'; // Adjust path as necessary
4 |
5 | const SingleProduct = () => {
6 | const [data, setData] = useState(null);
7 | const { id } = useParams();
8 |
9 | useEffect(() => {
10 | fetch(`https://fakestoreapi.com/products/${id}`)
11 | .then(res => res.json())
12 | .then(res => {
13 | setData(res);
14 | })
15 | .catch(err => {
16 | console.log(err);
17 | });
18 | }, [id]);
19 |
20 | return (
21 | <>
22 |
23 |
24 | {data ? (
25 |
26 | {/* Product Image */}
27 |
28 |

33 |
34 | {/* Product Details */}
35 |
36 |
{data.title}
37 |
{data.description}
38 |
${data.price}
39 |
Category: {data.category}
40 |
Rating: {data.rating.rate} ({data.rating.count} reviews)
41 |
47 |
48 |
49 | ) : (
50 |
Loading...
51 | )}
52 |
53 |
54 |
55 | >
56 | );
57 | };
58 |
59 | export default SingleProduct;
60 |
--------------------------------------------------------------------------------
/src/component/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import { Link } from 'react-router-dom';
3 |
4 | const Navbar = () => {
5 | const [isOpen, setIsOpen] = useState(false);
6 |
7 | const toggleMenu = () => {
8 | setIsOpen(!isOpen);
9 | };
10 |
11 | const closeMenu = () => {
12 | setIsOpen(false);
13 | };
14 |
15 | return (
16 |
67 | );
68 | };
69 |
70 | export default Navbar;
71 |
--------------------------------------------------------------------------------
/src/page/Contact.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Footer from '../component/Footer'
3 |
4 | const Contact = () => {
5 | return (
6 | <>
7 |
8 |
9 |
10 | {/* Contact Information */}
11 |
12 |
13 | Contact Us
14 |
15 |
16 | We’d love to hear from you! Whether you have questions, feedback, or just want to say hello, feel free to reach out to us.
17 |
18 |
19 | Email: umarofficial0121@gmail.com
20 |
21 |
22 | Phone: +92 317 2472531
23 |
24 |
25 | Address: Orangi Town Karachi
26 |
27 |
28 |
29 | {/* Contact Form */}
30 |
80 |
81 |
82 |
83 |
84 |
85 | >
86 | )
87 | }
88 |
89 | export default Contact
90 |
--------------------------------------------------------------------------------
/src/page/Home.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import Section from '../component/Section';
3 | import Footer from '../component/Footer';
4 |
5 | const Home = () => {
6 |
7 | return (
8 | <>
9 |
17 |
18 |
26 |
27 |
28 |
29 |
30 | {/* Contact Information */}
31 |
32 |
33 | Contact Us
34 |
35 |
36 | We’d love to hear from you! Whether you have questions, feedback, or just want to say hello, feel free to reach out to us.
37 |
38 |
39 | Email: umarofficial0121@gmail.com
40 |
41 |
42 | Phone: +92 317 2472531
43 |
44 |
45 | Address: Orangi Town Karachi
46 |
47 |
48 |
49 | {/* Contact Form */}
50 |
100 |
101 |
102 |
103 |
104 |
105 | >
106 | );
107 | };
108 |
109 | export default Home;
110 |
--------------------------------------------------------------------------------