parent
6bef83dd46
commit
3038fae33d
22 changed files with 990 additions and 72 deletions
@ -0,0 +1,119 @@ |
||||
|
||||
.Slider{ |
||||
width: 100%; |
||||
height: 80vh; |
||||
overflow: hidden; |
||||
position: relative; |
||||
z-index: 4; |
||||
max-width: 1550px; |
||||
@media screen and (min-width: 1551px) { |
||||
margin: 0 auto; |
||||
} |
||||
|
||||
&-main-box { |
||||
width: 100%; |
||||
height: 100%; |
||||
position: absolute; |
||||
top: 0; |
||||
left: 0; |
||||
|
||||
&-title { |
||||
width: 80%; |
||||
margin: 0 auto; |
||||
font-size: 38px; |
||||
color: #fff; |
||||
font-family: Medium; |
||||
} |
||||
|
||||
&-item-container { |
||||
width: 80%; |
||||
margin: 0 auto; |
||||
margin-top: 20px; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
// direction: rtl; |
||||
|
||||
&-item { |
||||
width: 32%; |
||||
flex-shrink: 0; |
||||
aspect-ratio: 1/0.85; |
||||
border-radius: 21px; |
||||
background-color: rgba($color: #fff, $alpha: 0.1); |
||||
backdrop-filter: blur(10px); |
||||
box-sizing: border-box; |
||||
padding: 20px; |
||||
margin-right: 2%; |
||||
transition: all 1s; |
||||
|
||||
&-img-container { |
||||
width: 100%; |
||||
height: 70%; |
||||
// background-color: rgb(253, 57, 178); |
||||
} |
||||
|
||||
&-title { |
||||
font-size: 24px; |
||||
width: 100%; |
||||
margin-top: 10px; |
||||
font-family: Medium; |
||||
color: #0080ff; |
||||
} |
||||
|
||||
&-subtitle { |
||||
width: 100%; |
||||
font-size: 18px; |
||||
margin-top: 10px; |
||||
color: #fff; |
||||
font-family: Thin; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&-slider-btns { |
||||
width: 80%; |
||||
margin: 0 auto; |
||||
margin-top: 30px; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
|
||||
&-previous { |
||||
display: flex; |
||||
align-items: center; |
||||
cursor: pointer; |
||||
color: #555; |
||||
|
||||
&-icon { |
||||
// color: #fff; |
||||
font-size: 25px; |
||||
margin-right: 10px; |
||||
} |
||||
|
||||
&-text { |
||||
font-size: 30px; |
||||
font-family: Thin; |
||||
// color: #fff; |
||||
} |
||||
} |
||||
|
||||
&-next { |
||||
display: flex; |
||||
align-items: center; |
||||
cursor: pointer; |
||||
|
||||
&-icon { |
||||
color: #fff; |
||||
font-size: 25px; |
||||
margin-left: 10px; |
||||
} |
||||
|
||||
&-text { |
||||
font-size: 30px; |
||||
font-family: Thin; |
||||
color: #fff; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,21 @@ |
||||
import React from "react"; |
||||
import { connect } from "react-redux"; |
||||
|
||||
export const Textarea = ({ rows, value, onChange, name, placeholder }) => { |
||||
return ( |
||||
<textarea |
||||
rows={rows} |
||||
value={value} |
||||
placeholder={placeholder} |
||||
name={name} |
||||
onChange={e => onChange(e.target.name, e.target.value)} |
||||
className={`w-full outline-none border border-solid border-gray-200 focus:border-primary-7 focus:bg-secondary-9 bg-gray-50 rounded-lg placeholder:text-gray-400 focus:text-secondary-8 text-2x p-6 font-2`} |
||||
/> |
||||
); |
||||
}; |
||||
|
||||
const mapStateToProps = (state) => ({}); |
||||
|
||||
const mapDispatchToProps = {}; |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Textarea); |
@ -0,0 +1,87 @@ |
||||
import { useCallback, useRef, useState } from "react"; |
||||
|
||||
export const useLongPress = ( |
||||
onLongPress, |
||||
onClick, |
||||
{ shouldPreventDefault = true, delay = 300 } = {} |
||||
) => { |
||||
const [longPressTriggered, setLongPressTriggered] = useState(false); |
||||
const timeout = useRef(); |
||||
const target = useRef(); |
||||
|
||||
const start = useCallback( |
||||
(event) => { |
||||
if (shouldPreventDefault && event.target) { |
||||
event.target.addEventListener("touchend", preventDefault, { |
||||
passive: false, |
||||
}); |
||||
target.current = event.target; |
||||
} |
||||
timeout.current = setTimeout(() => { |
||||
onLongPress(event); |
||||
setLongPressTriggered(true); |
||||
}, delay); |
||||
}, |
||||
[onLongPress, delay, shouldPreventDefault] |
||||
); |
||||
|
||||
const clear = useCallback( |
||||
(event, shouldTriggerClick = true) => { |
||||
timeout.current && clearTimeout(timeout.current); |
||||
shouldTriggerClick && !longPressTriggered && onClick(); |
||||
setLongPressTriggered(false); |
||||
if (shouldPreventDefault && target.current) { |
||||
target.current.removeEventListener("touchend", preventDefault); |
||||
} |
||||
}, |
||||
[shouldPreventDefault, onClick, longPressTriggered] |
||||
); |
||||
|
||||
return { |
||||
onMouseDown: (e) => start(e), |
||||
onTouchStart: (e) => start(e), |
||||
onMouseUp: (e) => clear(e), |
||||
onMouseLeave: (e) => clear(e, false), |
||||
onTouchEnd: (e) => clear(e), |
||||
}; |
||||
}; |
||||
|
||||
const isTouchEvent = (event) => { |
||||
return "touches" in event; |
||||
}; |
||||
|
||||
const preventDefault = (event) => { |
||||
if (!isTouchEvent(event)) return; |
||||
|
||||
if (event.touches.length < 2 && event.preventDefault) { |
||||
event.preventDefault(); |
||||
} |
||||
}; |
||||
|
||||
export default null; |
||||
|
||||
//sample of useLongPress
|
||||
// import useLongPress from "./useLongPress";
|
||||
|
||||
// export default function App() {
|
||||
|
||||
// const onLongPress = () => {
|
||||
// console.log('longpress is triggered');
|
||||
// };
|
||||
|
||||
// const onClick = () => {
|
||||
// console.log('click is triggered')
|
||||
// }
|
||||
|
||||
// const defaultOptions = {
|
||||
// shouldPreventDefault: true,
|
||||
// delay: 500,
|
||||
// };
|
||||
// const longPressEvent = useLongPress(onLongPress, onClick, defaultOptions);
|
||||
|
||||
// return (
|
||||
// <div className="App">
|
||||
// <button {...longPressEvent}>use Loooong Press</button>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
@ -0,0 +1,11 @@ |
||||
|
||||
class location { |
||||
getId = () => { |
||||
const pathname = window.location.pathname; |
||||
return pathname.slice(pathname.lastIndexOf('/') + 1, pathname.length); |
||||
} |
||||
} |
||||
|
||||
const _location = new location(); |
||||
|
||||
export default _location; |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 13 KiB |
@ -1,19 +1,90 @@ |
||||
import React from "react"; |
||||
import { connect } from "react-redux"; |
||||
import { form } from "../../../../redux/actions"; |
||||
import onInput from "../../../../utils/onInput"; |
||||
|
||||
export const Form = ({}) => { |
||||
//components
|
||||
import Input from "../../../../components/Input"; |
||||
import Button from "../../../../components/Button"; |
||||
import Textarea from "../../../../components/Textarea"; |
||||
|
||||
export const Form = ({ contact, setContact }) => { |
||||
return ( |
||||
<div |
||||
className="w-full flex items-center justify-center bg-purple-100" |
||||
className="w-10/12 flex flex-col items-center justify-around" |
||||
style={{ height: "calc(100vh - 100vh / 10)" }} |
||||
> |
||||
Form |
||||
<div className="flex flex-col items-center"> |
||||
<strong className="text-primary-3 font-6 text-5x"> |
||||
فرم درخواست سرویس{" "} |
||||
</strong> |
||||
<p className="text-2x font-4 text-gray-400 mt-3"> |
||||
در این قسمت یک متن بسیار عجیب و جالب باید قرار بگیرید{" "} |
||||
</p> |
||||
</div> |
||||
<div className="flex w-full justify-between"> |
||||
<div className="flex flex-col justify-center w-5/12"> |
||||
<strong className="text-primary-7 font-4 text-4x">تماس با ما </strong> |
||||
<strong className="text-black font-7 text-5x mt-2"> |
||||
سلام |
||||
<br /> بیاید با هم صحبت کنیم |
||||
</strong> |
||||
<strong className="text-black font-2 text-4x mt-4"> |
||||
Info@Barnamenegar.com |
||||
</strong> |
||||
</div> |
||||
<div className="h-full w-px bg-gray-200"></div> |
||||
<form |
||||
className="flex flex-col gap-6 items-end justify-center w-5/12" |
||||
onSubmit={(e) => e.prevDefault()} |
||||
> |
||||
<Input |
||||
placeholder="نام" |
||||
name="name" |
||||
value={contact.name} |
||||
onChange={(name, value) => setContact({ name, value })} |
||||
regex={(val) => val} |
||||
/> |
||||
<Input |
||||
placeholder="ایمیل" |
||||
name="email" |
||||
value={contact.email} |
||||
onChange={(name, value) => setContact({ name, value })} |
||||
regex={(val) => val} |
||||
/> |
||||
<Input |
||||
placeholder="زمینه فعالیت" |
||||
name="job" |
||||
value={contact.job} |
||||
onChange={(name, value) => setContact({ name, value })} |
||||
regex={(val) => val} |
||||
/> |
||||
<Textarea |
||||
rows={4} |
||||
name="message" |
||||
value={contact.message} |
||||
placeholder="پیام" |
||||
onChange={(name, value) => setContact({ name, value })} |
||||
/> |
||||
<Button |
||||
title="ارسال" |
||||
backgroundColor="bg-primary-7" |
||||
color="text-white" |
||||
padding="py-4 px-20" |
||||
round="rounded-lg" |
||||
/> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const mapStateToProps = (state) => ({}); |
||||
const mapStateToProps = (state) => ({ |
||||
contact: state.form.contact, |
||||
}); |
||||
|
||||
const mapDispatchToProps = {}; |
||||
const mapDispatchToProps = { |
||||
setContact: form.setContact, |
||||
}; |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Form); |
||||
|
Loading…
Reference in new issue