diff --git a/src/shared/icons/temp_1.svg b/public/icons/temp_1.svg similarity index 100% rename from src/shared/icons/temp_1.svg rename to public/icons/temp_1.svg diff --git a/src/shared/icons/temp_2.svg b/public/icons/temp_2.svg similarity index 100% rename from src/shared/icons/temp_2.svg rename to public/icons/temp_2.svg diff --git a/src/shared/icons/temp_3.svg b/public/icons/temp_3.svg similarity index 100% rename from src/shared/icons/temp_3.svg rename to public/icons/temp_3.svg diff --git a/src/shared/icons/temp_4.svg b/public/icons/temp_4.svg similarity index 100% rename from src/shared/icons/temp_4.svg rename to public/icons/temp_4.svg diff --git a/src/app/(service)/(my)/my-study/page.tsx b/src/app/(service)/(my)/my-study/page.tsx index d728059d..4303b0de 100644 --- a/src/app/(service)/(my)/my-study/page.tsx +++ b/src/app/(service)/(my)/my-study/page.tsx @@ -8,7 +8,7 @@ import { useMemberStudyListQuery } from '@/features/study/group/model/use-member import CompletedGroupStudyList from '@/features/study/group/ui/completed-group-study-list'; import GroupStudyFormModal from '@/features/study/group/ui/group-study-form-modal'; import NotCompletedGroupStudyList from '@/features/study/group/ui/not-completed-group-study-list'; -import { useAuth } from '@/hooks/use-auth'; +import { useAuth } from '@/hooks/common/use-auth'; interface MemberGroupStudyList extends MemberStudyItem { type: 'GROUP_STUDY'; diff --git a/src/app/(service)/layout.tsx b/src/app/(service)/layout.tsx index cd0a8fd7..8954c45e 100644 --- a/src/app/(service)/layout.tsx +++ b/src/app/(service)/layout.tsx @@ -43,11 +43,8 @@ export default function ServiceLayout({
- {/** 1400 + 48*2 패딩 양옆 48로 임의적용 */} -
-
-
{children}
-
+
+
{children}
diff --git a/src/components/card/mission-card.tsx b/src/components/card/mission-card.tsx index 935d455a..a880ece8 100644 --- a/src/components/card/mission-card.tsx +++ b/src/components/card/mission-card.tsx @@ -4,7 +4,8 @@ import { ComponentProps } from 'react'; import { MissionListResponse } from '@/api/openapi/models'; import Badge from '@/components/ui/badge'; import Button from '@/components/ui/button'; -import { useIsLeader } from '@/providers/study-leader-context'; +import { useIsLeader } from '@/stores/useLeaderStore'; +import { useUserStore } from '@/stores/useUserStore'; import DeleteMissionModal from '../modals/delete-mission-modal'; import EditMissionModal from '../modals/edit-mission-modal'; @@ -12,6 +13,7 @@ import { cn } from '../ui/(shadcn)/lib/utils'; interface MissionCardProps { mission: MissionListResponse; + groupStudyId: number; onSelectMission: (missionId: number) => void; showDeadline?: boolean; } @@ -92,10 +94,12 @@ function isCardClickable( export default function MissionCard({ mission, + groupStudyId, onSelectMission, showDeadline = false, }: MissionCardProps) { - const isLeader = useIsLeader(); + const memberId = useUserStore((state) => state.memberId); + const isLeader = useIsLeader(memberId); const statusConfig = mission.status && mission.status in STATUS_CONFIG ? STATUS_CONFIG[mission.status as keyof typeof STATUS_CONFIG] @@ -116,7 +120,7 @@ export default function MissionCard({ // 리더 + 진행 예정: 수정/삭제 버튼만 노출 if (isLeader && mission.status === 'NOT_STARTED') { return ( -
  • +
  • - +
  • ); @@ -147,7 +154,7 @@ export default function MissionCard({ if (isLeader && mission.status === 'ENDED') { return (
  • void; - onDelete?: () => void; } export default function HomeworkDetailContent({ homeworkId, - onEdit, - onDelete, }: HomeworkDetailContentProps) { - const isLeader = useIsLeader(); + const router = useRouter(); + const searchParams = useSearchParams(); const currentUserId = useUserStore((state) => state.memberId); + const isLeader = useIsLeader(currentUserId); const { data: homework, isLoading: isHomeworkLoading } = useGetHomework(homeworkId); - const { mutate: deleteHomework, isPending: isDeleting } = useDeleteHomework(); - const handleDelete = () => { - if (window.confirm('정말 삭제하시겠습니까?')) { - deleteHomework(homeworkId, { - onSuccess: () => { - onDelete?.(); - }, - }); - } + const handleDeleteSuccess = () => { + const params = new URLSearchParams(searchParams.toString()); + params.delete('homeworkId'); + router.push(`?${params.toString()}`); }; if (isHomeworkLoading || !homework) { @@ -99,7 +93,10 @@ export default function HomeworkDetailContent({ attachmentLink: homework.homeworkContent.optionalContent.link, }} /> - + )} diff --git a/src/components/contents/mission-detail-content.tsx b/src/components/contents/mission-detail-content.tsx index 0a3c8cea..2009af0d 100644 --- a/src/components/contents/mission-detail-content.tsx +++ b/src/components/contents/mission-detail-content.tsx @@ -8,7 +8,7 @@ import Avatar from '@/components/ui/avatar'; import Badge from '@/components/ui/badge'; import Progress from '@/components/ui/progress'; import { useGetMission } from '@/hooks/queries/mission-api'; -import { useIsLeader } from '@/providers/study-leader-context'; +import { useIsLeader } from '@/stores/useLeaderStore'; import { useUserStore } from '@/stores/useUserStore'; import MyHomeworkStatus from '../card/my-homework-status-card'; @@ -27,12 +27,10 @@ export default function MissionDetailContent({ groupStudyId, missionId, }: MissionDetailContentProps) { - const isLeader = useIsLeader(); const router = useRouter(); const searchParams = useSearchParams(); const memberId = useUserStore((state) => state.memberId); - - console.log('memberId', memberId); + const isLeader = useIsLeader(memberId); const { data: mission, isLoading } = useGetMission(missionId); @@ -58,8 +56,7 @@ export default function MissionDetailContent({ (mission.maxHomeworkSubmissionCount ?? 1)) * 100; - // TODO: 백엔드에서 MissionResponseDto에 status 필드 추가 후 교체 필요 - const isMissionClosed = true; + const isMissionClosed = mission.status === 'ENDED'; return (
    diff --git a/src/components/contents/payment-page-content.tsx b/src/components/contents/payment-page-content.tsx index b7d1ddc6..15abf023 100644 --- a/src/components/contents/payment-page-content.tsx +++ b/src/components/contents/payment-page-content.tsx @@ -26,6 +26,8 @@ export default function PaymentPageContent({ id }: PaymentPageContentProps) { const data = result.data; + console.log(data); + return (
    @@ -37,6 +39,7 @@ export default function PaymentPageContent({ id }: PaymentPageContentProps) { diff --git a/src/components/layout/sidebar/admin-sidebar.tsx b/src/components/layout/sidebar/admin-sidebar.tsx index 2d2de52a..d41045fb 100644 --- a/src/components/layout/sidebar/admin-sidebar.tsx +++ b/src/components/layout/sidebar/admin-sidebar.tsx @@ -5,7 +5,7 @@ import { usePathname } from 'next/navigation'; import UserAvatar from '@/components/ui/avatar'; import TabMenu from '@/components/ui/tab-menu'; import { useUserProfileQuery } from '@/entities/user/model/use-user-profile-query'; -import { useAuth } from '@/hooks/use-auth'; +import { useAuth } from '@/hooks/common/use-auth'; import OutIcon from 'public/icons/out.svg'; export default function AdminSideBar() { diff --git a/src/components/lists/group-study-list.tsx b/src/components/lists/group-study-list.tsx index 0a431b81..6f724cbb 100644 --- a/src/components/lists/group-study-list.tsx +++ b/src/components/lists/group-study-list.tsx @@ -4,7 +4,7 @@ import { sendGTMEvent } from '@next/third-parties/google'; import Image from 'next/image'; import { GroupStudyListItemDto } from '@/api/openapi'; -import { useAuth } from '@/hooks/use-auth'; +import { useAuth } from '@/hooks/common/use-auth'; import { hashValue } from '@/utils/hash'; import { GroupStudyData } from '../../features/study/group/api/group-study-types'; diff --git a/src/components/lists/study-member-list.tsx b/src/components/lists/study-member-list.tsx index 5caff2ae..6e2f7249 100644 --- a/src/components/lists/study-member-list.tsx +++ b/src/components/lists/study-member-list.tsx @@ -4,9 +4,10 @@ import Image from 'next/image'; import { useState } from 'react'; import { GetGroupStudyMemberStatusResponseContent } from '@/api/openapi'; import Pagination from '@/components/ui/pagination'; +import { useAuth } from '@/hooks/common/use-auth'; import { useGetGroupStudyMembers } from '@/hooks/queries/group-study-member-api'; -import { useAuth } from '@/hooks/use-auth'; import type { GroupStudyMember } from '../../features/study/group/api/group-study-types'; + import GroupStudyMemberItem from '../../features/study/group/ui/group-study-member-item'; import KickedReasonModal from '../../features/study/group/ui/kicked-reason-modal'; @@ -45,7 +46,7 @@ export default function StudyMemberList({ const totalPages = Math.ceil((data?.totalMemberCount || 0) / PAGE_SIZE) || 1; return ( -
    +
    {/* 리더가 아닌 참가자에게 내 정보 상단에 노출 */} {!isLeader && ( void; } // 과제 삭제 모달 export default function DeleteHomeworkModal({ homeworkId, + onSuccess, }: DeleteHomeworkModalProps) { const [open, setOpen] = useState(false); @@ -20,6 +22,7 @@ export default function DeleteHomeworkModal({ onSuccess: () => { alert('과제가 성공적으로 삭제되었습니다!'); setOpen(false); + onSuccess?.(); }, onError: () => { alert('과제 삭제에 실패했습니다. 다시 시도해주세요.'); diff --git a/src/components/modals/delete-mission-modal.tsx b/src/components/modals/delete-mission-modal.tsx index 2d88eb47..82a3ddbe 100644 --- a/src/components/modals/delete-mission-modal.tsx +++ b/src/components/modals/delete-mission-modal.tsx @@ -1,20 +1,41 @@ import { useState } from 'react'; import { MissionListResponse } from '@/api/openapi'; +import { useDeleteMission } from '@/hooks/queries/mission-api'; import Button from '../ui/button'; import { Modal } from '../ui/modal'; interface DeleteMissionModalProps { missionId: MissionListResponse['missionId']; + groupStudyId: number; + onSuccess?: () => void; } // 미션 삭제 모달 export default function DeleteMissionModal({ missionId, + groupStudyId, + onSuccess, }: DeleteMissionModalProps) { const [open, setOpen] = useState(false); - const handleDelete = () => {}; + const { mutate: deleteMission } = useDeleteMission(); + + const handleDelete = () => { + deleteMission( + { missionId, groupStudyId }, + { + onSuccess: () => { + alert('미션이 성공적으로 삭제되었습니다!'); + setOpen(false); + onSuccess?.(); + }, + onError: () => { + alert('미션 삭제에 실패했습니다. 다시 시도해주세요.'); + }, + }, + ); + }; return ( diff --git a/src/components/modals/edit-homework-modal.tsx b/src/components/modals/edit-homework-modal.tsx index f4b2dbaa..9ad0a937 100644 --- a/src/components/modals/edit-homework-modal.tsx +++ b/src/components/modals/edit-homework-modal.tsx @@ -19,13 +19,15 @@ type EditHomeworkFormValues = z.infer; interface EditHomeworkModalProps { defaultValue: EditHomeworkFormValues; - homeworkId: number; // todo api response 타입 적용 + homeworkId: number; + onSuccess?: () => void; } // 과제 수정 모달 export default function EditHomeworkModal({ defaultValue, homeworkId, + onSuccess, }: EditHomeworkModalProps) { const [open, setOpen] = useState(false); @@ -57,6 +59,7 @@ export default function EditHomeworkModal({ defaultValue={defaultValue} homeworkId={homeworkId} onClose={() => setOpen(false)} + onSuccess={onSuccess} /> @@ -68,12 +71,14 @@ interface EditHomeworkFormProps { defaultValue: EditHomeworkFormValues; homeworkId: number; onClose: () => void; + onSuccess?: () => void; } function EditHomeworkForm({ defaultValue, homeworkId, onClose, + onSuccess, }: EditHomeworkFormProps) { const methods = useForm({ resolver: zodResolver(EditHomeworkFormSchema), @@ -101,6 +106,7 @@ function EditHomeworkForm({ onSuccess: async () => { alert('과제가 성공적으로 수정되었습니다!'); onClose(); + onSuccess?.(); }, onError: () => { alert('과제 수정에 실패했습니다. 다시 시도해주세요.'); diff --git a/src/components/pages/group-study-detail-page.tsx b/src/components/pages/group-study-detail-page.tsx index 05efdda2..c79b08f5 100644 --- a/src/components/pages/group-study-detail-page.tsx +++ b/src/components/pages/group-study-detail-page.tsx @@ -2,12 +2,12 @@ import { sendGTMEvent } from '@next/third-parties/google'; import { useRouter, useSearchParams } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import MoreMenu from '@/components/ui/dropdown/more-menu'; import Tabs from '@/components/ui/tabs'; import { STUDY_DETAIL_TABS, StudyTabValue } from '@/config/constants'; import { useGetGroupStudyMyStatus } from '@/hooks/queries/group-study-member-api'; -import { StudyLeaderProvider } from '@/providers/study-leader-context'; +import { useLeaderStore } from '@/stores/useLeaderStore'; import { Leader } from '../../features/study/group/api/group-study-types'; import ChannelSection from '../../features/study/group/channel/ui/channel-section'; @@ -35,6 +35,7 @@ export default function StudyDetailPage({ }: StudyDetailPageProps) { const router = useRouter(); const searchParams = useSearchParams(); + const setLeaderInfo = useLeaderStore((state) => state.setLeaderInfo); const tabFromUrl = searchParams.get('tab') as StudyTabValue | null; @@ -45,6 +46,13 @@ export default function StudyDetailPage({ const isLeader = leaderId === memberId; + // 리더 정보를 Zustand store에 저장 + useEffect(() => { + if (studyDetail?.basicInfo.leader) { + setLeaderInfo(studyDetail.basicInfo.leader as Leader); + } + }, [studyDetail?.basicInfo.leader, setLeaderInfo]); + const [active, setActive] = useState(tabFromUrl || 'intro'); const [showModal, setShowModal] = useState(false); const [action, setAction] = useState(null); @@ -129,104 +137,101 @@ export default function StudyDetailPage({ return
    로딩중...
    ; } - const leaderInfo = studyDetail.basicInfo.leader as Leader; - return ( - -
    - setShowModal(!showModal)} - title={ModalContent[action]?.title} - content={ModalContent[action]?.content} - confirmText={ModalContent[action]?.confirmText} - onConfirm={ModalContent[action]?.onConfirm} - /> - setShowStudyFormModal(!showStudyFormModal)} - /> - -
    -
    -

    - {studyDetail?.detailInfo.title} -

    -

    - {studyDetail?.detailInfo.summary} -

    -
    - {isLeader && ( - { - setShowStudyFormModal(true); - }, +
    + setShowModal(!showModal)} + title={ModalContent[action]?.title} + content={ModalContent[action]?.content} + confirmText={ModalContent[action]?.confirmText} + onConfirm={ModalContent[action]?.onConfirm} + /> + setShowStudyFormModal(!showStudyFormModal)} + /> + +
    +
    +

    + {studyDetail?.detailInfo.title} +

    +

    + {studyDetail?.detailInfo.summary} +

    +
    + {isLeader && ( + { + setShowStudyFormModal(true); }, - { - label: '스터디 종료', - value: 'end', - onMenuClick: () => { - setAction('end'); - setShowModal(true); - }, + }, + { + label: '스터디 종료', + value: 'end', + onMenuClick: () => { + setAction('end'); + setShowModal(true); }, - { - label: '스터디 삭제', - value: 'delete', - onMenuClick: () => { - setAction('delete'); - setShowModal(true); - }, + }, + { + label: '스터디 삭제', + value: 'delete', + onMenuClick: () => { + setAction('delete'); + setShowModal(true); }, - ]} - iconSize={35} - /> - )} -
    - - {/** 탭리스트 */} - tab.value === 'intro' || isLeader || isMember, - )} - activeTab={active} - onChange={(value: StudyTabValue) => { - setActive(value); - - // 탭 변경 시 URL 파라미터 초기화 및 탭 값 설정 - router.replace(`?tab=${value}`); - - sendGTMEvent({ - event: 'group_study_tab_change', - group_study_id: String(groupStudyId), - tab: value, - }); - }} - /> - {active === 'intro' && } - {active === 'members' && ( - )} +
    - {active === 'mission' && } - {active === 'channel' && ( - + {/** 탭리스트 */} + tab.value === 'intro' || isLeader || isMember, )} -
    - + activeTab={active} + onChange={(value: StudyTabValue) => { + setActive(value); + + // 탭 변경 시 URL 파라미터 초기화 및 탭 값 설정 + router.replace(`?tab=${value}`); + + sendGTMEvent({ + event: 'group_study_tab_change', + group_study_id: String(groupStudyId), + tab: value, + }); + }} + /> + {active === 'intro' && } + {active === 'members' && ( + + )} + + {active === 'mission' && } + {active === 'channel' && ( + + )} +
    ); } diff --git a/src/components/pages/premium-study-detail-page.tsx b/src/components/pages/premium-study-detail-page.tsx index dd2cec12..cac6719d 100644 --- a/src/components/pages/premium-study-detail-page.tsx +++ b/src/components/pages/premium-study-detail-page.tsx @@ -2,7 +2,7 @@ import { sendGTMEvent } from '@next/third-parties/google'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import MoreMenu from '@/components/ui/dropdown/more-menu'; import Tabs from '@/components/ui/tabs'; import { STUDY_DETAIL_TABS, StudyTabValue } from '@/config/constants'; @@ -11,7 +11,7 @@ import { Leader, } from '@/features/study/group/api/group-study-types'; import { useGetGroupStudyMyStatus } from '@/hooks/queries/group-study-member-api'; -import { StudyLeaderProvider } from '@/providers/study-leader-context'; +import { useLeaderStore } from '@/stores/useLeaderStore'; import ChannelSection from '../../features/study/group/channel/ui/channel-section'; import { useCompleteGroupStudyMutation, @@ -38,6 +38,7 @@ export default function PremiumStudyDetailPage({ const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); + const setLeaderInfo = useLeaderStore((state) => state.setLeaderInfo); const activeTab = (searchParams.get('tab') as StudyTabValue) || 'intro'; @@ -47,6 +48,13 @@ export default function PremiumStudyDetailPage({ const leaderId = studyDetail?.basicInfo.leader.memberId; const isLeader = leaderId === memberId; + + // 리더 정보를 Zustand store에 저장 + useEffect(() => { + if (studyDetail?.basicInfo.leader) { + setLeaderInfo(studyDetail.basicInfo.leader as Leader); + } + }, [studyDetail?.basicInfo.leader, setLeaderInfo]); const [showModal, setShowModal] = useState(false); const [action, setAction] = useState(null); const [showStudyFormModal, setShowStudyFormModal] = useState(false); @@ -130,108 +138,105 @@ export default function PremiumStudyDetailPage({ return
    로딩중...
    ; } - const leaderInfo = studyDetail.basicInfo.leader as Leader; - return ( - -
    - setShowModal(!showModal)} - title={ModalContent[action]?.title} - content={ModalContent[action]?.content} - confirmText={ModalContent[action]?.confirmText} - onConfirm={ModalContent[action]?.onConfirm} - /> - setShowStudyFormModal(!showStudyFormModal)} - /> - -
    -
    -

    - {studyDetail?.detailInfo.title} -

    -

    - {studyDetail?.detailInfo.summary} -

    -
    - {isLeader && ( - { - setShowStudyFormModal(true); - }, +
    + setShowModal(!showModal)} + title={ModalContent[action]?.title} + content={ModalContent[action]?.content} + confirmText={ModalContent[action]?.confirmText} + onConfirm={ModalContent[action]?.onConfirm} + /> + setShowStudyFormModal(!showStudyFormModal)} + /> + +
    +
    +

    + {studyDetail?.detailInfo.title} +

    +

    + {studyDetail?.detailInfo.summary} +

    +
    + {isLeader && ( + { + setShowStudyFormModal(true); }, - { - label: '스터디 종료', - value: 'end', - onMenuClick: () => { - setAction('end'); - setShowModal(true); - }, + }, + { + label: '스터디 종료', + value: 'end', + onMenuClick: () => { + setAction('end'); + setShowModal(true); }, - { - label: '스터디 삭제', - value: 'delete', - onMenuClick: () => { - setAction('delete'); - setShowModal(true); - }, + }, + { + label: '스터디 삭제', + value: 'delete', + onMenuClick: () => { + setAction('delete'); + setShowModal(true); }, - ]} - iconSize={35} - /> - )} -
    - - {/** 탭리스트 */} - tab.value === 'intro' || isLeader || isMember, - )} - activeTab={activeTab} - onChange={(value: StudyTabValue) => { - const params = new URLSearchParams(searchParams.toString()); - params.set('tab', value); - router.push(`${pathname}?${params.toString()}`, { scroll: false }); - sendGTMEvent({ - event: 'premium_study_tab_change', - group_study_id: String(groupStudyId), - tab: value, - }); - }} - /> - {activeTab === 'intro' && ( - - )} - {activeTab === 'members' && ( - - )} - {activeTab === 'mission' && ( - - )} - {activeTab === 'channel' && ( - )}
    - + + {/** 탭리스트 */} + tab.value === 'intro' || isLeader || isMember, + )} + activeTab={activeTab} + onChange={(value: StudyTabValue) => { + const params = new URLSearchParams(searchParams.toString()); + params.set('tab', value); + router.push(`${pathname}?${params.toString()}`, { scroll: false }); + sendGTMEvent({ + event: 'premium_study_tab_change', + group_study_id: String(groupStudyId), + tab: value, + }); + }} + /> + {activeTab === 'intro' && ( + + )} + {activeTab === 'members' && ( + + )} + {activeTab === 'mission' && ( + + )} + {activeTab === 'channel' && ( + + )} +
    ); } diff --git a/src/components/payment/paymentActionClient.tsx b/src/components/payment/paymentActionClient.tsx index 682a92c3..0d863c66 100644 --- a/src/components/payment/paymentActionClient.tsx +++ b/src/components/payment/paymentActionClient.tsx @@ -29,7 +29,7 @@ export default function PaymentCheckoutPage({ study }: Props) { const [paymentMethod, setPaymentMethod] = useState('CARD'); - const canPay = isAgreed && !!paymentMethod && !!payment && !isLoading; + const canPay = isAgreed && !!paymentMethod && !isLoading; const toggleTerm = () => { setIsAgreed((prev) => !prev); diff --git a/src/components/premium/premium-study-list.tsx b/src/components/premium/premium-study-list.tsx index f07c4345..5ccb546b 100644 --- a/src/components/premium/premium-study-list.tsx +++ b/src/components/premium/premium-study-list.tsx @@ -5,7 +5,7 @@ import Image from 'next/image'; import { GroupStudyListItemDto } from '@/api/openapi'; import { GroupStudyData } from '@/features/study/group/api/group-study-types'; -import { useAuth } from '@/hooks/use-auth'; +import { useAuth } from '@/hooks/common/use-auth'; import { hashValue } from '@/utils/hash'; import StudyCard from '../card/study-card'; diff --git a/src/components/section/group-study-info-section.tsx b/src/components/section/group-study-info-section.tsx index d6ef1046..3356c01c 100644 --- a/src/components/section/group-study-info-section.tsx +++ b/src/components/section/group-study-info-section.tsx @@ -10,8 +10,9 @@ import Button from '@/components/ui/button'; import { getSincerityPresetByLevelName } from '@/config/sincerity-temp-presets'; import UserProfileModal from '@/entities/user/ui/user-profile-modal'; import { useApplicantsByStatusQuery } from '@/features/study/group/application/model/use-applicant-qeury'; -import { useAuth } from '@/hooks/use-auth'; -import { useIsLeader } from '@/providers/study-leader-context'; +import { useAuth } from '@/hooks/common/use-auth'; +import { useIsLeader } from '@/stores/useLeaderStore'; +import { useUserStore } from '@/stores/useUserStore'; import { hashValue } from '@/utils/hash'; import SummaryStudyInfo from '../summary/study-info-summary'; @@ -23,10 +24,11 @@ interface StudyInfoSectionProps { export default function StudyInfoSection({ study: studyDetail, }: StudyInfoSectionProps) { - const isLeader = useIsLeader(); const router = useRouter(); const params = useParams(); const { data: authData } = useAuth(); + const memberId = useUserStore((state) => state.memberId); + const isLeader = useIsLeader(memberId); const groupStudyId = Number(params.id); @@ -42,7 +44,7 @@ export default function StudyInfoSection({ return ( // todo: 스터디 공지 모달 추가 // -
    +
    state.memberId); + const isLeader = useIsLeader(memberId); const [filter, setFilter] = useState('all'); const missionId = searchParams.get('missionId'); @@ -154,37 +156,40 @@ export default function MissionSection({ groupStudyId }: MissionSectionProps) { // 미션 목록 (기본) return ( -
    -
    - 미션 목록 - {isLeader && } -
    +
    +
    +
    + 미션 목록 + {isLeader && } +
    - - - {hasMissions ? ( -
      - {filteredMissions.map((mission) => ( - - ))} -
    - ) : ( - - )} + + + {hasMissions ? ( +
      + {filteredMissions.map((mission) => ( + + ))} +
    + ) : ( + + )} +
    ); } @@ -209,7 +214,7 @@ function MissionFilterTabs({ ]; return ( -
    +
    {tabs.map((tab) => (