Страница /club (уровни, форма заявки, статус, админ-модерация), /club/gallery (закрытая галерея), /login (кнопка «Войти через Яндекс» + email-вход, разбор #token). Хелперы lib/auth.ts, lib/club.ts, компонент AdminRequests. Ссылки «Клуб»/«Войти» в Nav. Эстетика по существующим токенам (paper/ink/accent, Cormorant/Inter). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
// Типы и API-обёртки закрытого клуба (клиентская сторона).
|
|
'use client';
|
|
|
|
import { authFetch } from './auth';
|
|
|
|
export type ClubTierId =
|
|
| 'vip'
|
|
| 'collector'
|
|
| 'partner'
|
|
| 'photographer'
|
|
| 'organizer'
|
|
| 'press';
|
|
|
|
export interface ClubTier {
|
|
id: ClubTierId;
|
|
title: string;
|
|
desc: string;
|
|
}
|
|
|
|
export type RequestStatus = 'pending' | 'approved' | 'declined';
|
|
|
|
export interface MyAccessRequest {
|
|
id: string;
|
|
tier: ClubTierId;
|
|
status: RequestStatus;
|
|
note: string | null;
|
|
admin_note?: string | null;
|
|
created_at: string;
|
|
reviewed_at?: string | null;
|
|
}
|
|
|
|
export interface AdminAccessRequest extends MyAccessRequest {
|
|
user_id: string;
|
|
user_name: string;
|
|
user_email: string;
|
|
user_avatar: string | null;
|
|
user_current_tier: ClubTierId | null;
|
|
}
|
|
|
|
export const clubApi = {
|
|
tiers: () => authFetch<{ tiers: ClubTier[] }>('/club/tiers').then((r) => r.tiers),
|
|
|
|
myRequest: () =>
|
|
authFetch<{ club_tier: ClubTierId | null; request: MyAccessRequest | null }>(
|
|
'/club/my-request',
|
|
),
|
|
|
|
submit: (tier: ClubTierId, note: string) =>
|
|
authFetch<{ request: MyAccessRequest }>('/club/request', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ tier, note }),
|
|
}),
|
|
|
|
listRequests: (status = 'pending') =>
|
|
authFetch<{ items: AdminAccessRequest[] }>(
|
|
`/club/requests?status=${encodeURIComponent(status)}`,
|
|
).then((r) => r.items),
|
|
|
|
approve: (id: string) =>
|
|
authFetch(`/club/requests/${id}/approve`, { method: 'POST', body: '{}' }),
|
|
|
|
decline: (id: string) =>
|
|
authFetch(`/club/requests/${id}/decline`, { method: 'POST', body: '{}' }),
|
|
};
|