parent
fb80e688ab
commit
7e551c5a50
21 changed files with 675 additions and 20 deletions
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 309 KiB |
@ -0,0 +1,13 @@ |
|||||||
|
import React from "react"; |
||||||
|
import "./index.scss"; |
||||||
|
|
||||||
|
export default function Radio(props) { |
||||||
|
return ( |
||||||
|
<div className="radio flex items-center"> |
||||||
|
<input id="radio-1" name={props.name} type="radio" /> |
||||||
|
<label htmlFor="radio-1" className="radio-label text-xs"> |
||||||
|
{/* {props.label} */} |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
$color1: #f4f4f4; |
||||||
|
$color2: #3197EE; |
||||||
|
|
||||||
|
.radio { |
||||||
|
input[type="radio"] { |
||||||
|
position: absolute; |
||||||
|
opacity: 0; |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
content: ''; |
||||||
|
background: $color1; |
||||||
|
border-radius: 100%; |
||||||
|
border: 1px solid darken($color1, 25%); |
||||||
|
display: inline-block; |
||||||
|
width: 1.4em; |
||||||
|
height: 1.4em; |
||||||
|
position: relative; |
||||||
|
vertical-align: top; |
||||||
|
margin-left: 0.5em; |
||||||
|
cursor: pointer; |
||||||
|
text-align: center; |
||||||
|
transition: all 250ms ease; |
||||||
|
} |
||||||
|
} |
||||||
|
&:checked { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
background-color: $color2; |
||||||
|
box-shadow: inset 0 0 0 4px $color1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&:focus { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
outline: none; |
||||||
|
border-color: $color2; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
&:disabled { |
||||||
|
+ .radio-label { |
||||||
|
&:before { |
||||||
|
box-shadow: inset 0 0 0 4px $color1; |
||||||
|
border-color: darken($color1, 25%); |
||||||
|
background: darken($color1, 25%); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
+ .radio-label { |
||||||
|
&:empty { |
||||||
|
&:before { |
||||||
|
margin-right: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import Button from "../../../components/Button"; |
||||||
|
import Radio from "../../../components/Radio"; |
||||||
|
|
||||||
|
function Address({ addresses, isDark }) { |
||||||
|
const [activeAddress, setActiveAddress] = useState(addresses[0]); |
||||||
|
const Location = ({ address }) => { |
||||||
|
return ( |
||||||
|
<button |
||||||
|
className={`flex flex-row border-2 border-solid items-center w-full px-3 py-4 rounded-md mt-4 transition-all duration-500 dark:bg-opacity-5 ${ |
||||||
|
activeAddress === address |
||||||
|
? "bg-blueFD border-blueC0" |
||||||
|
: "bg-grayF9 border-gray45" |
||||||
|
}`}
|
||||||
|
> |
||||||
|
<Radio /> |
||||||
|
<div className="flex flex-1 flex-col mr-3"> |
||||||
|
<li className="text-right text-xs text-blue52 dark:text-white leading-4"> |
||||||
|
آدرس: {address.address} |
||||||
|
</li> |
||||||
|
<li className="text-right text-xs text-blue52 dark:text-white mt-1.5"> |
||||||
|
نام تحویل گیرنده: {address.receiver} |
||||||
|
</li> |
||||||
|
<li className="text-right text-xs text-blue52 dark:text-white mt-1.5"> |
||||||
|
کد پستی: {address.postalCode} |
||||||
|
</li> |
||||||
|
<li className="text-right text-xs text-blue52 dark:text-white mt-1.5"> |
||||||
|
شماره تماس: {address.cellphone} |
||||||
|
</li> |
||||||
|
</div> |
||||||
|
</button> |
||||||
|
); |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<section className="mt-2"> |
||||||
|
<strong className="font-medium dark:text-white">انتخاب آدرس</strong> |
||||||
|
<ul className="list-none p-0 m-0 flex flex-col"> |
||||||
|
{addresses.map((address, index) => ( |
||||||
|
<Location address={address} key={index} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
<div className="w-full flex flex-row justify-between items-center mt-4"> |
||||||
|
<Button |
||||||
|
title="یک آدرس جدید اضافه کنید +" |
||||||
|
backgroundColor="bg-grayF9 dark:bg-blueC0 dark:bg-opacity-30" |
||||||
|
border={{ color: isDark ? '#DBDBDB22' : "#DBDBDB", width: "1px" }} |
||||||
|
bgOpacity="bg-opacity-100" |
||||||
|
width="100%" |
||||||
|
color={isDark ? "text-white" : "text-gray70"} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</section> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({ |
||||||
|
isDark: state.publicApi.isDark, |
||||||
|
}); |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(Address); |
@ -0,0 +1,36 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
|
||||||
|
function PaymentMethods({ paymentMethods, isDark }) { |
||||||
|
const [activeMethod, setActiveMactiveMethod] = useState(paymentMethods[0]); |
||||||
|
const Method = ({ method }) => { |
||||||
|
return ( |
||||||
|
<button |
||||||
|
className={`flex flex-col border border-solid items-center w-full px-2.5 py-3.5 rounded-md mt-4 relative transition-all duration-500 dark:text-white ${ |
||||||
|
activeMethod === method |
||||||
|
? "bg-blueFD border-blueC0 text-blueC0 bg-opacity-5" |
||||||
|
: "bg-grayF9 border-grayDB text-gray70 bg-opacity-5" |
||||||
|
}`}
|
||||||
|
onClick={() => setActiveMactiveMethod(method)} |
||||||
|
> |
||||||
|
{method.name} |
||||||
|
</button> |
||||||
|
); |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<section className="mt-8"> |
||||||
|
<strong className="font-medium dark:text-white">انتخاب شیوه پرداخت</strong> |
||||||
|
<ul className="list-none p-0 m-0 flex flex-row justify-between flex-wrap"> |
||||||
|
{paymentMethods.map((method, index) => ( |
||||||
|
<Method method={method} key={index} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</section> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({ |
||||||
|
isDark: state.publicApi.isDark, |
||||||
|
}); |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(PaymentMethods); |
@ -0,0 +1,53 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import Button from "../../../components/Button"; |
||||||
|
import Radio from "../../../components/Radio"; |
||||||
|
|
||||||
|
function TransportDate({ transportDate, isDark }) { |
||||||
|
const [activeDate, setActiveDate] = useState(transportDate?.times[0]); |
||||||
|
const Time = ({ time }) => { |
||||||
|
return ( |
||||||
|
<button |
||||||
|
className={`flex flex-col border border-solid items-center flex-1 mx-1 px-2 py-3 rounded-md mt-4 relative transition-all duration-500 ${ |
||||||
|
activeDate === time |
||||||
|
? "bg-blueFD border-blueC0 dark:bg-opacity-5" |
||||||
|
: "bg-grayF9 border-grayDB dark:bg-opacity-5" |
||||||
|
}`}
|
||||||
|
onClick={() => setActiveDate(time)} |
||||||
|
> |
||||||
|
<strong |
||||||
|
className={`text-sm transition-all duration-500 dark:text-white ${ |
||||||
|
activeDate === time ? "text-blueC0" : "text-blue52" |
||||||
|
}`}
|
||||||
|
> |
||||||
|
{time.time} |
||||||
|
</strong> |
||||||
|
{time.status === "completed" && ( |
||||||
|
<span |
||||||
|
className={`text-xs transition-all duration-500 dark:text-white ${ |
||||||
|
activeDate === time ? "text-blueC0" : "text-blue52" |
||||||
|
}`}
|
||||||
|
> |
||||||
|
تکمیل ظرفیت |
||||||
|
</span> |
||||||
|
)} |
||||||
|
</button> |
||||||
|
); |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<section className="mt-8"> |
||||||
|
<strong className="font-medium dark:text-white">زمان ارسال را انتخاب کنید</strong> |
||||||
|
<ul className="list-none p-0 m-0 flex flex-row justify-between flex-wrap"> |
||||||
|
{transportDate.times.map((time, index) => ( |
||||||
|
<Time time={time} key={index} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</section> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({ |
||||||
|
isDark: state.publicApi.isDark, |
||||||
|
}); |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(TransportDate); |
@ -0,0 +1,62 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import Button from "../../../components/Button"; |
||||||
|
import Radio from "../../../components/Radio"; |
||||||
|
|
||||||
|
function TransportMethod({ transportMethods, isDark }) { |
||||||
|
const [activeMethod, setActiveMethod] = useState(transportMethods[0]); |
||||||
|
const Method = ({ method }) => { |
||||||
|
return ( |
||||||
|
<button |
||||||
|
className={`flex flex-col border border-solid items-center w-full px-2 py-3 rounded-md mt-4 relative transition-all duration-500 ${ |
||||||
|
activeMethod === method |
||||||
|
? "bg-blueFD border-blueC0 dark:bg-opacity-5" |
||||||
|
: "bg-grayF9 border-grayDB dark:bg-opacity-5" |
||||||
|
}`}
|
||||||
|
onClick={() => setActiveMethod(method)} |
||||||
|
> |
||||||
|
<strong |
||||||
|
className={`text-sm transition-all duration-500 ${ |
||||||
|
activeMethod === method |
||||||
|
? "text-blueC0 dark:text-white" |
||||||
|
: "text-blue52 dark:text-white" |
||||||
|
}`}
|
||||||
|
> |
||||||
|
{method.name} |
||||||
|
</strong> |
||||||
|
<span |
||||||
|
className={`text-xs transition-all duration-500 ${ |
||||||
|
activeMethod === method |
||||||
|
? "text-blueC0 dark:text-white" |
||||||
|
: "text-blue52 dark:text-white" |
||||||
|
}`}
|
||||||
|
> |
||||||
|
هزینه ارسال {method.cost} |
||||||
|
</span> |
||||||
|
<img |
||||||
|
src={method.icon} |
||||||
|
alt={method.name} |
||||||
|
className="w-7 absolute left-3 top-1/2 transform -translate-y-1/2" |
||||||
|
/> |
||||||
|
</button> |
||||||
|
); |
||||||
|
}; |
||||||
|
return ( |
||||||
|
<section className="mt-8"> |
||||||
|
<strong className="font-medium dark:text-white"> |
||||||
|
لطفا یک روش ارسال انتخاب کنید |
||||||
|
</strong> |
||||||
|
<ul className="list-none p-0 m-0 flex flex-col"> |
||||||
|
{transportMethods.map((method, index) => ( |
||||||
|
<Method method={method} key={index} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</section> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({ |
||||||
|
isDark: state.publicApi.isDark, |
||||||
|
}); |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(TransportMethod); |
@ -0,0 +1,18 @@ |
|||||||
|
import React, { useEffect } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import { publicApi } from "../../../redux/actions"; |
||||||
|
|
||||||
|
export const Content = ({ headerOptions, setHeaderOptions, setPage }) => { |
||||||
|
useEffect(() => { |
||||||
|
setHeaderOptions(headerOptions); |
||||||
|
}); |
||||||
|
return <div></div>; |
||||||
|
}; |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({}); |
||||||
|
|
||||||
|
const mapDispatchToProps = { |
||||||
|
setHeaderOptions: publicApi.setHeaderOptions, |
||||||
|
}; |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Content); |
@ -0,0 +1,67 @@ |
|||||||
|
import React, { useState, useEffect } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import { publicApi } from "../../../redux/actions"; |
||||||
|
import { useNavigate } from "react-router-dom"; |
||||||
|
import Scanner from "react-qr-reader"; |
||||||
|
import laptopImage from "../../../assets/images/laptop.svg"; |
||||||
|
|
||||||
|
const facingMode = ["environment", "user"]; |
||||||
|
|
||||||
|
export const Scan = ({ headerOptions, setHeaderOptions, setPage }) => { |
||||||
|
const navigation = useNavigate(); |
||||||
|
const [result, setResult] = useState(""); |
||||||
|
|
||||||
|
const handleScan = (data) => { |
||||||
|
setResult(data); |
||||||
|
}; |
||||||
|
|
||||||
|
const handleError = (err) => { |
||||||
|
console.error(err); |
||||||
|
}; |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
setHeaderOptions(headerOptions); |
||||||
|
}); |
||||||
|
|
||||||
|
return ( |
||||||
|
<div |
||||||
|
className="w-full h-screen bg-transparent px-0 transform -translate-y-16" |
||||||
|
style={{ backgroundImage: `url(${laptopImage})` }} |
||||||
|
> |
||||||
|
{!result && ( |
||||||
|
<div className="w-full h-full flex flex-col justify-center bg-gray50 items-center px-6 bg-opacity-70 backdrop-filter backdrop-blur-sm"> |
||||||
|
<div className="rounded-3xl overflow-hidden w-full"> |
||||||
|
<Scanner |
||||||
|
delay={300} |
||||||
|
onError={handleError} |
||||||
|
onScan={handleScan} |
||||||
|
style={{ width: "100%" }} |
||||||
|
facingMode={facingMode[1]} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<strong className="mt-4 text-white text-xl"> |
||||||
|
اسکن کد QR فعالسازی کتاب |
||||||
|
</strong> |
||||||
|
<p className="text-sm text-white text-center mt-2 font-medium"> |
||||||
|
کد کیو آر روی کارت فعالسازی را با دوربین گوشی اسکن کنید تا محتوای |
||||||
|
دیجیتال مربوط به کتاب برای شما فعال شود |
||||||
|
</p> |
||||||
|
<button |
||||||
|
onClick={() => navigation(-1)} |
||||||
|
className="py-3 mt-16 w-2/5 rounded-3xl border-2 border-solid border-blueB9 text-white text-lg font-semibold" |
||||||
|
> |
||||||
|
بازگشت |
||||||
|
</button> |
||||||
|
</div> |
||||||
|
)} |
||||||
|
</div> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({}); |
||||||
|
|
||||||
|
const mapDispatchToProps = { |
||||||
|
setHeaderOptions: publicApi.setHeaderOptions, |
||||||
|
}; |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Scan); |
@ -0,0 +1,19 @@ |
|||||||
|
import React, { useState } from "react"; |
||||||
|
import Scan from "./Scan"; |
||||||
|
import Content from "./Content"; |
||||||
|
|
||||||
|
function QR({ headerOptions, page }) { |
||||||
|
const [currentPage, setCurrentPage] = useState(page); |
||||||
|
return ( |
||||||
|
<> |
||||||
|
{page === "scan" && ( |
||||||
|
<Scan headerOptions={headerOptions} setPage={setCurrentPage} /> |
||||||
|
)} |
||||||
|
{page === "content" && ( |
||||||
|
<Content headerOptions={headerOptions} setPage={setCurrentPage} /> |
||||||
|
)} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default QR; |
@ -0,0 +1,21 @@ |
|||||||
|
import React, { useState, useEffect, useCallback } from "react"; |
||||||
|
import { Link } from "react-router-dom"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import { book, publicApi } from "../../redux/actions"; |
||||||
|
|
||||||
|
|
||||||
|
const Videos = ({ }) => { |
||||||
|
return ( |
||||||
|
<></> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({ |
||||||
|
|
||||||
|
}); |
||||||
|
|
||||||
|
const mapDispatchToProps = { |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Videos); |
Loading…
Reference in new issue