Skip to content
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
1f90c39
Style : placement
heewls May 24, 2025
704e90e
Feat : 비밀번호 변경 시 토큰 삭제 및 로그인 페이지 리다이렉트 처리
hhjin1 May 25, 2025
092e27b
Fix : 24hour
heewls May 25, 2025
728efb5
Fix : 5/23코드로 리셋
hhjin1 May 25, 2025
7c35bc7
Style : 글쓰기 버튼 위치 수정
hhjin1 May 25, 2025
6fea4a0
Fix : nogroup 페이지 loading.tsx 삭제
KSJ27 May 25, 2025
4f2422b
Fix : 홈페이지 첫번째 기능 설명 카드 모바일 상단 패딩 추가
KSJ27 May 25, 2025
b6d15c5
Style : 마이 히스토리 페이지 height 수정
May 25, 2025
9427d33
Feat : 비밀번호 변경 전 본인 인증 기능 추가
hhjin1 May 25, 2025
055814a
Stlyle : list-page 할일이 없을때 높이 수정
May 25, 2025
d372b6f
Feat : 비밀번호 인풋에 Enter키를 눌러도 요청이 실행되도록 기능추가
hhjin1 May 25, 2025
a1c5046
Style : 스켈레톤 스타일 수정
May 25, 2025
82c2538
Style : 비밀번호 변경 성공 토스트문구 수정
hhjin1 May 25, 2025
b720a44
Style : OAuth 페이지 스타일 수정
May 25, 2025
0721b82
Merge pull request #158 from FE-team1/feature/articles/page
hhjin1 May 25, 2025
767930c
Merge branch 'dev' into fix/nogroup
KSJ27 May 25, 2025
c7b114b
Merge pull request #159 from FE-team1/fix/nogroup
KSJ27 May 25, 2025
0c2328b
Merge branch 'dev' of https://github.com/FE-team1/coworkers into refa…
May 25, 2025
a29d0d9
Merge pull request #160 from FE-team1/Refactor/mid-cleanup
grimza99 May 25, 2025
0880e6b
Fix : 그룹 생성/수정/삭제와 드롭다운이 안보이던 문제 해결
hhjin1 May 25, 2025
67f0aca
Merge branch 'dev' of https://github.com/FE-team1/coworkers into refa…
heewls May 25, 2025
1a92d60
Feat : nearest time
heewls May 25, 2025
9aedca7
Fix : delete group modal id
heewls May 25, 2025
276f406
Fix : StartButton에 toSorted 추가
hhjin1 May 25, 2025
535a013
detailArticleInfo에 Image object-cover 추가
hhjin1 May 25, 2025
e1b0bd4
Refactor : 비밀번호 변경 시 쿠키 삭제 후 UserContext 상태 초기화
hhjin1 May 25, 2025
2a33d98
Style : skeleton에 애니메이션효과 추가
hhjin1 May 25, 2025
468eeb5
Merge pull request #162 from FE-team1/refactor/manage-task-team
heewls May 25, 2025
7463e65
Refactor : add isPending
heewls May 25, 2025
cbbf246
Style : 카드 컴포넌트 제목 스타일 변경
hhjin1 May 25, 2025
cb48e5d
Merge pull request #161 from FE-team1/feature/mypage
hhjin1 May 25, 2025
b907ba9
Fix : 회원가입 시 이메일·닉네임 중복 에러 메시지 입력 시 초기화 처리
hhjin1 May 25, 2025
9531056
Merge branch 'dev' of https://github.com/FE-team1/coworkers into gnb
hhjin1 May 25, 2025
c2eeced
Merge pull request #163 from FE-team1/gnb
hhjin1 May 25, 2025
9709c01
Refactor : JoinGroup 페이지에서 localStorage 대신 UserContext 사용
hhjin1 May 25, 2025
ef3c5fa
Merge pull request #165 from FE-team1/feature/join
hhjin1 May 25, 2025
e9357dd
Merge branch 'dev' of https://github.com/FE-team1/coworkers into refa…
heewls May 25, 2025
90efed0
Merge pull request #164 from FE-team1/refactor/manage-group
heewls May 25, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,40 @@ import BouncingDots from '@/components/common/loading/BouncingDots';
import useModalContext from '@/components/common/modal/core/useModalContext';
import TrashCan from '@/assets/TrashCan';
import { deleteGroup } from '../action';

const DELETE_MODAL_ID = 'delete-group';
import { useUser } from '@/contexts/UserContext';

export default function DeleteGroupButton({ groupId }: { groupId: number }) {
const [isPending, setIsPending] = useState(false);
const { openModal } = useModalContext();
const { fetchUser } = useUser();
const router = useRouter();

const handleDeleteGroup = () => {
setIsPending(true);

deleteGroup(groupId)
.then(() => {
fetchUser();
Toast.success('팀 삭제 성공');
router.push('/');
})
.catch(() => Toast.error('팀 삭제 실패'))
.finally(() => setIsPending(false));
};

const deleteModalId = `delete-group-${groupId}`;

return (
<>
<button
onClick={() => openModal(DELETE_MODAL_ID)}
onClick={() => openModal(deleteModalId)}
className="text-danger text-lg-md flex w-fit cursor-pointer items-center justify-start gap-2"
>
<TrashCan />
<span>팀 삭제하기</span>
</button>
<DangerModal
modalId={DELETE_MODAL_ID}
modalId={deleteModalId}
heading="팀 삭제를 진행하시겠어요?"
confirmButton={isPending ? <BouncingDots /> : '삭제하기'}
onConfirm={handleDeleteGroup}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export function DateSkeleton() {
return (
<section className="flex items-center gap-3">
<div className="bg-gray200 h-6 w-24 rounded-md" />
<div className="bg-bg200 h-6 w-24 rounded-md" />
<div className="flex gap-1">
<div className="bg-gray200 h-4 w-4 rounded" />
<div className="bg-gray200 h-4 w-4 rounded" />
<div className="bg-bg200 h-4 w-4 rounded" />
<div className="bg-bg200 h-4 w-4 rounded" />
</div>
<div className="bg-gray200 h-6 w-6 rounded" />
<div className="bg-bg200 h-6 w-6 rounded" />
</section>
);
}
Expand All @@ -16,7 +16,7 @@ export function TaskListsSkeleton() {
<section>
<ol className="flex h-fit max-w-full gap-3 overflow-x-auto overflow-y-hidden">
{[...Array(4)].map((_, i) => (
<li key={i} className="bg-gray200 h-6 w-20 shrink-0 rounded" />
<li key={i} className="bg-bg200 h-6 w-20 shrink-0 rounded" />
))}
</ol>
</section>
Expand All @@ -29,7 +29,7 @@ export function TaskSkeleton() {
<div className="mb-20 flex h-full w-full flex-col items-center justify-start overflow-auto lg:mb-30 xl:mb-50">
<ol className="flex h-full w-full flex-col gap-4">
{[...Array(5)].map((_, i) => (
<li key={i} className="bg-gray200 h-24 w-full rounded-lg" />
<li key={i} className="bg-bg200 h-24 w-full rounded-lg" />
))}
</ol>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function Tasks({ groupId, tasks, currentTaskList }: Props) {
</SortableContext>
</DndContext>
) : (
<div className="flex h-200 items-center justify-center">
<div className="flex h-full items-center justify-center">
<p className="text-md-md text-gray500">
아직 할 일이 없습니다.
<br />할 일을 추가 해보세요.
Expand Down
4 changes: 2 additions & 2 deletions src/app/(content-layout)/articles/ArticlesPageClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export default function ArticlesPageClient() {
key={article.id}
{...article}
title={
article.title.length > 30 ? article.title.slice(0, 30) + '...' : article.title
article.title.length > 50 ? article.title.slice(0, 50) + '...' : article.title
}
/>
))}
Expand All @@ -203,7 +203,7 @@ export default function ArticlesPageClient() {

<Button
onClick={() => router.push(`${PATHS.ARTICLES.NEW}`)}
className="fixed right-6 bottom-6 gap-1"
className="text-lg-semi bg-primary fixed right-1/20 bottom-5.5 flex h-12 w-[125px] items-center justify-center rounded-[40px] text-white md:bottom-6 lg:right-1/10 lg:bottom-15"
>
<Image width={16} height={16} alt="게시글 추가버튼" src="/icons/plus.svg" /> 글쓰기
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default function DetailArticleInfo({ detail }: { detail: GetArticleDetail
<div className="flex w-full flex-col items-center gap-6 md:flex-row md:items-start">
{detail.image && detail.image !== DEFAULT_IMAGE && (
<div className="relative aspect-[1/1] w-full max-w-125 items-center overflow-hidden rounded-2xl md:h-100 md:w-100">
<Image fill src={detail.image} alt="article-image" />
<Image fill src={detail.image} alt="article-image" className="object-cover" />
</div>
)}
<div className="flex w-full flex-1 flex-col gap-12">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function Card(props: Article) {
<div className="border-bg100 bg-bg200 flex h-44 w-full flex-col gap-6 rounded-lg border px-7 py-6">
<Link href={`/articles/${props.id}`}>
<div className="flex justify-between">
<h3 className="text-2lg-md text-gray300 max-w-75 truncate">{title}</h3>
<h3 className="text-2lg-md text-gray300 max-w-80">{title}</h3>

<div className="relative flex h-16 w-16 shrink-0 items-start overflow-hidden rounded-md md:h-18 md:w-18">
{image && image !== DEFAULT_IMAGE && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ export function BestCardSkeleton() {
return (
<section className="space-y-6">
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
<div className="bg-bg200 block h-45 rounded-lg md:h-55" />
<div className="bg-bg200 hidden h-55 rounded-lg md:block" />
<div className="bg-bg200 hidden h-55 rounded-lg lg:block" />
<div className="bg-bg200 block h-45 animate-pulse rounded-lg md:h-55" />
<div className="bg-bg200 hidden h-55 animate-pulse rounded-lg md:block" />
<div className="bg-bg200 hidden h-55 animate-pulse rounded-lg lg:block" />
</div>
</section>
);
Expand All @@ -15,7 +15,7 @@ export function CardSkeleton() {
<section className="space-y-6">
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="bg-bg200 h-44 rounded-lg" />
<div key={i} className="bg-bg200 h-44 animate-pulse rounded-lg" />
))}
</div>
</section>
Expand Down
4 changes: 2 additions & 2 deletions src/app/(content-layout)/myhistory/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ export default async function MyHistoryPage() {
{historyTasks.tasksDone.length > 0 ? (
<GroupedByDateTaskList historyTaskData={historyTasks.tasksDone} />
) : (
<div className="flex h-svh w-full items-center justify-center">
<div className="flex h-full w-full items-center justify-center">
<p className="text-md-md text-gray500">아직 히스토리가 없습니다.</p>
</div>
)}
</>
);
} catch {
return (
<div className="flex h-svh w-full items-center justify-center">
<div className="flex h-full w-full items-center justify-center">
<p className="text-md-md text-gray500">데이터를 불러오는데 실패했습니다.</p>
</div>
);
Expand Down
17 changes: 0 additions & 17 deletions src/app/(content-layout)/nogroup/loading.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/app/(form-layout)/joingroup/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import axiosClient from '@/lib/axiosClient';
import Button from '@/components/common/Button';
import FormField from '@/components/common/formField';
import { Toast } from '@/components/common/Toastify';
import { useUser } from '@/contexts/UserContext';

export default function JoinGroup() {
const [inviteLink, setInviteLink] = useState('');
const router = useRouter();
const { email: userEmail } = useUser();

const handleJoin = async (e: React.FormEvent) => {
e.preventDefault();
const token = inviteLink.trim();
const userEmail = localStorage.getItem('userEmail') ?? '';
try {
const response = await axiosClient.post('/groups/accept-invitation', {
userEmail,
Expand Down
11 changes: 8 additions & 3 deletions src/app/(form-layout)/signup/_signup/SignupForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,14 @@ export default function SignupForm() {
isFailure={field.isFailure}
errorMessage={field.errorMessage}
value={formData[field.name as keyof typeof formData]}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setFieldValue(field.name as keyof typeof formData, e.target.value)
}
onChange={(e: ChangeEvent<HTMLInputElement>) => {
const key = field.name as keyof typeof formData;
setFieldValue(key, e.target.value);

if (key === 'email' || key === 'nickname') {
setDuplicateError((prev) => ({ ...prev, [key]: false }));
}
}}
placeholder={field.placeholder}
rightSlot={field.rightSlot}
/>
Expand Down
5 changes: 4 additions & 1 deletion src/app/_home/StartButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export default function StartButton({
} else if (memberships.length === 0) {
determinedHref = PATHS.NOGROUP;
} else if (memberships[0].group.id) {
determinedHref = PATHS.getGroupPath(memberships[0].group.id);
const sortedGroups = memberships
.map((m) => m.group)
.toSorted((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
determinedHref = PATHS.getGroupPath(sortedGroups[0].id);
} else {
determinedHref = PATHS.LOGIN;
}
Expand Down
13 changes: 11 additions & 2 deletions src/app/mypage/MypageClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import Image from 'next/image';
import { useState, useEffect } from 'react';
import { updateUserNickname } from './_mypage/action';
import { updateUserNickname, verifyPassword } from './_mypage/action';
import ProfileImageUploader from './_mypage/ProfileImageUploader';
import NicknameField from './_mypage/NicknameField';
import PasswordField from './_mypage/PasswordField';
Expand Down Expand Up @@ -79,7 +79,16 @@ export default function MyPageClient() {
<PasswordField
password={password}
setPassword={setPassword}
onClick={() => openModal('change-password')}
onClick={async () => {
try {
const res = await verifyPassword(email!, password);
if (res?.accessToken) {
openModal('change-password');
}
} catch (e) {
Toast.error('비밀번호 인증 실패');
}
}}
/>
<button
type="button"
Expand Down
7 changes: 7 additions & 0 deletions src/app/mypage/_mypage/PasswordField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ export default function PasswordField({ password, setPassword, onClick }: Passwo
field="input"
type="password"
label="비밀번호"
placeholder="비밀번호를 입력해 주세요."
value={password}
onChange={(e) => setPassword(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
onClick();
}
}}
rightSlot={
<div className="flex items-center">
<Button size="xs" fontSize="14" className="shrink-0" onClick={onClick}>
Expand Down
10 changes: 10 additions & 0 deletions src/app/mypage/_mypage/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ export async function updateUserPassword(password: string, passwordConfirmation:
throw new Error('비밀번호 변경 실패');
}
}

export async function verifyPassword(email: string, password: string) {
try {
const res = await axiosServer.post('/auth/signIn', { email, password });
return res.data;
} catch (e) {
console.error('비밀번호 인증 실패:', e);
throw new Error('비밀번호 인증 실패');
}
}
12 changes: 11 additions & 1 deletion src/app/mypage/_mypage/mypage-modal/ChangePasswordModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { useState, useTransition } from 'react';
import { useRouter } from 'next/navigation';
import {
ModalContainer,
ModalFooter,
Expand All @@ -17,13 +18,18 @@ import { AUTH_ERROR_MESSAGES } from '@/constants/messages/signup';
import { Toast } from '@/components/common/Toastify';
import { updateUserPassword } from '../action';
import BouncingDots from '@/components/common/loading/BouncingDots';
import { deleteClientCookie } from '@/lib/cookie/client';
import { useUser } from '@/contexts/UserContext';

interface PasswordChangeSuccessModalProps {
onClose: () => void;
}

export default function ChangePasswordModal({ onClose }: PasswordChangeSuccessModalProps) {
const { closeModal } = useModalContext();
const router = useRouter();
const [isPending, startTransition] = useTransition();
const { logoutUser } = useUser();
const INITIAL_FORM_DATA = {
newPassword: '',
confirmPassword: '',
Expand Down Expand Up @@ -54,11 +60,15 @@ export default function ChangePasswordModal({ onClose }: PasswordChangeSuccessMo
try {
await updateUserPassword(formData.newPassword, formData.confirmPassword);

deleteClientCookie('accessToken');
deleteClientCookie('refreshToken');
await logoutUser();

setFormData(INITIAL_FORM_DATA);

closeModal('change-password');
Toast.success('비밀번호 변경 성공');
onClose();
router.replace('/login?from=password-change');
} catch {
Toast.error('비밀번호 변경 실패');
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/oauth/kakao/_kakao/OAuthClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function OAuthClient() {
}, [oauthRequest]);

return (
<div className="flex h-full w-full items-center justify-center pt-100">
<div className="flex h-full w-full items-center justify-center">
<BouncingDots />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/oauth/kakao/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Spinner from '@/components/common/loading/Spinner';

export default async function OAuthPage() {
return (
<Suspense fallback={<Spinner className="text-4xl" />}>
<Suspense fallback={<Spinner className="text-primary" />}>
<OAuthClient />
</Suspense>
);
Expand Down
4 changes: 2 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ export default function Home() {
>
<div
className={clsx(
'bg-bg300 size-full, flex h-full flex-col items-start gap-10 rounded-[40px] px-13.5',
'md:flex-row-reverse md:items-center md:justify-between md:px-[121.5px]',
'bg-bg300 size-full, flex h-full flex-col items-start gap-10 rounded-[40px] px-13.5 pt-12',
'md:flex-row-reverse md:items-center md:justify-between md:px-[121.5px] md:pt-0',
'lg:px-[181px]'
)}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/comment/CommentItemDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function CommentItemDropdown({
}
options={ITEM_DROPDOWN_VALUE}
onSelect={handleClickDropdownOption}
placement="top-6 right-[14px]"
placement="top-5 right-[10px]"
/>
)
);
Expand Down
Loading