Skip to content

Commit be807f1

Browse files
committed
Added furnimart frontend app made with NextJS
1 parent ce69a4e commit be807f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+8404
-0
lines changed

CollectionCounter/furnimart/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Furnimart

CollectionCounter/furnimart/assets/stylesheets/_mixins.scss

Whitespace-only changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
$amberShade1: #ffb300;
2+
$amberShade2: #ffa000;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Gemunu+Libre:wght@300;400;500;700&display=swap");
2+
@tailwind base;
3+
@tailwind components;
4+
@tailwind utilities;
5+
6+
* {
7+
box-sizing: border-box;
8+
margin: 0;
9+
padding: 0;
10+
}
11+
12+
body {
13+
// background-color: rgb(245, 245, 245);
14+
font-family: "Gemunu Libre", sans-serif;
15+
}
16+
17+
ul {
18+
list-style: none;
19+
20+
li {
21+
display: inline-block;
22+
padding-left: 40px;
23+
}
24+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { FiMapPin, FiPhone, FiShoppingCart, FiUser } from "react-icons/fi";
2+
import { useRecoilState, useRecoilValue } from "recoil";
3+
import { CartItem, ProductCard } from "..";
4+
import {
5+
currentCartState,
6+
numberOfItemsInCart,
7+
totalAmount,
8+
userNameState,
9+
} from "../../lib/recoil-atoms";
10+
11+
export const CartItems = () => {
12+
const [_currentCartState, _setCurrentCartState] =
13+
useRecoilState(currentCartState);
14+
const cartItemNumber = useRecoilValue(numberOfItemsInCart);
15+
const userName = useRecoilValue(userNameState);
16+
const _totalAmount = useRecoilValue(totalAmount);
17+
18+
const removeItemFromCart = (itemToRemoveId) => {
19+
let cartItems = [..._currentCartState];
20+
cartItems.splice(
21+
cartItems.findIndex((item) => item.productId === itemToRemoveId),
22+
1
23+
);
24+
_setCurrentCartState(cartItems);
25+
};
26+
27+
return (
28+
<div className="cart-items flex flex-row justify-around container mx-auto px-40">
29+
<div className="cart-items__details w-9/12 py-8">
30+
<div className="cart-items__title-container text-center flex flex-col justify-center items-center my-4">
31+
<span className="cart-items__icon text-4xl">
32+
<FiShoppingCart />
33+
</span>
34+
{_currentCartState.length > 0 && (
35+
<>
36+
<h2 className="text-4xl font-bold">Confirm Cart</h2>
37+
<p className="text-2xl text-gray-500">{cartItemNumber} Items</p>
38+
</>
39+
)}
40+
</div>
41+
<div className="cart-items__items-list flex flex-wrap">
42+
{_currentCartState.length > 0 ? (
43+
_currentCartState.map((item) => {
44+
return (
45+
<CartItem
46+
productId={item.productId}
47+
image={item.productImage}
48+
title={item.productTitle}
49+
price={item.productPrice}
50+
removeItem={removeItemFromCart}
51+
/>
52+
);
53+
})
54+
) : (
55+
<h2 className="text-3xl text-gray-400 mx-auto mt-4">
56+
There's nothing in your cart !!!
57+
</h2>
58+
)}
59+
</div>
60+
</div>
61+
{/* Shipping Information */}
62+
{_currentCartState.length > 0 && (
63+
<div className="cart-items__overview w-3/12 pl-4 py-8 border-l border-gray-300">
64+
<div className="cart-items__overview-card">
65+
<div className="cart-items__shipping-information rounded-xl bg-gray-100 my-4 px-8 py-6 text-gray-700">
66+
<h2 className="text-lg font-bold text-black">
67+
Shipping Information
68+
</h2>
69+
<div className="cart-items__shipping-name flex my-2">
70+
<FiUser className="text-xl text-green-500" />
71+
<p className="pl-3">{userName}</p>
72+
</div>
73+
<div className="cart-items__shipping-address flex my-2">
74+
<FiMapPin className="text-3xl text-green-500" />
75+
<p className="pl-3">
76+
7348 Scarletwood Ter San Jose, CA 91259 - 1940
77+
</p>
78+
</div>
79+
<div className="cart-items__shipping-contact-number flex my-2">
80+
<FiPhone className="text-xl text-green-500" />
81+
<p className="pl-3">408-027-8153</p>
82+
</div>
83+
</div>
84+
{/* Total */}
85+
<div className="cart-items__receipt my-4 px-4 py-6 text-gray-700 text-lg">
86+
<div className="cart-items__subtotal flex justify-between my-2">
87+
<p>Subtotal</p>
88+
<p className="pl-3">$ {_totalAmount}</p>
89+
</div>
90+
<div className="cart-items__taxes flex justify-between my-2">
91+
<p>Taxes</p>
92+
<p className="pl-3">Free</p>
93+
</div>
94+
<div className="cart-items__total flex justify-between my-2 py-2 text-black font-bold border-t border-gray-300">
95+
<p>Total Price</p>
96+
<p className="pl-3">$ {_totalAmount}</p>
97+
</div>
98+
</div>
99+
{/* Place Order Button */}
100+
{/* <div className="cart-items__button my-4 px-8 py-6"> */}
101+
<button
102+
className="bg-green-500 hover:bg-green-400 px-8 py-4 rounded-lg float-right text-white"
103+
type="button"
104+
>
105+
PLACE YOUR ORDER
106+
</button>
107+
{/* </div> */}
108+
</div>
109+
</div>
110+
)}
111+
</div>
112+
);
113+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { FiX } from "react-icons/fi";
2+
3+
export const CartItem = ({ productId, image, title, price, removeItem }) => {
4+
const removeItemFromCart = () => {
5+
removeItem(productId);
6+
};
7+
return (
8+
<div className="cart-item items-center mx-2 my-3 cursor-pointer">
9+
<div className="cart-item__image group relative w-40 rounded-3xl max-h-52 overflow-hidden">
10+
<div
11+
className="inline-block absolute top-0 right-0 text-2xl bg-white text-red-500
12+
hover:bg-red-500 hover:text-white rounded-bl-xl p-1 transform origin-top-right
13+
group-hover:transform scale-0 group-hover:scale-full transition duration-100"
14+
onClick={removeItemFromCart}
15+
>
16+
<FiX />
17+
</div>
18+
<img className="block w-full h-52" src={image} alt="cart-item" />
19+
</div>
20+
<div className="cart-item__details pl-4 pt-2">
21+
<h2 className="text-xl font-bold">{title}</h2>
22+
<p className="text-md">$ {price}</p>
23+
</div>
24+
</div>
25+
);
26+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { FiHeart } from "react-icons/fi";
2+
3+
export const ProductCard = ({
4+
productId,
5+
productImage,
6+
productTitle,
7+
productPrice,
8+
addItemToCart,
9+
}) => {
10+
const _addItemInCart = () => {
11+
addItemToCart({
12+
productId: productId,
13+
productImage: productImage,
14+
productTitle: productTitle,
15+
productPrice: productPrice,
16+
});
17+
};
18+
19+
return (
20+
<div className="product-card inline-block my-4 transform transition hover:scale-105 ease-out duration-150">
21+
<div className="group max-h-80 h-80 product-card__image cursor-pointer relative w-52 rounded overflow-hidden flex justify-center">
22+
<img className="w-full" src={productImage} alt="product-image" />
23+
<div className="absolute bottom-0 transform origin-bottom scale-y-0 transition ease-out duration-100 group-hover:transform group-hover:scale-y-full flex items-center justify-center bg-white border-b-2 border-green-400 text-center rounded-tl rounded-tr text-xl overflow-hidden">
24+
<span className="p-3 border-r border-gray-200 hover:text-red-400">
25+
<FiHeart />
26+
</span>
27+
<p className="p-3 text-sm hover:bg-gray-200" onClick={_addItemInCart}>
28+
ADD TO CART
29+
</p>
30+
</div>
31+
</div>
32+
<p className="product-card__title text-sm mt-4 text-gray-500">
33+
{productTitle}
34+
</p>
35+
<p className="product-card__price mt-2 text-gray-800 font-bold">
36+
$ {productPrice}
37+
</p>
38+
</div>
39+
);
40+
};
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { useRouter } from "next/router";
2+
import { useState } from "react";
3+
import { FiShoppingCart, FiUser } from "react-icons/fi";
4+
import { IoSearch } from "react-icons/io5";
5+
import { useRecoilValue, useResetRecoilState, useSetRecoilState } from "recoil";
6+
import Link from "next/link";
7+
import {
8+
currentCartState,
9+
currentUserState,
10+
numberOfItemsInCart,
11+
userNameState,
12+
} from "../../lib/recoil-atoms";
13+
14+
export const Header = () => {
15+
const userName = useRecoilValue(userNameState);
16+
const cartItemNumber = useRecoilValue(numberOfItemsInCart);
17+
const [isSettingsVisible, setIsSettingsVisible] = useState(false);
18+
const router = useRouter();
19+
const resetUser = useResetRecoilState(currentUserState);
20+
const resetCart = useResetRecoilState(currentCartState);
21+
22+
const logoutUser = () => {
23+
// Reset user and cart atoms
24+
resetUser();
25+
resetCart();
26+
localStorage.removeItem("currentUser");
27+
router.push("/login");
28+
};
29+
30+
return (
31+
<div className="header bg-gray-100 py-8">
32+
<div className="container mx-auto px-40">
33+
<div className="flex items-center justify-between">
34+
<div className="header__logo">
35+
<Link href="/">
36+
<h1 className="text-3xl font-bold cursor-pointer">
37+
<span className="text-green-500">Furni</span>mart
38+
</h1>
39+
</Link>
40+
</div>
41+
<div className="header__searchbar flex items-center justify-center border rounded-lg bg-white">
42+
<input
43+
type="text"
44+
className="w-96 bg-white mx-1 p-2 outline-none"
45+
name="searchbar"
46+
id="searchbar"
47+
/>
48+
<span className="mx-3 text-xl text-gray-400">
49+
<IoSearch />
50+
</span>
51+
</div>
52+
<ul className="header__navigation text-xl text-gray-700 font-medium cursor-pointer select-none">
53+
<li>
54+
<div className="relative">
55+
{cartItemNumber > 0 && (
56+
<span className="absolute flex items-center justify-center top-0 right-full text-sm font-bold bg-green-500 text-white w-5 h-5 rounded-full">
57+
{cartItemNumber}
58+
</span>
59+
)}
60+
<Link href="/cart">
61+
<FiShoppingCart />
62+
</Link>
63+
</div>
64+
</li>
65+
<li>
66+
<div className="relative">
67+
<FiUser
68+
onClick={(e) => setIsSettingsVisible(!isSettingsVisible)}
69+
/>
70+
<ul
71+
className={`${
72+
isSettingsVisible ? "scale-100" : "scale-0"
73+
} transform origin-top-right overflow-hidden transition duration-75 ease-in z-10 absolute right-0 top-full bg-white rounded shadow-2xl text-center mt-3`}
74+
>
75+
<li className="px-4 w-full py-1">
76+
Hi, <span className="font-bold">{userName}</span>
77+
</li>
78+
<li className="px-4 w-full py-1 hover:bg-gray-300 whitespace-nowrap">
79+
My Orders
80+
</li>
81+
<li className="px-4 w-full py-1 hover:bg-gray-300">
82+
Settings
83+
</li>
84+
<li
85+
className="px-4 w-full py-1 hover:bg-gray-300"
86+
onClick={logoutUser}
87+
>
88+
Logout
89+
</li>
90+
</ul>
91+
</div>
92+
</li>
93+
</ul>
94+
</div>
95+
</div>
96+
</div>
97+
);
98+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Products } from "..";
2+
3+
export const Home = () => {
4+
return (
5+
<div className="home">
6+
<Products />
7+
</div>
8+
);
9+
};

0 commit comments

Comments
 (0)