Skip to content

Commit

Permalink
Merge pull request #219 from depromeet/feat/setting
Browse files Browse the repository at this point in the history
οΏ½feat: setting νŽ˜μ΄μ§€ λ§ˆν¬μ—… 및 κΈ°λŠ₯(λͺ©ν‘œ 거리 μˆ˜μ • / νƒˆν‡΄ / λ‘œκ·Έμ•„μ›ƒ)을 κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.
  • Loading branch information
summermong authored Aug 27, 2024
2 parents 9be0f33 + 92e1503 commit 0890c96
Show file tree
Hide file tree
Showing 34 changed files with 1,019 additions and 19 deletions.
21 changes: 21 additions & 0 deletions app/api/goal/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NextRequest, NextResponse } from 'next/server';

import { fetchData } from '@/apis/fetch-data';

export type goalProps = {
goal: number;
};

export async function PATCH(request: NextRequest) {
try {
const { goal } = (await request.json()) as goalProps;
const data = await fetchData(`/goal`, 'PATCH', { goal });

return NextResponse.json(data);
} catch (error) {
return NextResponse.json(
{ error: 'Failed to update goal' },
{ status: 500 },
);
}
}
12 changes: 12 additions & 0 deletions app/api/logout/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';

import { fetchData } from '@/apis/fetch-data';

export async function GET() {
const data = await fetchData(`/logout`, 'GET');
cookies().delete('accessToken');
cookies().delete('refreshToken');

return NextResponse.json(data);
}
10 changes: 2 additions & 8 deletions app/api/member/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,7 @@ export interface MemberProps {
}

export async function GET() {
try {
const data = await fetchData<MemberProps>('/member', 'GET');
const data = await fetchData<MemberProps>('/member', 'GET');

return NextResponse.json(data);
} catch (error) {
console.error('Error fetching member data:', error);

return NextResponse.error();
}
return NextResponse.json(data);
}
55 changes: 55 additions & 0 deletions app/change-distance/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use client';

import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';

import { LoadingArea } from '@/components/atoms';
import { BackButton, HeaderBar } from '@/components/molecules';
import { useMemberData } from '@/features/setting/apis';
import { SettingCalendar } from '@/features/setting/components';
import { useSaveDialogHandler } from '@/features/setting/hooks';

export default function Page() {
const router = useRouter();
const { data, error } = useMemberData();
const { openSaveModal } = useSaveDialogHandler();

const [selectedDistance, setSelectedDistance] = useState<number | null>(null);

useEffect(() => {
if (data) {
setSelectedDistance(data.data.goal);
}
}, [data]);

if (!data) return <LoadingArea />;
if (error) return console.log(error);

const handleDistanceChange = (distance: number) => {
setSelectedDistance(distance);
};

const backButton = () => {
if (data.data.goal !== selectedDistance) {
openSaveModal();
} else {
router.push('/setting');
}
};

return (
<div>
<HeaderBar>
<HeaderBar.LeftContent>
<BackButton onClickBack={backButton} />
</HeaderBar.LeftContent>
<HeaderBar.Title>기둝 μ‹œκ°ν™” κΈ°μ€€ 거리</HeaderBar.Title>
</HeaderBar>
<SettingCalendar
goal={data.data.goal}
selectedDistance={selectedDistance}
onDistanceChange={handleDistanceChange}
/>
</div>
);
}
51 changes: 51 additions & 0 deletions app/delete-account/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use client';

import { useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';

import { BackButton, HeaderBar } from '@/components/molecules';
import { Step1 } from '@/features/setting/components';
import { Step2 } from '@/features/setting/components';
import { Step3 } from '@/features/setting/components';

export default function Page() {
const router = useRouter();
const searchParams = useSearchParams();
const [step, setStep] = useState(1);

useEffect(() => {
const queryStep = searchParams.get('step');
if (queryStep) {
setStep(Number(queryStep));
}
}, [searchParams]);

const handleListItemClick = () => {
setStep(2);
router.push('?step=2');
};

const getStepComponent = (step: number) => {
switch (step) {
case 1:
return <Step1 onClickListItem={handleListItemClick} />;
case 2:
return <Step2 />;
case 3:
return <Step3 />;
default:
return null;
}
};

return (
<div>
<HeaderBar>
<HeaderBar.LeftContent>
<BackButton />
</HeaderBar.LeftContent>
</HeaderBar>
{getStepComponent(step)}
</div>
);
}
16 changes: 16 additions & 0 deletions app/delete-account/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import dynamic from 'next/dynamic';
import React, { Suspense } from 'react';

import { LoadingArea } from '@/components/atoms';

const StepComponent = dynamic(() => import('./index'), {
suspense: true,
});

export default function Page() {
return (
<Suspense fallback={<LoadingArea />}>
<StepComponent />
</Suspense>
);
}
101 changes: 101 additions & 0 deletions app/setting/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use client';

import { useRouter } from 'next/navigation';

import { LoadingArea } from '@/components/atoms';
import { NormalShapeIcon } from '@/components/atoms';
import { Divider } from '@/components/atoms/divider';
import { BackButton, HeaderBar } from '@/components/molecules';
import { useLogout, useMemberData } from '@/features/setting/apis';
import { ListItem } from '@/features/setting/components';
import { useLogoutDialogHandler } from '@/features/setting/hooks/use-logout-dialog-handler';
import { css } from '@/styled-system/css';
import { flex } from '@/styled-system/patterns';

export default function Page() {
const logout = useLogout();
const router = useRouter();

const { data, isLoading, error } = useMemberData();
const { openLogoutModal } = useLogoutDialogHandler(logout);

if (isLoading) {
return <LoadingArea />;
}

if (error) {
return <div>Error: {error.message}</div>;
}

const handleGoToDeleteAccount = () => {
router.push('/delete-account?step=1');
};

// TODO: κ΄€λ ¨ νŽ˜μ΄μ§€ μž‘μ—… ν•„μš”
const handleGoToSetting = () => {
// console.log('λΌμš°νŒ… 경둜 지정 ν•„μš”');
};

const handleGoToChangeDistance = () => {
router.push('/change-distance');
};

if (isLoading) return <LoadingArea />;
if (error) return console.log(error);

return (
<div>
<HeaderBar>
<HeaderBar.LeftContent>
<BackButton onClickBack={() => router.push('/')} />
</HeaderBar.LeftContent>
<HeaderBar.Title>μ„€μ •</HeaderBar.Title>
</HeaderBar>
<ListItem
text="기둝 μ‹œκ°ν™” κΈ°μ€€ 거리"
subText="달λ ₯ ν•œ 칸에 ν‘œμ‹œλ˜λŠ” μ΅œλŒ€ 수영 거리"
distance={`${data?.data.goal.toLocaleString()}m`}
onClick={handleGoToChangeDistance}
>
<NormalShapeIcon />
</ListItem>
<Divider variant="thick" />
<ListItem text="μ„œλΉ„μŠ€ 이용 μ•½κ΄€" onClick={handleGoToSetting}>
<NormalShapeIcon />
</ListItem>
<ListItem text="κ°œμΈμ •λ³΄ 처리방침" onClick={handleGoToSetting}>
<NormalShapeIcon />
</ListItem>
<ListItem text="μ˜€ν”ˆμ†ŒμŠ€ λΌμ΄μ„ μŠ€" onClick={handleGoToSetting}>
<NormalShapeIcon />
</ListItem>
<Divider variant="thick" />
<ListItem text="λ‘œκ·Έμ•„μ›ƒ" onClick={openLogoutModal}>
<NormalShapeIcon />
</ListItem>
<ListItem text="νƒˆν‡΄ν•˜κΈ°" onClick={handleGoToDeleteAccount}>
<NormalShapeIcon />
</ListItem>
<Divider variant="thick" />
<ListItem text="μŠ€μœ„λ―ΈνŒ€μ—κ²Œ λ¬Έμ˜ν•˜κΈ°" onClick={handleGoToSetting}>
<NormalShapeIcon />
</ListItem>

<div className={dividerStyles}>
<div className={dividerTextStyles}>μ•± 버전 1.1</div>
</div>
</div>
);
}

const dividerStyles = flex({
height: '266px',
backgroundColor: 'line.alternative',
fontWeight: '500',
});

const dividerTextStyles = css({
color: 'text.alternative',
textStyle: 'body2.normal',
padding: '20px 16px',
});
2 changes: 1 addition & 1 deletion components/atoms/button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react';

import { css } from '@/styled-system/css';

import { StatisticsIcon } from '../icons';
import BadgeIcon from '../icons/badge-icon';
import StatisticsIcon from '../icons/statistics-icon';
import { Button } from './button';

const meta: Meta<typeof Button> = {
Expand Down
4 changes: 2 additions & 2 deletions components/atoms/icons/badge-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const BadgeIcon = () => {
export function BadgeIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -13,5 +13,5 @@ const BadgeIcon = () => {
/>
</svg>
);
};
}
export default BadgeIcon;
8 changes: 8 additions & 0 deletions components/atoms/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * from './album-icon';
export * from './apple-logo-icon';
export * from './badge-icon';
export * from './bell-icon';
export * from './camera-icon';
export * from './check-icon';
Expand All @@ -12,19 +14,25 @@ export * from './delete-icon';
export * from './divider-icon';
export { DownArrowIcon } from './down-arrow-icon';
export * from './find-member-icon';
export * from './google-logo-icon';
export * from './kakao-logo-icon';
export { LeftArrowIcon } from './left-arrow-icon';
export * from './loading-button-icon';
export * from './loading-icon';
export * from './logo-icon';
export * from './normal-shape-icon';
export * from './persons-icon';
export * from './search-icon';
export * from './setting-icon';
export * from './speech-bubble-icon';
export * from './star-icon';
export * from './star-icon-fill';
export * from './statistics-icon';
export * from './success-check-icon';
export * from './swim-icon';
export * from './swimmer-icon';
export * from './toast';
export * from './triangle-arrow-icon';
export * from './triangle-arrow-icon-reverse';
export * from './types';
export * from './user-image-icon';
4 changes: 2 additions & 2 deletions components/atoms/icons/loading-button-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const spinAnimation = css({
animation: 'spin 1s linear infinite',
});

export const LoadingButtonIcon = () => {
export function LoadingButtonIcon() {
return (
<svg
width="21"
Expand Down Expand Up @@ -40,4 +40,4 @@ export const LoadingButtonIcon = () => {
</g>
</svg>
);
};
}
20 changes: 20 additions & 0 deletions components/atoms/icons/normal-shape-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export function NormalShapeIcon() {
return (
<svg
width="8"
height="16"
viewBox="0 0 8 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="Shape">
<path
id="Vector"
d="M1.72064 3.05413C1.38218 3.39259 1.38218 3.94133 1.72064 4.27979L5.44114 8.00029L1.72064 11.7208C1.38218 12.0593 1.38218 12.608 1.72064 12.9465C2.05909 13.2849 2.60783 13.2849 2.94629 12.9465L7.27961 8.61312C7.61807 8.27466 7.61807 7.72592 7.27961 7.38747L2.94629 3.05413C2.60783 2.71568 2.05909 2.71568 1.72064 3.05413Z"
fill="#37383C"
fillOpacity="0.61"
/>
</g>
</svg>
);
}
5 changes: 2 additions & 3 deletions components/atoms/icons/statistics-icon.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const StatisticsIcon = () => {
export function StatisticsIcon() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -21,5 +21,4 @@ const StatisticsIcon = () => {
/>
</svg>
);
};
export default StatisticsIcon;
}
2 changes: 1 addition & 1 deletion features/profile/components/organisms/my-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import { useState } from 'react';

import { Button } from '@/components/atoms';
import { StatisticsIcon } from '@/components/atoms';
import BadgeIcon from '@/components/atoms/icons/badge-icon';
import StatisticsIcon from '@/components/atoms/icons/statistics-icon';
import { Tab, TabItem } from '@/components/molecules';
import { css } from '@/styled-system/css';
import { flex } from '@/styled-system/patterns';
Expand Down
Loading

0 comments on commit 0890c96

Please sign in to comment.