Skip to content

Commit

Permalink
feat: use input in AgeForm
Browse files Browse the repository at this point in the history
  • Loading branch information
ooooorobo committed Dec 22, 2024
1 parent ab54d61 commit bbf7811
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 29 deletions.
11 changes: 5 additions & 6 deletions src/entities/ideal_partner/model/idealPartnerStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const REQUIRED_OPTION_MAX_COUNT = 3;

export type IdealPartner = {
ageRange?: {
min: number;
max: number;
min?: number;
max?: number;
};
heightRange?: {
min: number;
Expand Down Expand Up @@ -40,6 +40,7 @@ export type IdealPartner = {
};

type Action = {
toggleAge: (on: boolean) => void;
setMinAge: (value: number) => void;
setMaxAge: (value: number) => void;
setMinHeight: (value: number) => void;
Expand All @@ -61,10 +62,8 @@ type Action = {

const createStoreHook = (initialState?: IdealPartner) =>
create<IdealPartner & Action>((set, get) => ({
ageRange: {
min: 20,
max: 30,
},
ageRange: undefined,
toggleAge: (on: boolean) => set({ ageRange: on ? { max: undefined, min: undefined } : undefined }),
setMinAge: (min) => set({ ageRange: { max: 30, ...get().ageRange, min } }),
setMaxAge: (max) => set({ ageRange: { min: 20, ...get().ageRange, max } }),
heightRange: {
Expand Down
23 changes: 23 additions & 0 deletions src/processes/ideal_partner/AgeForm/AgeForm.module.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
.Container {
height: 100%;
}

.AgeDetailWrapper {
margin-left: 32px;
margin-right: 20px;
display: flex;
flex-direction: column;
gap: 8px;

& small {
color: var(--color-neutral-600);
}
}

.AgeInputWrapper {
display: flex;
gap: 8px;
justify-content: stretch;
align-items: center;

& input {
width: 100%
}
}
58 changes: 35 additions & 23 deletions src/processes/ideal_partner/AgeForm/AgeForm.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
import styles from './AgeForm.module.css';
import { useIdealPartnerStore } from 'src/entities/ideal_partner/model/idealPartnerStore';
import { RangeSlider } from 'src/shared/ui/RangeSlider/RangeSlider';
import { useProfileAge } from 'src/entities/profile/lib/useProfileAge';

const AGE_GAP = 20;
const ADULT_AGE = 19;
const MIN_AGE = 15;
import { Radio } from 'src/shared/ui/Radio/Radio';
import { Input } from 'src/shared/ui/Input/Input';
import { ChangeEvent } from 'react';

export const AgeForm = () => {
const age = useProfileAge();
const { min, max } = useIdealPartnerStore((state) => state.ageRange);
const idealPartnerAge = useIdealPartnerStore((state) => state.ageRange);
const { min, max } = idealPartnerAge ?? { min: undefined, max: undefined };

const minAge = Math.max(age >= ADULT_AGE ? Math.max(ADULT_AGE, age - AGE_GAP) : age - AGE_GAP, MIN_AGE);
const maxAge = age <= ADULT_AGE ? Math.min(age + AGE_GAP, ADULT_AGE) : age + AGE_GAP;
const toggleAge = useIdealPartnerStore((state) => state.toggleAge);
const onChangeRadio = (type: boolean) => toggleAge(type);

const setMin = useIdealPartnerStore((state) => state.setMinAge);
const setMax = useIdealPartnerStore((state) => state.setMaxAge);

const onChange = ([min, max]: [number, number]) => {
setMin(min);
setMax(max);
const onChangeMin = (e: ChangeEvent<HTMLInputElement>) => {
if (!isNaN(Number(e.target.value))) {
setMin(Number(e.target.value));
}
};

const onChangeMax = (e: ChangeEvent<HTMLInputElement>) => {
if (!isNaN(Number(e.target.value))) {
setMax(Number(e.target.value));
}
};

return (
<section className={styles.Container}>
<RangeSlider
min={minAge}
max={maxAge}
minLabel={`${min}세`}
maxLabel={`${max}세`}
step={1}
defaultValue={[min, max]}
disabled={false}
onChanged={onChange}
/>
<div>
<Radio
label={'아니요, 나이는 딱히 상관 없어요!'}
checked={!idealPartnerAge}
onChange={() => onChangeRadio(false)}
/>
<Radio label={'네, 있어요!'} checked={Boolean(idealPartnerAge)} onChange={() => onChangeRadio(true)} />
{idealPartnerAge && (
<div className={styles.AgeDetailWrapper}>
<small>선호하는 연령대를 입력해주세요</small>
<div className={styles.AgeInputWrapper}>
<Input placeholder={'최소 나이'} suffixSlot={<span></span>} value={min} onChange={onChangeMin} />
<span>-</span>
<Input placeholder={'최대 나이'} suffixSlot={<span></span>} value={max} onChange={onChangeMax} />
</div>
</div>
)}
</div>
</section>
);
};
3 changes: 3 additions & 0 deletions src/shared/ui/Input/Input.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@
font-size: 16px;
line-height: 16px;
color: var(--color-neutral-900);

display: flex;
align-items: center;
}

0 comments on commit bbf7811

Please sign in to comment.