|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 33 KiB |
@ -1,38 +1,3 @@ |
|||||||
.App { |
* { |
||||||
text-align: center; |
margin: 0; |
||||||
} |
|
||||||
|
|
||||||
.App-logo { |
|
||||||
height: 40vmin; |
|
||||||
pointer-events: none; |
|
||||||
} |
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) { |
|
||||||
.App-logo { |
|
||||||
animation: App-logo-spin infinite 20s linear; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.App-header { |
|
||||||
background-color: #282c34; |
|
||||||
min-height: 100vh; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
justify-content: center; |
|
||||||
font-size: calc(10px + 2vmin); |
|
||||||
color: white; |
|
||||||
} |
|
||||||
|
|
||||||
.App-link { |
|
||||||
color: #61dafb; |
|
||||||
} |
|
||||||
|
|
||||||
@keyframes App-logo-spin { |
|
||||||
from { |
|
||||||
transform: rotate(0deg); |
|
||||||
} |
|
||||||
to { |
|
||||||
transform: rotate(360deg); |
|
||||||
} |
|
||||||
} |
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
.checkout { |
||||||
|
display: flex; |
||||||
|
padding: 20px; |
||||||
|
background-color: white; |
||||||
|
height: max-content; |
||||||
|
} |
||||||
|
|
||||||
|
.checkout__title { |
||||||
|
margin-right: 10px; |
||||||
|
padding: 10px; |
||||||
|
border-bottom: 1px solid lightgray; |
||||||
|
} |
||||||
|
|
||||||
|
.checkout__ad { |
||||||
|
width: 100%; |
||||||
|
margin-bottom: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkout__empty { |
||||||
|
direction: rtl; |
||||||
|
margin: 10px; |
||||||
|
} |
||||||
@ -0,0 +1,48 @@ |
|||||||
|
import React from 'react' |
||||||
|
import { useStateValue } from './StateProvider' |
||||||
|
import './Checkout.css' |
||||||
|
import CheckoutProduct from "./CheckoutProduct" |
||||||
|
import Subtotal from './Subtotal'; |
||||||
|
|
||||||
|
function Checkout() { |
||||||
|
const [{basket}] = useStateValue(); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="checkout"> |
||||||
|
{basket.length > 0 && ( |
||||||
|
<div className="checkout__left"> |
||||||
|
<Subtotal /> |
||||||
|
</div> |
||||||
|
)} |
||||||
|
<div className="checkout__right"> |
||||||
|
<img
|
||||||
|
className="checkout__ad" |
||||||
|
src="./img/ad123.jpg" |
||||||
|
alt="" |
||||||
|
/> |
||||||
|
{basket.length === 0 ? ( |
||||||
|
<div> |
||||||
|
<h2 className="checkout__empty"> عــربــة التســـوق فارغة ({basket.length})</h2> |
||||||
|
<p className="checkout__empty">عربة التسوق فارغة. |
||||||
|
أضف سلع لعربة التسوق واستعرضهم قبل عملية الشراء. تكملة الشراء!</p> |
||||||
|
</div> |
||||||
|
) : ( |
||||||
|
<div> |
||||||
|
<h2 className="checkout__empty">عــربــة التســـوق ({basket.length})</h2> |
||||||
|
{basket.map(item => ( |
||||||
|
<CheckoutProduct
|
||||||
|
id={item.id} |
||||||
|
title={item.title} |
||||||
|
image={item.image} |
||||||
|
price={item.price} |
||||||
|
rating={item.rating} |
||||||
|
/> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Checkout |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
.checkoutProduct { |
||||||
|
display: flex; |
||||||
|
direction: rtl; |
||||||
|
margin-top: 20px; |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkoutProduct__image { |
||||||
|
object-fit: contain; |
||||||
|
width: 180px; |
||||||
|
height: 180px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkoutProduct__info { |
||||||
|
padding-right: 20px; |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
.checkoutProduct__info > button { |
||||||
|
background-color: #f0c14b; |
||||||
|
border: 1px solid; |
||||||
|
border-color: #a88734 #9c7e31 #846a29; |
||||||
|
color: #111; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkoutProduct__rating { |
||||||
|
display: flex; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.checkoutProduct__title { |
||||||
|
font-size: 17px; |
||||||
|
font-weight: 800; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
import React from 'react' |
||||||
|
import './CheckoutProduct.css' |
||||||
|
import { useStateValue } from "./StateProvider" |
||||||
|
|
||||||
|
function CheckoutProduct({ id, title, image, price, rating }) { |
||||||
|
|
||||||
|
const [{basket}, dispatch] = useStateValue(); |
||||||
|
|
||||||
|
const removeFromBasket = () => { |
||||||
|
|
||||||
|
dispatch({ |
||||||
|
type: "REMOVE_FROM_BASKET", |
||||||
|
id: id, |
||||||
|
}) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="checkoutProduct"> |
||||||
|
<img className="checkoutProduct__image" src={image} alt="" /> |
||||||
|
<div className="checkoutProduct__info"> |
||||||
|
<p className="checkoutProduct__title">{title}</p> |
||||||
|
<p className="checkoutProduct__price"> |
||||||
|
<strong>{price}</strong> |
||||||
|
<small> جنيه</small> |
||||||
|
</p> |
||||||
|
<div className="checkoutProduct__rating"> |
||||||
|
{Array(rating) |
||||||
|
.fill() |
||||||
|
.map((_) => ( |
||||||
|
<p>⭐</p> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
<button onClick={removeFromBasket}>مسح من السلة</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default CheckoutProduct |
||||||
@ -0,0 +1,71 @@ |
|||||||
|
.header { |
||||||
|
background-color: #131921; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
position: sticky; |
||||||
|
top: 0; |
||||||
|
z-index: 100; |
||||||
|
} |
||||||
|
|
||||||
|
.header__logo { |
||||||
|
width: 100px; |
||||||
|
object-fit: contain; |
||||||
|
margin-left: 20px; |
||||||
|
margin-right: 20px; |
||||||
|
margin-top: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.header__optionBasket { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.header__optionBasketCount { |
||||||
|
margin-left: 10px; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.header__nav { |
||||||
|
display: flex; |
||||||
|
justify-content: space-evenly; |
||||||
|
} |
||||||
|
|
||||||
|
.header__option { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
margin-left: 10px; |
||||||
|
margin-right: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.header__optionLineOne { |
||||||
|
font-size: 10px; |
||||||
|
} |
||||||
|
|
||||||
|
.header__optionLineTwo { |
||||||
|
font-size: 13px; |
||||||
|
font-weight: 800; |
||||||
|
} |
||||||
|
|
||||||
|
.header__link { |
||||||
|
color: white; |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
.header__search { |
||||||
|
display: flex; |
||||||
|
flex: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.header__searchInput { |
||||||
|
height: 12px; |
||||||
|
padding: 10px; |
||||||
|
border: none; |
||||||
|
width: 100%; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
.header__searchIcon { |
||||||
|
padding: 5px; |
||||||
|
height: 22px !important; |
||||||
|
background-color: #cd9042; |
||||||
|
} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
import React from 'react' |
||||||
|
import "./Header.css" |
||||||
|
import { Link } from "react-router-dom"; |
||||||
|
import SearchIcon from '@material-ui/icons/Search'; |
||||||
|
import ShoppingBasketIcon from '@material-ui/icons/ShoppingBasket'; |
||||||
|
import { useStateValue } from "./StateProvider"; |
||||||
|
import { auth } from "firebase"; |
||||||
|
|
||||||
|
|
||||||
|
function Header() { |
||||||
|
const [{ basket, user }] = useStateValue(); |
||||||
|
|
||||||
|
const login = () => { |
||||||
|
if(user){ |
||||||
|
auth().signOut(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<nav className="header"> |
||||||
|
<Link to="/"> |
||||||
|
<img className="header__logo" src="./img/amazon_logo.png" alt="amazon_logo"/> |
||||||
|
</Link> |
||||||
|
|
||||||
|
<div className="header__search"> |
||||||
|
<input type="text" className="header__searchInput"/> |
||||||
|
<SearchIcon className="header__searchIcon"/> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div className="header__nav"> |
||||||
|
<Link to={!user && "/login"} className="header__link"> |
||||||
|
<div onClick={login} className="header__option"> |
||||||
|
<span className="header__optionLineOne">Hello {user?.email}</span> |
||||||
|
<span className="header__optionLineTwo">{user ? 'Sign Out' : 'Sign In'}</span> |
||||||
|
</div> |
||||||
|
</Link> |
||||||
|
|
||||||
|
<Link to="/" className="header__link"> |
||||||
|
<div className="header__option"> |
||||||
|
<span className="header__optionLineOne">Returns</span> |
||||||
|
<span className="header__optionLineTwo">& Orders</span> |
||||||
|
</div> |
||||||
|
</Link> |
||||||
|
|
||||||
|
<Link to="/" className="header__link"> |
||||||
|
<div className="header__option"> |
||||||
|
<span className="header__optionLineOne">Your</span> |
||||||
|
<span className="header__optionLineTwo">Prime</span> |
||||||
|
</div> |
||||||
|
</Link> |
||||||
|
|
||||||
|
<Link to="/checkout" className="header__link"> |
||||||
|
<div className="header__optionBasket"> |
||||||
|
<ShoppingBasketIcon /> |
||||||
|
<span className="header__optionLineTwo header__optionBasketCount">{basket.length}</span> |
||||||
|
</div> |
||||||
|
</Link> |
||||||
|
|
||||||
|
</div> |
||||||
|
|
||||||
|
|
||||||
|
</nav> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Header |
||||||
@ -0,0 +1,24 @@ |
|||||||
|
.home { |
||||||
|
max-width: 1200px; |
||||||
|
margin-left: auto; |
||||||
|
margin-right: auto; |
||||||
|
} |
||||||
|
|
||||||
|
.home__row { |
||||||
|
display: flex; |
||||||
|
z-index: 1; |
||||||
|
margin-left: 5px; |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.home__image { |
||||||
|
width: 100%; |
||||||
|
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); |
||||||
|
z-index: -1; |
||||||
|
margin-bottom: -150px; |
||||||
|
} |
||||||
|
|
||||||
|
.home__strip { |
||||||
|
width: 100%; |
||||||
|
margin-top: 3px; |
||||||
|
} |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
import React from 'react' |
||||||
|
import './Home.css' |
||||||
|
import Product from "./Product" |
||||||
|
|
||||||
|
function Home() { |
||||||
|
return ( |
||||||
|
<div className="home"> |
||||||
|
<img className="home__image" src="./img/banner1.jpg" alt="banner" /> |
||||||
|
<div className="home__row"> |
||||||
|
<Product
|
||||||
|
id={111}
|
||||||
|
title="ريسيفر ميني اتش دي من سكاي لاين 222i - اسود" |
||||||
|
price={215.00} |
||||||
|
rating={5} |
||||||
|
image="./img/rec.jpg" |
||||||
|
/> |
||||||
|
<Product
|
||||||
|
id={112}
|
||||||
|
title="نظارة 3D ثلاثية الابعاد المحاكية للواقع الإفتراضي متوافق مع كل الهواتف الذكيــة" |
||||||
|
price={137.07} |
||||||
|
rating={5} |
||||||
|
image="./img/vr.jpg" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<img className="home__strip" src="./img/strip.jpg" alt="banner" /> |
||||||
|
<div className="home__row"> |
||||||
|
<Product
|
||||||
|
id={113}
|
||||||
|
title="جيني كوليكشن 5573 للنساء 25 مل" |
||||||
|
price={150.00} |
||||||
|
rating={5} |
||||||
|
image="./img/gc1.jpg" |
||||||
|
/> |
||||||
|
<Product
|
||||||
|
id={114}
|
||||||
|
title="جيني كوليكشين 5571 لل رجال 25 مل - او دى بارفان" |
||||||
|
price={115.00} |
||||||
|
rating={5} |
||||||
|
image="./img/gc2.jpg" |
||||||
|
/> |
||||||
|
<Product
|
||||||
|
id={115}
|
||||||
|
title="جيني كوليكشين 8813 لل نساء 25 مل - او دى بارفان" |
||||||
|
price={195.00} |
||||||
|
rating={5} |
||||||
|
image="./img/gc3.jpg" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<div className="home__row"> |
||||||
|
<Product
|
||||||
|
id={116}
|
||||||
|
title="تكييف يونيون اير سبليت بارد وساخن ART1030HR-F – اسود، 4 حصان" |
||||||
|
price={13280.00} |
||||||
|
rating={5} |
||||||
|
image="./img/ac.jpg" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Home |
||||||
@ -0,0 +1,69 @@ |
|||||||
|
.login { |
||||||
|
background-color: white; |
||||||
|
height: 100vh; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
.login__container { |
||||||
|
width: 300px; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
padding: 20px; |
||||||
|
border: 1px solid lightgray; |
||||||
|
} |
||||||
|
|
||||||
|
.login__container > h1 { |
||||||
|
font-weight: 500; |
||||||
|
margin-bottom: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.login__container > p { |
||||||
|
margin-bottom: 15px; |
||||||
|
font-size: 12px; |
||||||
|
} |
||||||
|
|
||||||
|
.login__container > form > h5 { |
||||||
|
margin-bottom: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.login__container > form > input { |
||||||
|
height: 30px; |
||||||
|
margin-bottom: 10px; |
||||||
|
background-color: white; |
||||||
|
width: 98%; |
||||||
|
} |
||||||
|
|
||||||
|
.login__logo { |
||||||
|
margin-top: 20px; |
||||||
|
margin-bottom: 20px; |
||||||
|
width: 100px; |
||||||
|
object-fit: contain; |
||||||
|
} |
||||||
|
|
||||||
|
.login__signInButton { |
||||||
|
background: #f0c14b; |
||||||
|
border-radius: 2px; |
||||||
|
width: 100%; |
||||||
|
height: 30px; |
||||||
|
border: 1px solid; |
||||||
|
margin-top: 10px; |
||||||
|
border-color: #a88734 #9c7e31 #846a29; |
||||||
|
} |
||||||
|
|
||||||
|
.login__registerButton { |
||||||
|
border-radius: 2px; |
||||||
|
width: 100%; |
||||||
|
height: 30px; |
||||||
|
border: 1px solid; |
||||||
|
border-color: darkgray; |
||||||
|
} |
||||||
|
|
||||||
|
.login__newUser { |
||||||
|
margin-top: 20px; |
||||||
|
margin-bottom: 5px; |
||||||
|
text-align: center; |
||||||
|
font-size: 15px; |
||||||
|
} |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
import React, { useState } from 'react' |
||||||
|
import "./Login.css" |
||||||
|
import { Link, useHistory } from "react-router-dom" |
||||||
|
import { auth } from "./firebase" |
||||||
|
|
||||||
|
function Login() { |
||||||
|
const history = useHistory(); |
||||||
|
const [email, setEmail] = useState(""); |
||||||
|
const [password, setPassword] = useState(""); |
||||||
|
|
||||||
|
const login = event => { |
||||||
|
event.preventDefault(); |
||||||
|
auth.signInWithEmailAndPassword(email,password) |
||||||
|
.then((auth) => { |
||||||
|
history.push('/'); |
||||||
|
}) |
||||||
|
.catch((e) => alert(e.message)); |
||||||
|
} |
||||||
|
|
||||||
|
const register = event => { |
||||||
|
event.preventDefault(); |
||||||
|
auth.createUserWithEmailAndPassword(email,password) |
||||||
|
.then((auth) => { |
||||||
|
history.push('/'); |
||||||
|
}) |
||||||
|
.catch((e) => alert(e.message)); |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="login"> |
||||||
|
<Link to="/"> |
||||||
|
<img |
||||||
|
className="login__logo" |
||||||
|
src="./img/souqAmazon-logo-v2.png" |
||||||
|
alt=""
|
||||||
|
/> |
||||||
|
</Link> |
||||||
|
<div className="login__container"> |
||||||
|
<h1>تسجيل الدخول</h1> |
||||||
|
<p>يمكنك الدخول إلى موقع سوق وأمازون باستخدام بيانات الدخول ذاتها!</p> |
||||||
|
<p>قم بتسجيل الدخول باستخدام حسابك في سوق أو حسابك في أمازون</p> |
||||||
|
<form> |
||||||
|
<h5>البريد الالكتروني</h5> |
||||||
|
<input value={email} onChange={event => setEmail(event.target.value)} type="email"/> |
||||||
|
<h5>كلمة السر</h5> |
||||||
|
<input value={password} onChange={event => setPassword(event.target.value)} type="password"/> |
||||||
|
<button onClick={login} type="submit" className="login__signInButton">تسجيل الدخول</button> |
||||||
|
</form> |
||||||
|
<h6 className="login__newUser"> مستخدم جديد؟ </h6> |
||||||
|
<button onClick={register} className="login__registerButton">انشئ حسابك</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Login |
||||||
@ -0,0 +1,45 @@ |
|||||||
|
.product { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
align-items: center; |
||||||
|
justify-content: flex-end; |
||||||
|
max-height: 400px; |
||||||
|
min-width: 100px; |
||||||
|
margin: 10px; |
||||||
|
padding: 20px; |
||||||
|
width: 100%; |
||||||
|
background-color: white; |
||||||
|
z-index: 1; |
||||||
|
} |
||||||
|
|
||||||
|
.product__info { |
||||||
|
height: 100px; |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.product__price { |
||||||
|
margin-top: 5px; |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
.product__rating { |
||||||
|
display: flex; |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
.product > img { |
||||||
|
max-height: 200px; |
||||||
|
width: 100%; |
||||||
|
object-fit: contain; |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
|
||||||
|
.product > button { |
||||||
|
background-color: #f0c14b; |
||||||
|
border: 1px solid; |
||||||
|
border-color: #a88734 #9c7e31 #846a29; |
||||||
|
} |
||||||
|
|
||||||
|
.product__title { |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
import React from 'react' |
||||||
|
import "./Product.css" |
||||||
|
import { useStateValue } from './StateProvider' |
||||||
|
|
||||||
|
function Product({ id, title, image, price, rating}) { |
||||||
|
const [{basket}, dispatch] = useStateValue(); |
||||||
|
const addToBasket = () => { |
||||||
|
dispatch({ |
||||||
|
type: 'ADD_TO_BASKET', |
||||||
|
item: { |
||||||
|
id: id, |
||||||
|
title: title, |
||||||
|
image: image, |
||||||
|
price: price, |
||||||
|
rating: rating, |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div className="product"> |
||||||
|
<div className="product__info"> |
||||||
|
<p className="product__title">{title}</p> |
||||||
|
<p className="product__price"> |
||||||
|
<strong>{price}</strong> |
||||||
|
<small> جنيه</small> |
||||||
|
</p> |
||||||
|
<div className="product__rating"> |
||||||
|
{Array(rating) |
||||||
|
.fill() |
||||||
|
.map((_) => ( |
||||||
|
<p>⭐</p> |
||||||
|
))} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<img src={image} /> |
||||||
|
<button onClick={addToBasket}>أضف الي السلة</button> |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Product |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
import React, { createContext, useContext, useReducer } from "react"; |
||||||
|
export const StateContext = createContext(); |
||||||
|
export const StateProvider = ({ reducer, initialState, children }) => ( |
||||||
|
<StateContext.Provider value={useReducer(reducer, initialState)}> |
||||||
|
{children} |
||||||
|
</StateContext.Provider> |
||||||
|
); |
||||||
|
export const useStateValue = () => useContext(StateContext); |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
.subtotal { |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
justify-content: space-between; |
||||||
|
width: 300px; |
||||||
|
height: 100px; |
||||||
|
padding: 20px; |
||||||
|
background-color: #f3f3f3; |
||||||
|
border: 1px solid #dddddd; |
||||||
|
border-radius: 3px; |
||||||
|
direction: rtl; |
||||||
|
} |
||||||
|
|
||||||
|
.subtotal__gift { |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
} |
||||||
|
|
||||||
|
.subtotal__gift > input { |
||||||
|
margin-right: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
.subtotal > button { |
||||||
|
background: #f0c14b; |
||||||
|
border-radius: 2px; |
||||||
|
width: 100%; |
||||||
|
height: 30px; |
||||||
|
border: 1px solid; |
||||||
|
margin-top: 10px; |
||||||
|
border-color: #a88734 #9c7e31 #846a29; |
||||||
|
color: #111; |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
import React from 'react' |
||||||
|
import './Subtotal.css' |
||||||
|
import CurrencyFormat from "react-currency-format" |
||||||
|
import { useStateValue } from "./StateProvider" |
||||||
|
import { getBasketTotal } from "./reducer" |
||||||
|
|
||||||
|
|
||||||
|
function Subtotal() { |
||||||
|
const [{ basket }] = useStateValue(); |
||||||
|
return ( |
||||||
|
<div className="subtotal"> |
||||||
|
<CurrencyFormat |
||||||
|
renderText={(value) => ( |
||||||
|
<> |
||||||
|
<p> |
||||||
|
الأجمالي ({basket.length} قطعة): <strong>{ value } جنيه</strong> |
||||||
|
</p> |
||||||
|
<small> |
||||||
|
<input type="checkbox" /> هل الطلب يحتوي علي كارت هدايا |
||||||
|
</small> |
||||||
|
</> |
||||||
|
)} |
||||||
|
|
||||||
|
decimalScale={2} |
||||||
|
value={getBasketTotal(basket)} |
||||||
|
displayType={"text"} |
||||||
|
thousandSeparator={true} |
||||||
|
/> |
||||||
|
<button>تابع عملية الشراء</button> |
||||||
|
|
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export default Subtotal |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
import firebase from 'firebase' |
||||||
|
|
||||||
|
const firebaseApp = firebase.initializeApp({ |
||||||
|
apiKey: YOUR_API_KEY, |
||||||
|
authDomain: YOUR_AUTH_DOMAIN, |
||||||
|
databaseURL: YOUR_DATABASE_URL, |
||||||
|
projectId: YOUR_PROJECT_ID, |
||||||
|
storageBucket: '', |
||||||
|
messagingSenderId: YOUR_MESSAGING_SENDER_ID, |
||||||
|
appId: YOUR_APP_ID, |
||||||
|
measurementId: YOURS |
||||||
|
}); |
||||||
|
|
||||||
|
const auth = firebase.auth(); |
||||||
|
|
||||||
|
export { auth }; |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
export const initialState = { |
||||||
|
basket: [], |
||||||
|
user: null, |
||||||
|
}; |
||||||
|
|
||||||
|
export const getBasketTotal = (basket) => |
||||||
|
basket.reduce((amount, item) => item.price + amount, 0); |
||||||
|
|
||||||
|
const reducer = (state, action) => { |
||||||
|
switch(action.type) { |
||||||
|
case 'SET_USER': |
||||||
|
return { |
||||||
|
...state, |
||||||
|
user: action.user, |
||||||
|
}; |
||||||
|
case 'ADD_TO_BASKET': |
||||||
|
return { |
||||||
|
...state, |
||||||
|
basket: [...state.basket, action.item] |
||||||
|
}; |
||||||
|
case 'REMOVE_FROM_BASKET': |
||||||
|
let newBasket = [...state.basket]; |
||||||
|
|
||||||
|
const index = state.basket.findIndex((basketItem) => basketItem.id === action.id); |
||||||
|
|
||||||
|
if (index >= 0) { |
||||||
|
newBasket.splice(index, 1); |
||||||
|
}; |
||||||
|
return { ...state, basket: newBasket }; |
||||||
|
default: |
||||||
|
return state; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default reducer; |
||||||