view controller

This commit is contained in:
2024-01-23 18:35:18 +05:00
parent 3206ec8540
commit 45cd2ad16f
12 changed files with 274 additions and 6 deletions
+51
View File
@@ -0,0 +1,51 @@
import { Parameters } from "../types/appartment";
type ParametersProps = {
parameters: Parameters;
};
const Parameters = ({ parameters }: ParametersProps) => {
return (
<div className="p-6 border-b">
<h2 className="text-xl font-medium ">Parameters</h2>
<div className="flex flex-col gap-2 pt-4">
<div className="flex justify-between gap-4">
<div className="w-1/2 text-sm text-[#666668] font-medium">Type</div>
<div className="w-1/2 text-sm font-medium">{parameters.type}</div>
</div>
<div className="flex justify-between gap-4">
<div className="w-1/2 text-sm text-[#666668] font-medium">
Plot area
</div>
<div className="w-1/2 text-sm font-medium">{parameters.plotArea}</div>
</div>
<div className="flex justify-between gap-4">
<div className="w-1/2 text-sm text-[#666668] font-medium">
Total Build up Area
</div>
<div className="w-1/2 text-sm font-medium">
{parameters.totalBuildUpArea}
</div>
</div>
<div className="flex justify-between gap-4">
<div className="w-1/2 text-sm text-[#666668] font-medium">
Total no. of Bedrooms
</div>
<div className="w-1/2 text-sm font-medium">
{parameters.TotalCountBedroms}
</div>
</div>
<div className="flex justify-between gap-4">
<div className="w-1/2 text-sm text-[#666668] font-medium">
Villa Theme
</div>
<div className="w-1/2 text-sm font-medium">
{parameters.villaTheme}
</div>
</div>
</div>
</div>
);
};
export default Parameters;
+77
View File
@@ -0,0 +1,77 @@
import { useState } from "react";
import { useSwipeable } from "react-swipeable";
import { SliderType } from "../types/appartment";
type SliderProps = {
sliders: SliderType[];
};
const Slider = ({ sliders }: SliderProps) => {
const [offset, setOffset] = useState(0);
const handleOnRight = () => {
if (offset < 0) {
setOffset((prev) => prev + 1);
}
};
const handleOnLeft = () => {
if (offset > 1 - sliders.length) {
setOffset((prev) => prev - 1);
}
};
const handlers = useSwipeable({
onSwipedRight: handleOnRight,
onSwipedLeft: handleOnLeft,
});
return (
<div className="border-b">
<div className="h-7 overflow-y-hidden ">
<div
className="transition-all duration-300"
style={{
transform: `translateY(${offset * 28}px)`,
}}
>
{sliders.map(({ title }) => (
<h2 key={title} className="h-7 font-medium text-[16px] text-center">
{title}
</h2>
))}
</div>
</div>
<div className="flex w-full overflow-x-hidden">
<div
{...handlers}
className="flex w-full transition-all duration-300"
style={{
transform: `translateX(${offset * 100}vw)`,
}}
>
{sliders.map((slider) => (
<div
className={`h-full min-w-full flex flex-col px-6 transition-all duration-300`}
key={slider.title}
>
<img src={slider.image} alt="" />
</div>
))}
</div>
</div>
<div className="flex justify-center pb-4">
{sliders.map(({ title }, index) => (
<div className="p-1" key={title}>
<div
className={`w-2 h-2 rounded-full transition-all duration-300 ${
0 - index === offset ? "bg-[#050409]" : "bg-[#DDD7D6]"
}`}
></div>
</div>
))}
</div>
</div>
);
};
export default Slider;
+76
View File
@@ -0,0 +1,76 @@
import { useState } from "react";
import ButtonSwipperIcon from "../icons/ButtonSwipperIcon";
import { Parameters as ParametersType } from "../types/appartment";
import Parameters from "./Parameters";
import Slider from "./Slider";
import { SwipeEventData, useSwipeable } from "react-swipeable";
import { HandledEvents } from "react-swipeable/es/types";
type ViewControllerProps = {
parameters: ParametersType;
};
const ViewController = ({ parameters }: ViewControllerProps) => {
const { sliders } = parameters;
const [offset, setOffset] = useState(0);
const [isScroll, setIsScroll] = useState(false);
const handleOnSwiped = (eventData: SwipeEventData) => {
if (eventData.dir === "Down") {
setOffset(1);
}
if (eventData.dir === "Up") {
// setTimeout(() => {
setOffset(0);
// }, 1000);
}
};
const handleOnBackClick = () => {
setOffset(1);
};
const handleOnTouchEnd = ({ event }: { event: HandledEvents }) => {
console.log("event", event);
};
const handlers = useSwipeable({
onSwiped: handleOnSwiped,
// onSwiping:()=>
// onSwipeStart: () => setIsScroll(true),
// onSwiped: () => setIsScroll(false),
// onSwiped: () => console.log("first"),
// onTouchEndOrOnMouseUp: handleOnTouchEnd,
// swipeDuration: 300,
preventScrollOnSwipe: true,
});
return (
<div
className="bg-white w-full h-screen border rounded-ss-2xl rounded-se-2xl flex flex-col transition-all duration-1000 overflow-hidden"
style={{
transform: `translateY(calc(${offset * 90}vh))`,
}}
{...handlers}
>
<div className="mx-auto flex justify-center self-start w-full">
<ButtonSwipperIcon />
</div>
<div className="h-[calc(100vh-110px)] overflow-y-scroll">
<Slider sliders={sliders} />
<Parameters parameters={parameters} />
</div>
<div className="px-6 py-3 mt-auto border">
<button
className="border flex w-full py-3 justify-center rounded-full"
onClick={handleOnBackClick}
>
Back
</button>
</div>
</div>
);
};
export default ViewController;
+15
View File
@@ -0,0 +1,15 @@
const ButtonSwipperIcon = () => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<rect x="2" y="11" width="20" height="2" rx="1" fill="#C7BDBA" />
</svg>
);
};
export default ButtonSwipperIcon;
+4 -1
View File
@@ -1,9 +1,12 @@
@import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;600&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&family=Noto+Sans:wght@500&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
font-family: "Manrope", sans-serif;
font-family: "Montserrat", sans-serif;
font-family: "Noto Sans", sans-serif;
background-color: #c7bdba;
}
+15
View File
@@ -0,0 +1,15 @@
type Slider = {
title: string;
image: string;
}
type Parameters = {
type: string;
plotArea: string;
totalBuildUpArea: string;
TotalCountBedroms: number;
villaTheme: string;
sliders: Slider[];
};
export type {Slider as SliderType, Parameters}
+28 -3
View File
@@ -1,20 +1,45 @@
import { useEffect } from "react";
import useStore from "../store/store";
import LoaderModal from "../components/LoaderModal";
// import LoaderModal from "../components/LoaderModal";
import { isMobile } from "react-device-detect";
import ViewController from "../components/ViewController";
import { Parameters } from "../types/appartment";
const mainViewParams: Parameters = {
type: "A1M",
plotArea: "1080 Sq.m",
totalBuildUpArea: "472 Sq.m",
TotalCountBedroms: 5,
villaTheme: "Modern",
sliders: [
{
title: "General View",
image: "/images/apartment/A1M/A1M_P.png",
},
{
title: "Ground Floor",
image: "/images/apartment/A1M/A1M_GF.png",
},
{
title: "First Floor",
image: "/images/apartment/A1M/A1M_1F.png",
},
],
};
const MainView = () => {
const { modal, setModal } = useStore();
console.log("isMobile", isMobile);
useEffect(() => {
setModal(<LoaderModal />);
// setModal(<LoaderModal />);
}, [setModal]);
return (
<>
{modal}
<div className="bg-black w-8 h-8 text-white ">add</div>
{/* <div className="bg-black w-8 h-8 text-white ">add</div> */}
<ViewController parameters={mainViewParams} />
</>
);
};