useDonationHub.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. 'use client';
  2. import { useEffect, useRef, useState, useCallback } from 'react';
  3. import * as signalR from '@microsoft/signalr';
  4. import { GoalProgress, CrewRankItem } from '@/types/donation';
  5. /**
  6. * DonationHub 공통 Hook — 목표/순위/크루 위젯에서 공유
  7. */
  8. export function useDonationHub(widgetToken: string, hubUrl: string) {
  9. const connectionRef = useRef<signalR.HubConnection|null>(null);
  10. const [connected, setConnected] = useState(false);
  11. // 목표
  12. const [goalProgress, setGoalProgress] = useState<GoalProgress|null>(null);
  13. // 순위
  14. const [ranking, setRanking] = useState<{ rank: number; sponsorMemberID: number; sponsorName: string; totalAmount: number; donationCount: number }[]>([]);
  15. // 크루
  16. const [crewRanking, setCrewRanking] = useState<CrewRankItem[]>([]);
  17. const [crewTotalAmount, setCrewTotalAmount] = useState(0);
  18. useEffect(() => {
  19. const conn = new signalR.HubConnectionBuilder()
  20. .withUrl(hubUrl)
  21. .withAutomaticReconnect()
  22. .build();
  23. conn.on('ReceiveGoalUpdate', (data: GoalProgress) => {
  24. setGoalProgress(data);
  25. });
  26. conn.on('ReceiveRankUpdate', (data: { list: typeof ranking }) => {
  27. setRanking(data.list);
  28. });
  29. conn.on('ReceiveCrewUpdate', (data: { list: CrewRankItem[]; totalAmount: number }) => {
  30. setCrewRanking(data.list);
  31. setCrewTotalAmount(data.totalAmount);
  32. });
  33. conn.start().then(() => {
  34. conn.invoke('JoinChannel', widgetToken);
  35. setConnected(true);
  36. }).catch(err => console.error('[DonationHub]', err));
  37. conn.onreconnected(() => {
  38. conn.invoke('JoinChannel', widgetToken);
  39. setConnected(true);
  40. });
  41. conn.onclose(() => setConnected(false));
  42. connectionRef.current = conn;
  43. return () => { conn.stop(); };
  44. }, [widgetToken, hubUrl]);
  45. return { connected, goalProgress, setGoalProgress, ranking, setRanking, crewRanking, crewTotalAmount };
  46. }