layout.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. 'use client';
  2. import './style.scss';
  3. import { useState, useCallback, useEffect } from 'react';
  4. import { fetchApi } from '@/lib/utils/client';
  5. import { useStudioContext } from '@/app/studio/context';
  6. import type { GoalConfigResponse, GoalConfigItem } from '@/types/response/donation/goalConfig';
  7. import { GoalConfigContext } from './context';
  8. export default function GoalLayout({ children }: { children: React.ReactNode }) {
  9. const { channelID } = useStudioContext();
  10. const [items, setItems] = useState<GoalConfigItem[]>([]);
  11. const [loading, setLoading] = useState(true);
  12. const [saving, setSaving] = useState(false);
  13. const fetchList = useCallback(() => {
  14. if (!channelID) {
  15. setLoading(false);
  16. return;
  17. }
  18. setLoading(true);
  19. fetchApi<GoalConfigResponse>(`/api/studio/donation/goal/config/${channelID}`).then(res => {
  20. setItems(res.data?.list ?? []);
  21. }).catch(err => {
  22. alert(err instanceof Error ? err.message : '불러오기 실패');
  23. }).finally(() => setLoading(false));
  24. }, [channelID]);
  25. useEffect(() => {
  26. fetchList();
  27. }, [fetchList]);
  28. if (!channelID) {
  29. return (
  30. <div className="studio-page">
  31. <p className="studio-page__empty">채널을 먼저 연동해 주세요.</p>
  32. </div>
  33. );
  34. }
  35. return (
  36. <GoalConfigContext.Provider value={{ items, loading, saving, setSaving, fetchList }}>
  37. <div className="goal-config">
  38. {children}
  39. </div>
  40. </GoalConfigContext.Provider>
  41. );
  42. }