Skip to content

Commit

Permalink
Merge pull request #169 from Donggrina/feature/search
Browse files Browse the repository at this point in the history
Feat: 검색 페이지 ui 수정
  • Loading branch information
DHyeon98 authored Jun 22, 2024
2 parents 40c7eff + 607d681 commit ed21013
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 114 deletions.
45 changes: 45 additions & 0 deletions components/search/search-checkbox.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.label {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
}

.imageContainer {
position: relative;
width: 14px;
height: 14px;
border: 2px solid var(--pet-border);
border-radius: 4px;

&:has(.input:checked) {
border: 2px solid var(--main-color);
background-color: var(--main-color);
}
}

.image {
border-radius: 9999px;
}

.input:checked ~ .check {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}

.check {
display: none;
}

.input {
width: 0;
height: 0;
}

.value {
font-weight: 400;
font-size: 12px;
}
30 changes: 30 additions & 0 deletions components/search/search-checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Image from 'next/image';
import styles from './search-checkbox.module.scss';
import { FieldValues, UseFormRegister } from 'react-hook-form';

interface SearchCheckboxProps {
register: UseFormRegister<FieldValues>;
selected: string[];
name: string;
value: string;
}

export default function SearchCheckbox({ register, selected, name, value }: SearchCheckboxProps) {
const isSelected = selected.includes(value);

return (
<label className={styles.label}>
<div className={styles.imageContainer}>
<input
{...register(name, { validate: (selected: string) => !!selected || '* 항목을 선택해주세요.' })}
value={value}
className={styles.input}
type="checkbox"
checked={isSelected}
/>
<Image src="/images/search/check.svg" alt="체크 표시" width={8} height={6} className={styles.check} />
</div>
<p className={styles.value}>{value}</p>
</label>
);
}
5 changes: 2 additions & 3 deletions components/search/search-form.module.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
.inner {
padding: 30px 24px;
padding: 30px 0;
display: flex;
flex-direction: column;
gap: 28px;
}

.dateContainer {
Expand All @@ -14,7 +13,7 @@

.pets {
display: flex;
gap: 16px;
gap: 6px;
width: 100%;
}

Expand Down
66 changes: 11 additions & 55 deletions components/search/search-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ import usePetsQuery from '@/hooks/queries/calendar/use-pets-query';
import { FieldValues, SubmitHandler, useForm } from 'react-hook-form';
import { SERVICE_CONFIGS } from '@/utils/constants/search';
import useMembersQuery from '@/hooks/queries/search/use-members-query';
import SearchMemberFilter from '@/components/search/search-member-filter';
import SearchSection from '@/components/search/search-section';
import SearchPetCheckbox from '@/components/search/search-pet-checkbox';
import getQueryString from '@/utils/search/get-query-string';
import { SearchFormProps } from '@/types/search';
import useResultsQuery from '@/hooks/queries/search/use-results-query';
import { PropsWithChildren, useEffect, useState } from 'react';
import { DiaryByQueries, GrowthByQueries, TodoByQueries } from '@/api/search/index.type';
import Calendar from '../calendar-compound/calendar';
import useSelect from '@/hooks/use-select';
import CalendarInstance from '@/utils/date/date.utils';
import SearchCheckbox from './search-checkbox';

export default function SearchForm({ service, onSubmit: handleResults, children }: PropsWithChildren<SearchFormProps>) {
const [searchParams, setSearchParams] = useState('');
Expand Down Expand Up @@ -54,7 +50,7 @@ export default function SearchForm({ service, onSubmit: handleResults, children
const keyword = getQueryString(SERVICE_CONFIGS[service].queries[0], [formData.keyword]);
const petNames = getQueryString(SERVICE_CONFIGS[service].queries[1], formData.pets);
const writerNames = getQueryString(SERVICE_CONFIGS[service].queries[2], formData.members);
const date = getQueryString(SERVICE_CONFIGS['diary'].queries[3], [yearMonthDate]);
const date = getQueryString(SERVICE_CONFIGS['diary'].queries[3], ['']);

setSearchParams(`?${keyword}&${petNames}&${writerNames}` + (service === 'diary' ? `&${date}` : ''));
};
Expand All @@ -67,24 +63,6 @@ export default function SearchForm({ service, onSubmit: handleResults, children
setValue(fieldName, ALL_SELECTED[fieldName]);
};

const { selectedItem: selectedYear, handleSelectedItem: onSelectedYear } = useSelect<number>(
CalendarInstance.currentYear,
);
const { selectedItem: selectedMonth, handleSelectedItem: onSelectedMonth } = useSelect<number>(
CalendarInstance.currentMonth,
);
const { selectedItem: selectedDate, handleSelectedItem: onSelectedDate } = useSelect<number>(
CalendarInstance.currentDate,
);

const onResetToday = () => {
onSelectedYear(CalendarInstance.currentYear);
onSelectedMonth(CalendarInstance.currentMonth);
onSelectedDate(CalendarInstance.currentDate);
};

const yearMonthDate = `${selectedYear}-${(selectedMonth + 1).toString().padStart(2, '0')}-${selectedDate.toString().padStart(2, '0')}`;

if (membersQuery.isPending || petsQuery.isPending) return <p>loading</p>;
if (membersQuery.isError) return <p>Error: {membersQuery.error.message}</p>;
if (petsQuery.isError) return <p>Error: {petsQuery.error.message}</p>;
Expand All @@ -95,46 +73,24 @@ export default function SearchForm({ service, onSubmit: handleResults, children

{children}

{SERVICE_CONFIGS[service].hasCalendar && (
<SearchSection title="날짜">
<div className={styles.dateContainer}>
<Calendar
value={{
year: selectedYear,
month: selectedMonth,
date: selectedDate,
onSelectedYear,
onSelectedMonth,
onSelectedDate,
onResetToday,
}}
>
<Calendar.Year />
<Calendar.Month />
<Calendar.Weekly />
</Calendar>
</div>
</SearchSection>
)}

<SearchSection selectAll={handleClickAll.bind(null, 'pets')} title="반려동물">
<div className={styles.pets}>
{petsQuery.data.map((pet) => (
<SearchPetCheckbox
register={register}
service={service}
pet={pet}
selected={watch('pets')}
key={pet.petId}
/>
<SearchCheckbox register={register} name="pets" value={pet.name} selected={watch('pets')} key={pet.petId} />
))}
</div>
</SearchSection>

<SearchSection selectAll={handleClickAll.bind(null, 'members')} title="작성자 필터">
<SearchSection selectAll={handleClickAll.bind(null, 'members')} title="작성자">
<div className={styles.members}>
{membersQuery.data.members.map((member) => (
<SearchMemberFilter key={member.id} member={member} register={register} selected={watch('members')} />
<SearchCheckbox
key={member.id}
name="members"
value={member.nickname}
register={register}
selected={watch('members')}
/>
))}
</div>
</SearchSection>
Expand Down
43 changes: 33 additions & 10 deletions components/search/search-member-filter.module.scss
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
.member {
background-color: var(--white);
width: fit-content;
padding: 8px;
border: 2px solid var(--pet-border);
border-radius: 9999px;
color: var(--pet-border);
.label {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
}

.imageContainer {
position: relative;
width: 14px;
height: 14px;
border: 2px solid var(--pet-border);
border-radius: 4px;

&.selected {
&:has(.input:checked) {
border: 2px solid var(--main-color);
background-color: var(--main-color);
color: var(--white);
}
}

.checkbox {
.image {
border-radius: 9999px;
}

.input:checked ~ .check {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}

.check {
display: none;
}

.input {
width: 0;
height: 0;
}

.name {
font-weight: 400;
font-size: 12px;
}
22 changes: 13 additions & 9 deletions components/search/search-member-filter.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Member } from '@/api/search/index.type';
import CalendarTodoProfile from '../calendar-monthly/calendar-todo-profile';
import styles from './search-member-filter.module.scss';
import { FieldValues, UseFormRegister } from 'react-hook-form';
import classNames from 'classnames';
import Image from 'next/image';

interface SearchMemberFilterProps {
member: Member;
Expand All @@ -14,13 +13,18 @@ export default function SearchMemberFilter({ member, register, selected }: Searc
const isSelected = selected.includes(member.nickname);

return (
<label
className={classNames(styles.member, {
[styles.selected]: isSelected,
})}
>
<input type="checkbox" value={member.nickname} className={styles.checkbox} {...register('members')} />
<CalendarTodoProfile name={member.nickname} src={member.profileImageUrl} />
<label className={styles.label}>
<div className={styles.imageContainer}>
<input
{...register('members', { validate: (selected: string) => !!selected || '*멤버를 선택해주세요.' })}
value={member.nickname}
className={styles.input}
type="checkbox"
checked={isSelected}
/>
<Image src="/images/search/check.svg" alt="체크 표시" width={8} height={6} className={styles.check} />
</div>
<p className={styles.name}>{member.nickname}</p>
</label>
);
}
15 changes: 8 additions & 7 deletions components/search/search-pet-checkbox.module.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
.petLabel {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
gap: 6px;
cursor: pointer;
}

.petImageContainer {
position: relative;
width: 64px;
height: 64px;
width: 14px;
height: 14px;
border: 2px solid var(--pet-border);
border-radius: 9999px;
border-radius: 4px;

&:has(.petInput:checked) {
border: 2px solid var(--main-color);
background-color: var(--main-color);
}
}

Expand All @@ -25,9 +25,9 @@
.petInput:checked ~ .check {
display: block;
position: absolute;
bottom: 0;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(50%);
transform: translateX(-50%) translateY(-50%);
}

.check {
Expand All @@ -41,4 +41,5 @@

.petName {
font-weight: 400;
font-size: 12px;
}
9 changes: 1 addition & 8 deletions components/search/search-pet-checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,7 @@ export default function SearchPetCheckbox({ register, pet, selected }: SearchPet
type="checkbox"
checked={isSelected}
/>
<Image className={styles.petImage} src={pet.imageUrl} alt="반려동물 프로필 사진" fill />
<Image
src="/images/calendar/check-circle.svg"
alt="체크 표시"
width={20}
height={20}
className={styles.check}
/>
<Image src="/images/search/check.svg" alt="체크 표시" width={8} height={6} className={styles.check} />
</div>
<p className={styles.petName}>{pet.name}</p>
</label>
Expand Down
11 changes: 7 additions & 4 deletions components/search/search-section.module.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
.section {
display: flex;
flex-direction: column;
gap: 16px;
padding: 14px 0;
border-bottom: 1px solid var(--pet-border);
}

.title {
display: flex;
justify-content: space-between;
width: 100%;
flex-shrink: 0;
width: 50px;
font-size: 12px;
font-weight: 700;
cursor: pointer;
}

.selectAll {
Expand Down
7 changes: 1 addition & 6 deletions components/search/search-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@ export default function SearchSection({ children, title, selectAll }: PropsWithC

return (
<div className={styles.section}>
<div className={styles.title}>
<div onClick={handleClick} className={styles.title}>
<p>{title}</p>
{selectAll && (
<p onClick={handleClick} className={styles.selectAll}>
전체 선택
</p>
)}
</div>
{children}
</div>
Expand Down
Loading

0 comments on commit ed21013

Please sign in to comment.