Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re : 랜딩 페이지에 파티 리스트에 드라이버 프로필 추가 #234

Merged
merged 1 commit into from
Jan 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/api/driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export const getRegionDriver = async (
true
);

export const getDriver = async () => await GET(`/driver/search`, true);

export const getDriverInfo = async (driverId: string | number) =>
await GET(`/driver/${driverId}`, true);

Expand Down
35 changes: 35 additions & 0 deletions src/pages/LandingPage/PartyList/DriverBox/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { memo, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { DriverData } from "@/types";
import basicProfileImage from "@/assets/images/profileImage.png";

function DriverBox({ driverId, name, profileImg, region }: DriverData) {
const navigate = useNavigate();

const onClickHandler = useCallback(() => {
navigate(`/driver/profile/${driverId}`);
}, [driverId]);

return (
<div className="bg-skyblue rounded-lg h-64">
<div className="relative h-[220px] border rounded-lg">
<img
className="absolute top-0 left-0 object-cover object-center w-full h-full overflow-hidden rounded-lg"
src={profileImg || basicProfileImage}
alt={name}
/>
<div className="absolute top-0 left-0 flex flex-col items-center justify-end w-full h-full text-base text-darkgray pb-3">
<button
className="h-9 text-white rounded-full text-xs font-bold w-32 bg-primary"
onClick={onClickHandler}
>
프로필
</button>
</div>
</div>
<div className="py-1 text-center text-lg text-primary font-semibold">{`${region.length === 1 ? region : "다양한 지역"} ${name} 드라이버`}</div>
</div>
);
}

export default memo(DriverBox);
30 changes: 24 additions & 6 deletions src/pages/LandingPage/PartyList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { memo, useCallback, useEffect, useState } from "react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import { useSelector } from "react-redux";
import { RootState } from "@/redux/store";
import { getPartyList } from "@/api/party";
import { dateToString } from "@/utils";
import { HeartParty } from "@/types";
import { dateToString, shuffleArray } from "@/utils";
import { DriverData, HeartParty } from "@/types";
import PartyBox from "./PartyBox";
import NoParty from "./NoParty";
import { getDriver } from "@/api/driver";
import DriverBox from "./DriverBox";

function PartyList() {
const { region, nowDate, num, price } = useSelector(
(state: RootState) => state.partyFilter
);
const [partyData, setPartyData] = useState<HeartParty[]>([]);
const [driverData, setDriverData] = useState<DriverData[]>([]);
const [loading, setLoading] = useState(true);

const ramdomSeed = useMemo(() => {
const today = new Date();
return (
today.getFullYear() * 10000 +
(today.getMonth() + 1) * 100 +
today.getDate()
);
}, []);

const getData = useCallback(async () => {
const regionQuery = region === "모든 지역" ? "all" : region;
const nowDateQuery =
Expand All @@ -24,32 +36,38 @@ function PartyList() {
const priceQuery = price;

try {
const driverResult = await getDriver();
const result = await getPartyList(
regionQuery,
nowDateQuery,
numQuery,
priceQuery
);

setDriverData(shuffleArray(driverResult.payload, ramdomSeed));
setPartyData(result.payload);
} catch (e) {
console.log(e);
} finally {
setLoading(false);
}
}, [region, nowDate, num, price]);
}, [region, nowDate, num, price, ramdomSeed]);

useEffect(() => {
getData();
window.scrollTo({ top: 0 });
}, [region, nowDate, num, price]);
}, [region, nowDate, num, price, ramdomSeed]);

if (loading) return null;
if (partyData.length === 0) return <NoParty />;
if (partyData.length === 0 && driverData.length === 0) return <NoParty />;
return (
<div className="grid grid-cols-1 gap-10 mt-6 mx-auto sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4">
{partyData.map((item) => (
<PartyBox key={item.partyId} {...item} />
))}
{driverData.map((item) => (
<DriverBox key={item.driverId} {...item} />
))}
</div>
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ export interface RegionDriverData {
userNickname: string;
}

export interface DriverData {
driverId: number;
name: string;
profileImg: string;
region: string[];
}

export interface Message {
type: string;
userId: number;
Expand Down
12 changes: 12 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { DriverData } from "@/types";

export function setScreenHeight() {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
Expand Down Expand Up @@ -182,3 +184,13 @@ export const isIos = () => {
UA.indexOf("ipod") > -1
);
};

export const shuffleArray = (array: DriverData[], seed: number) => {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const randomIndex = Math.floor(seed % (i + 1));
[result[i], result[randomIndex]] = [result[randomIndex], result[i]];
seed = (seed * 9301 + 49297) % 233280; // 간단한 난수 생성
}
return result;
};