Skip to content

Commit

Permalink
Merge pull request #318 from boostcampwm-2024/Feat/41
Browse files Browse the repository at this point in the history
[Feat] 분야별 필터링 구현
  • Loading branch information
zero0205 authored Dec 1, 2024
2 parents 4546d37 + 8d991c1 commit acf452c
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 47 deletions.
35 changes: 35 additions & 0 deletions apps/client/src/pages/Home/FieldFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Button } from '@/components/ui/button';
import { Field } from '@/types/liveTypes';

const fields: Field[] = ['WEB', 'AND', 'IOS'];

interface FieldFilterProps {
selectedField: Field;
onFieldSelect: (field: Field) => void;
}

function FieldFilter({ selectedField, onFieldSelect }: FieldFilterProps) {
const handleClick = (field: Field) => {
onFieldSelect(selectedField === field ? '' : field);
};

return (
<div className="flex flex-row justify-between gap-4">
{fields.map((field: Field) => (
<Button
key={field}
onClick={() => handleClick(field)}
className={`${
selectedField === field
? 'bg-surface-brand-default hover:bg-surface-point-alt'
: 'bg-transparent border border-border-default hover:bg-surface-alt'
}`}
>
{field}
</Button>
))}
</div>
);
}

export default FieldFilter;
64 changes: 47 additions & 17 deletions apps/client/src/pages/Home/LiveList.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,54 @@
import FieldFilter from './FieldFilter';
import LiveCard from './LiveCard';
import { LivePreviewInfo } from '@/types/homeTypes';
import { useEffect, useState } from 'react';
import { Field } from '@/types/liveTypes';
import axiosInstance from '@/services/axios';
import Search from './Search';

function LiveList() {
const [field, setField] = useState<Field>('');
const [liveList, setLiveList] = useState<LivePreviewInfo[]>([]);

useEffect(() => {
axiosInstance.get('/v1/broadcasts', { params: { field: field } }).then(response => {
if (response.data.success) {
setLiveList(response.data.data.broadcasts);
}
});
}, [field]);

const handleSelectField = (selected: Field) => {
setField(selected);
};

function LiveList({ liveList }: { liveList: LivePreviewInfo[] }) {
return (
<div className="grid grid-cols-1 min-[690px]:grid-cols-2 min-[1040px]:grid-cols-3 min-[1380px]:grid-cols-4 min-[1720px]:grid-cols-5 gap-x-[clamp(40px,2vw,60px)] gap-y-12 auto-rows-min p-15 w-[95%] max-w-[1920px] align-items-start">
{liveList &&
liveList.map(livePreviewInfo => {
const { broadcastId, broadcastTitle, camperId, profileImage, thumbnail } = livePreviewInfo;
return (
<div key={broadcastId} className="flex justify-center">
<LiveCard
liveId={broadcastId}
title={broadcastTitle}
userId={camperId}
profileUrl={profileImage}
thumbnailUrl={thumbnail}
/>
</div>
);
})}
<div className="flex flex-col w-full h-full p-10">
<div className="h-14 w-full flex justify-between items-center my-5 px-5">
<FieldFilter selectedField={field} onFieldSelect={handleSelectField} />
<Search />
</div>
<div className="grid grid-cols-1 min-[690px]:grid-cols-2 min-[1040px]:grid-cols-3 min-[1380px]:grid-cols-4 min-[1720px]:grid-cols-5 gap-x-[clamp(40px,2vw,60px)] gap-y-12 auto-rows-min p-15 w-[95%] max-w-[1920px] align-items-start">
{liveList ? (
liveList.map(data => {
const { broadcastId, broadcastTitle, camperId, profileImage, thumbnail } = data;
console.log(data);
return (
<div key={broadcastId} className="flex justify-center">
<LiveCard
liveId={broadcastId}
title={broadcastTitle}
userId={camperId}
profileUrl={profileImage}
thumbnailUrl={thumbnail}
/>
</div>
);
})
) : (
<div>방송 정보가 없습니다.</div>
)}
</div>
</div>
);
}
Expand Down
5 changes: 5 additions & 0 deletions apps/client/src/pages/Home/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function Search() {
return <div className="bg-surface-alt w-52 h-10"></div>;
}

export default Search;
30 changes: 1 addition & 29 deletions apps/client/src/pages/Home/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
import LiveList from '@pages/Home/LiveList';
import LoadingCharacter from '@components/LoadingCharacter';
import ErrorCharacter from '@components/ErrorCharacter';
import { useAPI } from '@hooks/useAPI';
import { LivePreviewListInfo } from '@/types/homeTypes';
import { useEffect, useState } from 'react';

export default function Home() {
const { data: liveListInfo, isLoading, error } = useAPI<LivePreviewListInfo>({ url: '/v1/broadcasts' });
const [showLoading, setShowLoading] = useState(false);

useEffect(() => {
const timer = setTimeout(() => {
setShowLoading(true);
}, 250);

return () => clearTimeout(timer);
});

return (
<div className="flex justify-center w-full h-full">
{error ? (
<div className="flex justify-center items-center flex-1">
<ErrorCharacter message={error.message} />
</div>
) : isLoading && showLoading ? (
<div className="flex justify-center items-center flex-1">
<LoadingCharacter />
</div>
) : liveListInfo?.broadcasts && liveListInfo.broadcasts.length > 0 ? (
<LiveList liveList={liveListInfo.broadcasts} />
) : (
<div className="h-full flex items-center">방송 중인 캠퍼가 없습니다.</div>
)}
<LiveList />
</div>
);
}
4 changes: 3 additions & 1 deletion apps/client/src/types/liveTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export interface LiveInfo {
title: string;
camperId: string;
viewers: number;
field: 'WEB' | 'AND' | 'IOS';
field: Field;
profileImage: string;
contacts: ContactInfo;
}

export type Field = 'WEB' | 'AND' | 'IOS' | '';

0 comments on commit acf452c

Please sign in to comment.