inital push

main
Jeremy Hayes 2023-09-26 16:31:07 -05:00
parent ea1aaa1c7e
commit 8b3c8638b2
36 changed files with 8820 additions and 0 deletions

20
.eslintrc.cjs Normal file
View File

@ -0,0 +1,20 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:react/jsx-runtime',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
settings: { react: { version: '18.2' } },
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}

9
deploy.sh Executable file
View File

@ -0,0 +1,9 @@
echo "Switching to branch main"
git checkout main
echo "building app..."
npm run build
echo "Deploying files to server"
scp -r dist/* jeremy@154.56.60.138:/var/www/trailblazer.shop/
echo "DONE!"

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TrailBlazer Supply Co.</title>
</head>
<body class="font-bodyFont">
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

7867
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

36
package.json Normal file
View File

@ -0,0 +1,36 @@
{
"name": "frontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@react-icons/all-files": "^4.1.0",
"axios": "^1.5.0",
"framer-motion": "^10.16.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.11.0",
"react-router-dom": "^6.16.0",
"react-slick": "^0.29.0",
"slick-carousel": "^1.8.1"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react": "^4.0.3",
"autoprefixer": "^10.4.15",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"postcss": "^8.4.29",
"tailwindcss": "^3.3.3",
"vite": "^4.4.5"
}
}

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

BIN
public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

0
src/App.css Normal file
View File

38
src/App.jsx Normal file
View File

@ -0,0 +1,38 @@
import './App.css'
import { Route, Outlet, RouterProvider, createBrowserRouter, createRoutesFromElements } from 'react-router-dom'
import TopNav from './components/TopNav'
import Shop from './pages/Shop/Shop'
import Footer from './components/footer/Footer'
import { productsData } from './api/api'
import Signin from './pages/Signin/Signin'
import Register from './pages/Register/Register'
import NoPage from './pages/NoPage/NoPage'
function App() {
const Layout = ()=>(
<div>
<TopNav />
<Outlet />
<Footer />
</div>
)
const router = createBrowserRouter(
createRoutesFromElements(
<Route path='/' element={<Layout />}>
<Route index element={<Shop />} loader={productsData}></Route>
<Route path='signin' element={<Signin />}></Route>
<Route path='register' element={<Register />}></Route>
<Route path='*' element={<NoPage />}></Route>
</Route>
)
)
return (
<>
<RouterProvider router={router}></RouterProvider>
</>
)
}
export default App

6
src/api/api.js Normal file
View File

@ -0,0 +1,6 @@
import axios from "axios";
export async function productsData(){
const products = await axios.get('https://fakestoreapi.com/products')
return products
}

BIN
src/assets/comingsoon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

0
src/assets/index.js Normal file
View File

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
src/assets/prepare.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

1
src/assets/react.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/assets/tents.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 KiB

104
src/components/Banner.jsx Normal file
View File

@ -0,0 +1,104 @@
import React, { useState } from "react";
import Slider from "react-slick";
import tents from "../assets/tents.png";
import prepare from "../assets/prepare.png";
import comingSoon from "../assets/comingsoon.jpg";
const Banner = () => {
const [Active, setActive] = useState(0);
const settings = {
dots: true,
infinite: true,
slidesToShow: 1,
autoplay: true,
autoplaySpeed: 5000,
slidesToScroll: 1,
arrows: false,
pauseOnHover: true,
beforeChange: (prev, next) => {
setActive(next);
},
appendDots: (dots) => (
<div
style={{
position: "absolute",
top: "95%",
left: "45%",
transform: "translate(-50%, -50%)",
width: "210px",
}}
>
<ul
style={{
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
{" "}
{dots}{" "}
</ul>
</div>
),
customPaging: (i) => (
<div
style={i===Active ? {
width: "30px",
color: "blue",
border: "1px solid rgb(34, 139, 34)",
borderRadius: "50%",
display:"flex",
alignItems:"center",
justifyContent:"center",
color: "white",
background: "#131921",
padding: "3px 0",
cursor:"pointer",
} : {
width: "30px",
color: "blue",
border: "1px solid rgb(34, 139, 34)",
borderRadius: "50%",
display:"flex",
alignItems:"center",
justifyContent:"center",
color: "white",
background: "#232F3E",
padding: "3px 0",
cursor:"pointer",
}}
>
{i + 1}
</div>
),
};
return (
<div className="w-full">
<div className="w-full max-w-container mx-auto h-full relative">
<Slider {...settings}>
<div className="mx-auto">
<img src={comingSoon} alt="Tents and camping supplies" />
</div>
<div>
<img src={prepare} alt="Be prepared when disaster strikes" />
</div>
<div >
<img src={tents} alt="Tents and camping supplies" />
</div>
<div>
<img src={prepare} alt="Be prepared when disaster strikes" />
</div>
<div >
<img src={tents} alt="Tents and camping supplies" />
</div>
<div>
<img src={prepare} alt="Be prepared when disaster strikes" />
</div>
</Slider>
</div>
</div>
);
};
export default Banner;

21
src/components/Logo.jsx Normal file
View File

@ -0,0 +1,21 @@
import React from 'react'
import logo from "../assets/logo.png";
const Logo = () => {
return (
<div className="w-full p-3 flex justify-center text-white text-lg bg-transparent">
<span className="flex items-center">
<img className="w-20" src={logo} alt="logo" />
<span>
<p>
TrailBlazer
</p>
<p>Supply Co.</p>
</span>
</span>
</div>
)
}
export default Logo

View File

@ -0,0 +1,50 @@
import axios from "axios";
import React, { useEffect } from "react";
import { FaStar } from "react-icons/fa6";
import { useLoaderData } from "react-router-dom";
const Products = () => {
const data = useLoaderData();
const products = data.data;
console.log(products);
return (
<div className="max-w-screen-2xl px-5 mx-auto grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-10">
{products.map((item) => (
<div key={item.id} className="h-auto border-[1px] bg-white hover:border-transparent shadow-none hover:shadow-testShadow duration-200 relative flex flex-col gap-4 border-gray-200 py-6 z-5 px-4">
<div className="w-full h-auto flex items-center justify-center">
<img
className="w-52 h-64 object-contain"
src={item.image}
alt={item.title}
/>
<span className="text-xs capitalize italic absolute top-2 right-2 text-gray-500">{item.category}</span>
</div>
<div className="flex justify-between text-sm">
<h3 className=" font-titleFont font-medium">{item.title.substring(0,25)}</h3>
<p className="text-gray-600 font-semibold">${item.price}</p>
</div>
<div>
<p className="text-sm">
{item.description.substring(0,100)}...
</p>
<span className=" text-orange-600 flex justify-end">
<FaStar />
<FaStar />
<FaStar />
<FaStar />
<FaStar />
</span>
<span className="flex justify-between mt-2">
<button className="bg-green text-white hover:bg-sky_blue hover:text-black py-2 px-3 rounded-md">Add to Cart</button>
<button className="bg-green text-white hover:bg-sky_blue hover:text-black py-2 px-3 rounded-md">View Details</button>
</span>
</div>
</div>
))}
</div>
);
};
export default Products;

View File

@ -0,0 +1,21 @@
import React from "react";
import { FaChevronRight } from "react-icons/fa6";
export const SideNavContent = (props) => {
const { title, items } = props;
console.log(items);
return (
<div className="py-3 border-b-[1px] border-gray-300">
<h3 className="text-lg font-titleFont font-semibold mb-1 px-6">
{title}
</h3>
<ul className="text-sm">
{items.map((item, idx) => (
<li key={idx} className="flex items-center justify-between hover:bg-zinc-200 px-6 py-1 cursor-pointer">
{item.title} <FaChevronRight />
</li>
))}
</ul>
</div>
);
};

153
src/components/TopNav.jsx Normal file
View File

@ -0,0 +1,153 @@
import { Link } from "react-router-dom";
import logo from "../assets/logo.png";
import { motion } from "framer-motion"
import {
FaBars,
FaCartArrowDown,
FaLocationDot,
FaMagnifyingGlass,
FaSortDown,
FaX,
} from "react-icons/fa6";
import { useRef, useState } from "react";
import { TopNavBottom } from "./TopNavBottom";
import Logo from "./Logo";
export default function TopNav() {
const [showAll, setShowAll] = useState(false);
const [SideNav, setSideNav] = useState(false);
const sideNav = useRef()
const listItems = [
{
_id: "1",
title: "All",
},
{
_id: "2",
title: "Camping",
},
{
_id: "3",
title: "Fishing",
},
{
_id: "4",
title: "Prepping",
},
];
return (
<div className="w-full bg-darkBrown sticky top-0 z-10">
<div className="w-full max-w-container mx-auto text-white flex items-center justify-between h-24 px-4 py-3 gap-4">
<div className="px-2 flex items-center ">
<Logo />
</div>
<div className="headerHover hidden mdl:inline-flex">
<FaLocationDot />
<p className="text-sm text-lightText font-light flex flex-col">
Deliver to
<span className="font-semibold -mt-1 text-white">Jeremy</span>
</p>
</div>
<div className="h-10 hidden rounded-md mdl:flex flex-grow relative">
<span
onClick={() => setShowAll(!showAll)}
className="w-14 h-full bg-gray-200 hover:bg-gray-300 border-2 cursor-pointer text-gray-800 duration-300 text-sm font-titleFont flex items-center justify-center rounded-tl-md rounded-bl-md"
>
<span>All</span>
<span>
<FaSortDown />
</span>
</span>
{showAll && (
<span>
<ul className=" absolute w-56 h-80 top-10 left-0 overflow-y-scroll overflow-x-hidden bg-white border-[1px] border-gray-800 text-black p-2 flex-col gap-1 z-50">
{listItems.map((item) => {
<li
key={item._id}
className="tracjing-wide font-titleFont border-b-[1px] border-transparent hover:border-gray-800 duration-200 cursor-pointer"
>
{item.title}
</li>;
})}
</ul>
</span>
)}
<input
className="h-full text-base flex-grow outline-none border-none px-2"
type="text"
/>
<span className="w-12 h-full flex items-center justify-center bg-green hover:bg-sky_blue rounded-tr-md rounded-br-md">
<FaMagnifyingGlass />
</span>
</div>
<div className="flex flex-col items-start justify-center headerHover">
<p className="text-sm mdl:text-xs text-white mdl:text-gray-200 text-lightText font-light">
Hello, sign in
</p>
<p className="text-sm font-semibold -mt-1 text-white hidden mdl:inline-flex">
Accounts & list{" "}
<span>
<FaSortDown />
</span>
</p>
</div>
<div className="hidden mdl:inline-flex flex-col items-start justify-center headerHover">
<p className=" text-sm mdl:text-xs text-white mdl:text-gray-200 font-light">
Returns
</p>
<p className="text-sm font-semibold -mt-1 text-white">& Orders</p>
</div>
<div className="flex gap-2">
<div>
<Link
to={"/cart"}
className="flex flex-col items-start justify-center headerHover relative"
>
<FaCartArrowDown />
<p className="text-sm font-semibold -mt-1 text-white">
Cart
<span className="absolute text-xs top-0 left-6 font-semibold p-1 h-4 bg-sky_blue text-black rounded-full flex justify-center items-center">
0
</span>
</p>
</Link>
</div>
<div
onClick={() => setSideNav(true)}
className="headerHover flex items-center gap-1"
>
<FaBars />
</div>
</div>
</div>
<TopNavBottom />
{SideNav && (
<div className="w-full h-screen text-black dark:text-white fixed top-0 left-0 bg-darkBrown bg-opacity-50">
<div className="w-full h-full relative">
<motion.div
ref={sideNav}
initial={{ x: -500, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.5 }}
className="w-full md:w-[350px] h-full bg-gray-100 border border-black dark:bg-gray-900 dark:border-gray-600"
>
<div className="w-full bg-darkBrown text-white py-2 px-6 flex items-center gap-4">
<h3 className="w-full font-titleFont font-bold text-lg tracking-wide">
Hello, please sign in
</h3>
<span
onClick={() => setSideNav(false)}
className="cursor-pointer self-end py-2 px-4 border border-white rounded-sm"
>
<FaX />
</span>
</div>
</motion.div>
</div>
</div>
)}
</div>
);
}

View File

@ -0,0 +1,86 @@
import React, { useEffect, useRef, useState } from "react";
import { FaBars, FaChevronRight, FaUser, FaX } from "react-icons/fa6";
import { SideNavContent } from "./SideNavContent";
import { motion } from "framer-motion"
export const TopNavBottom = () => {
const sideNav = useRef()
const [SideNav, setSideNav] = useState(false);
useEffect(() => {
document.body.addEventListener("click", (e)=>{
if(e.target.contains(sideNav.current)){
setSideNav(false)
}
})
}, [sideNav, SideNav])
return (
<div className="w-full px-4 h-[36px] bg-brown text-white flex items-center">
<ul className="mdl:max-w-container mdl:mx-auto flex items-start mdl:items-center gap-2 text-sm tracking-wide">
<li
onClick={() => setSideNav(true)}
className="headerHover flex items-center gap-1"
>
<FaBars /> All
</li>
<li className="headerHover hidden mdl:inline-flex">Today's Deals</li>
<li className="headerHover hidden mdl:inline-flex">Customer Service</li>
<li className="headerHover hidden mdl:inline-flex">Gift Cards</li>
<li className="headerHover hidden mdl:inline-flex">Registry</li>
</ul>
{SideNav && (
<div className="w-full h-screen text-black dark:text-white fixed top-0 left-0 bg-darkBrown bg-opacity-50">
<div className="w-full h-full relative">
<motion.div ref={sideNav} initial={{x:-500, opacity: 0}} animate={{x:0, opacity:1}} transition={{duration:0.5}} className="w-full md:w-[350px] h-full bg-gray-100 border border-black dark:bg-gray-900 dark:border-gray-600">
<div className="w-full bg-darkBrown text-white py-2 px-6 flex items-center gap-4">
<FaUser />
<h3 className="w-full font-titleFont font-bold text-lg tracking-wide">
Hello, please sign in
</h3>
<span onClick={()=>setSideNav(false)} className="cursor-pointer self-end py-2 px-4 border border-white rounded-sm">
<FaX />
</span>
</div>
<SideNavContent
title="Camping Supplies"
items={[
{ title: "Tents" },
{ title: "Cordage" },
{ title: "Hatchets" },
{ title: "Stoves" },
]}
/>
<SideNavContent
title="Prepping"
items={[
{ title: "Food" },
{ title: "Bugout" },
{ title: "Radio equipment" },
{ title: "Geiger counters" },
{ title: "Books" },
]}
/>
<SideNavContent
title="Fishing"
items={[
{ title: "Baits" },
{ title: "Line" },
{ title: "Nets" },
{ title: "Rods and reels" },
]}
/>
<SideNavContent
title="Hunting"
items={[
{ title: "Clothing" },
{ title: "Cordage" },
{ title: "Hatchets" },
{ title: "Stoves" },
]}
/>
</motion.div>
</div>
</div>
)}
</div>
);
};

View File

@ -0,0 +1,16 @@
import React from 'react'
import FooterBottom from './FooterBottom'
import FooterMiddle from './FooterMiddle'
import FooterTop from './FooterTop'
const Footer = () => {
return (
<div className='font-titleFont'>
<FooterTop />
<FooterMiddle />
<FooterBottom />
</div>
)
}
export default Footer

View File

@ -0,0 +1,14 @@
import React from "react";
import Logo from "../Logo";
const FooterBottom = () => {
return (
<div className="w-full flex gap-6 bg-darkBrown border-t-[1px] border-gray-600 items-center justify-center py-6">
<div className="flex items-center">
<Logo />
</div>
</div>
);
};
export default FooterBottom;

View File

@ -0,0 +1,53 @@
import React from "react";
import FooterMiddleList from "./FooterMiddleList";
const FooterMiddle = () => {
const listItems = [
{
title: "Who is TrailBlazer Supply?",
id:"01",
items: [
{ title: "About", id:"001", link: "about" },
{ title: "Testimonials", id:"002", link: "testimonials" },
{ title: "How to become a Christian", id:"003", link: "littleChrist" },
],
},
{
title: "Support",
id:"02",
items: [
{ title: "Contact Support", id:"001", link: "support" },
{ title: "Chat", id:"002", link: "chat" },
{ title: "FAQs", id:"003", link: "faqs" },
],
},
{
title: "Payment Products",
id:"03",
items: [
{ title: "Gift Cards", id:"001", link: "giftCards" },
{ title: "Points", id:"002", link: "points" },
{ title: "Store Card coming soon", id:"003", link: "storeCard" },
],
},
{
title: "Other",
id:"04",
items: [
{ title: "Your Orders", id:"001", link: "orders" },
{ title: "Shipping Rates", id:"002", link: "shipping" },
{ title: "Privacy Policy", id:"003", link: "privacypolicy" },
{ title: "Terms and Condtions", id:"004", link: "Terms" }
],
},
];
return (
<div className="w-full bg-darkBrown text-white">
<div className="max-w-5xl mx-auto text-gray-300 py-5">
<FooterMiddleList items={listItems} />
</div>
</div>
);
};
export default FooterMiddle;

View File

@ -0,0 +1,25 @@
import React from "react";
import { Link } from "react-router-dom";
const FooterMiddleList = ({ items }) => {
return (
<div className="w-full grid grid-cols-4">
{items.map((item, idx) => (
<div key={item.id}>
<h3 className="text-white text-base font-semibold mb-2">
{item.title}
</h3>
<ul className="text-sm flex flex-col gap-2 font-bodyFont">
{item.items.map((it, i) => (
<li key={item.id + it.id + i} className="footerLink">
<Link to={it.link}>{it.title}</Link>
</li>
))}
</ul>
</div>
))}
</div>
);
};
export default FooterMiddleList;

View File

@ -0,0 +1,18 @@
import React from "react";
import { Link } from "react-router-dom";
const FooterTop = () => {
return (
<div className="w-full bg-white py-6">
<div className="w-full border-t-[1px] py-8">
<div className="w-64 mx-auto text-center flex flex-col gap-1">
<p className="text-sm">Recomendations</p>
<Link to={'signin'} className="w-full bg-green rounded-md font-semibold cursor-pointer hover:bg-sky_blue py-1 text-white">Sign in</Link>
<p className="text-sm mt-1">Not registered? <Link to={'/register'} className=" text-green hover:text-sky_blue hover:underline ml-1 cursor-pointer">Sign up here</Link></p>
</div>
</div>
</div>
);
};
export default FooterTop;

13
src/index.css Normal file
View File

@ -0,0 +1,13 @@
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700;800&family=Work+Sans:wght@100;200;300;400;500&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components{
.headerHover{
@apply px-2 h-[80%] flex items-center rounded-sm border-transparent hover:border-gray-100 border-2 cursor-pointer duration-100;
}
.footerLink{
@apply px-2 h-[80%] flex items-center rounded-sm border-transparent hover:border-gray-100 border-b-[1px] cursor-pointer duration-100;
}
}

12
src/main.jsx Normal file
View File

@ -0,0 +1,12 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import "slick-carousel/slick/slick.css";
import App from './App.jsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)

7
src/pages/Cart/Cart.jsx Normal file
View File

@ -0,0 +1,7 @@
export default function Cart(){
return (
<div>
Cart
</div>
)
}

View File

@ -0,0 +1,15 @@
import React from 'react'
const NoPage = () => {
return (
<div className='w-full flex items-center h-screen justify-center bg-zinc-200'>
<div className=' max-w-[400px] w-full bg-white p-6'>
<h1 className='w-full flex justify-center text-5xl text-red-800'>404</h1>
<p className='w-full flex justify-center'>Nothing to see here!</p>
</div>
</div>
)
}
export default NoPage

View File

@ -0,0 +1,102 @@
import React from "react";
import logo from "../../assets/logo.png";
import Logo from "../../components/Logo";
const Register = () => {
return (
<div className="w-full">
<div className="w-[400px] mx-auto bg-gray-100 pb-2 my-9 border border-zinc-500">
<form>
<div className="w-full p-3 flex justify-center text-white text-lg bg-darkBrown">
<Logo />
</div>
<div>
<h3 className="w-full text-lg py-2 font-titleFont italic text-center">
Register
</h3>
</div>
<div className="flex py-2">
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="first">
First Name
</label>
<input
name="first"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input lowercase duration-100"
type="text"
/>
</div>
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="last">
Last Name
</label>
<input
name="last"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input lowercase duration-100"
type="text"
/>
</div>
</div>
<div className="flex py-2">
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="email">
Email Address
</label>
<input
name="email"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input lowercase duration-100"
type="email"
/>
</div>
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="re-email">
Reenter Email Address
</label>
<input
name="re-email"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input lowercase duration-100"
type="email"
/>
</div>
</div>
<div className="flex py-2">
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="password">
Enter Password
</label>
<input
name="password"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input duration-100"
type="password"
/>
</div>
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="re-password">
Reenter Password
</label>
<input
name="re-password"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input duration-100"
type="password"
/>
</div>
</div>
<div className="flex justify-end p-2">
<button className="px-2 py-1 bg-green text-white hover:text-black rounded-md hover:bg-sky_blue">
Register
</button>
</div>
</form>
</div>
</div>
);
};
export default Register;

13
src/pages/Shop/Shop.jsx Normal file
View File

@ -0,0 +1,13 @@
import Banner from "../../components/Banner";
import Products from "../../components/Products";
export default function Shop() {
return (
<div>
<Banner />
<div className=" bg-gray-100 pt-6">
<Products />
</div>
</div>
);
}

View File

@ -0,0 +1,56 @@
import React from "react";
import { Link } from "react-router-dom";
import logo from "../../assets/logo.png";
import Logo from "../../components/Logo";
const Signin = () => {
return (
<div className="w-full">
<div className="w-[300px] mx-auto bg-gray-100 pb-2 my-9 border border-zinc-500">
<form>
<div className="w-full p-3 flex justify-center text-white text-lg bg-darkBrown">
<Logo />
</div>
<div>
<h3 className="w-full text-lg py-2 font-titleFont italic text-center">
Sign in
</h3>
</div>
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="email">
Email Address
</label>
<input
name="email"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input lowercase duration-100"
type="email"
/>
</div>
<div className="px-2 flex flex-col gap-2">
<label className="text-sm" htmlFor="password">
Password
</label>
<input
name="password"
required
className="w-full py-1 px-2 border border-zinc-400 text-base rounded-sm outline-none focus-within:border-green focus-within:shadow-input duration-100"
type="password"
/>
</div>
<span className="px-2 w-full flex justify-end text-sm">
New customer?
<Link className="text-green hover:text-sky_blue hover:underline cursor-pointer" to={"/register"}>Register</Link>
</span>
<div className="flex justify-end p-2">
<button className="px-2 py-1 bg-green text-white hover:text-black rounded-md hover:bg-sky_blue">
Sign in
</button>
</div>
</form>
</div>
</div>
);
};
export default Signin;

38
tailwind.config.js Normal file
View File

@ -0,0 +1,38 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
maxWidth: {
container: "1440px",
},
screens: {
xs: "320px",
sm: "375px",
sml: "500px",
md: "667px",
mdl: "768px",
lg: "960px",
lgl: "1024px",
xl: "1280px",
},
fontFamily: {
titleFont: "Rubik",
bodyFont: "Work Sans",
},
colors: {
darkBrown: "#483C32",
olive: "#808000",
brown: "#5C4033",
green: "#228B22",
sky_blue: "#87CEEB",
},
boxShadow: {
testShadow: "0px 0px 32px 1px rgba(199,199,199,1)",
input: "0 0 3px 2px #228B22",
},
},
},
plugins: [],
darkMode: "class",
};

7
vite.config.js Normal file
View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})