| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- 'use client';
- import './style.scss';
- import { useState } from 'react';
- import { useRouter } from 'next/navigation';
- import { fetchApi } from '@/lib/utils/client';
- import { Button } from '@/components/ui/button';
- import { Input } from '@/components/ui/input';
- import { Label } from '@/components/ui/label';
- import { Checkbox } from '@/components/ui/checkbox';
- export default function CrewJoinPage()
- {
- const router = useRouter();
- const [inviteCode, setInviteCode] = useState('');
- const [nickname, setNickname] = useState('');
- const [consent, setConsent] = useState(false);
- const [processing, setProcessing] = useState(false);
- const [done, setDone] = useState<string|null>(null);
- const handleJoin = async () => {
- if (processing) {
- return;
- }
- if (!inviteCode.trim()) {
- alert('초대 코드를 입력해 주세요.');
- return;
- }
- if (!nickname.trim()) {
- alert('크루 안에서 사용할 별명을 입력해 주세요.');
- return;
- }
- if (!consent) {
- alert('크루 방송 합류 동의가 필요합니다.');
- return;
- }
- setProcessing(true);
- try {
- const res = await fetchApi<{ crewMemberID: number; crewName: string }>('/api/crew/join', {
- method: 'POST',
- body: { inviteCode: inviteCode.trim(), nickname: nickname.trim() }
- });
- setDone(res.data?.crewName ?? '크루');
- } catch (err) {
- alert(err instanceof Error ? err.message : '가입에 실패했습니다.');
- } finally {
- setProcessing(false);
- }
- };
- if (done) {
- return (
- <div className="crew-join-page">
- <h1 className="crew-join-page__title">✅ 크루 가입이 완료되었습니다</h1>
- <p className="crew-join-page__desc">
- <strong>{done}</strong> 크루의 크루원으로 등록되었습니다.<br />
- 이제 해당 크리에이터의 크루 방송에 참여하실 수 있습니다.
- </p>
- <Button type="button" onClick={() => router.push('/')}>홈으로</Button>
- </div>
- );
- }
- return (
- <div className="crew-join-page">
- <h1 className="crew-join-page__title">크루 합류</h1>
- <p className="crew-join-page__desc">
- 크리에이터로부터 받은 <strong>초대 코드</strong>를 입력해 크루에 합류합니다.<br />
- 코드 입력 시 해당 크리에이터의 <strong>크루 방송 합류에 동의</strong>하는 것으로 처리됩니다.
- </p>
- <div className="crew-join-page__form">
- <div className="crew-join-page__field">
- <Label htmlFor="invite-code">초대 코드</Label>
- <Input
- id="invite-code"
- value={inviteCode}
- onChange={e => setInviteCode(e.target.value)}
- placeholder="발급받은 초대 코드를 붙여 넣어 주세요"
- autoComplete="off"
- />
- </div>
- <div className="crew-join-page__field">
- <Label htmlFor="nickname">크루 내 별명</Label>
- <Input
- id="nickname"
- value={nickname}
- onChange={e => setNickname(e.target.value)}
- placeholder="크루 안에서 사용할 별명"
- maxLength={80}
- />
- </div>
- <label className="crew-join-page__consent" htmlFor="consent">
- <Checkbox id="consent" checked={consent} onCheckedChange={v => setConsent(!!v)} />
- <span>크루 방송 합류에 동의합니다.</span>
- </label>
- </div>
- <div className="crew-join-page__actions">
- <Button type="button" variant="outline" onClick={() => router.push('/')}>취소</Button>
- <Button type="button" onClick={handleJoin} disabled={processing}>
- {processing ? '처리 중...' : '합류'}
- </Button>
- </div>
- </div>
- );
- }
|