79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
/*
|
|
* 역할별 랜딩·트랙 판정 (모바일) — 웹 src/frontend/src/lib/roleTrack.ts 로직 이식(패리티).
|
|
* 우선순위: admin > ops > business > agency > visitor. 판정 불가 시 visitor(관람객) 기본.
|
|
*
|
|
* 웹과의 차이(모바일 계약 적응):
|
|
* · roleCode는 공유 백엔드 /api/auth/login 이 웹과 동일하게 반환한다(AuthUser.roleCode).
|
|
* roleCode('ADMIN'/'MANAGER')를 우선 사용하고, 누락 시 hallManager=true를 ops 신호로 폴백한다.
|
|
* · 랜딩 경로는 웹 라우트(/admin·/contractor/dashboard·/visitor·/home) 대신 모바일 라우트로 매핑.
|
|
*/
|
|
import type { AuthUser, EventRole, WorkspaceDto } from './types';
|
|
|
|
export type Track = 'visitor' | 'business' | 'agency' | 'ops' | 'admin';
|
|
|
|
/** 워크스페이스 역할 → 트랙(스코프 판정용). 웹 trackOf와 동일. */
|
|
export function trackOf(role: EventRole | null | undefined): Track {
|
|
switch (role) {
|
|
case 'ORGANIZER':
|
|
case 'EXHIBITOR':
|
|
return 'business';
|
|
case 'CONTRACTOR':
|
|
return 'agency';
|
|
case 'HALL_MANAGER':
|
|
return 'ops';
|
|
default:
|
|
return 'visitor';
|
|
}
|
|
}
|
|
|
|
/** 랜딩 판정 입력 — 로그인 응답 user(roleCode 포함) + workspaces. */
|
|
export interface LandingInput {
|
|
user?: AuthUser | null;
|
|
workspaces?: WorkspaceDto[] | null;
|
|
}
|
|
|
|
/**
|
|
* 로그인 랜딩 트랙 결정(primaryTrack 우선순위). 웹 resolveLandingTrack 이식.
|
|
* roleCode('ADMIN'/'MANAGER')를 알면 웹과 동일하게 판정하고, 없으면 hallManager로 ops를 추론한다.
|
|
*/
|
|
export function resolveLandingTrack({ user, workspaces }: LandingInput): Track {
|
|
const role = (user?.roleCode ?? '').toUpperCase();
|
|
const ws = workspaces ?? [];
|
|
if (role === 'ADMIN') return 'admin';
|
|
if (role === 'MANAGER' || user?.hallManager || ws.some((w) => w.myRole === 'HALL_MANAGER')) {
|
|
return 'ops';
|
|
}
|
|
if (ws.some((w) => w.myRole === 'ORGANIZER' || w.myRole === 'EXHIBITOR')) return 'business';
|
|
if (ws.some((w) => w.myRole === 'CONTRACTOR')) return 'agency';
|
|
return 'visitor';
|
|
}
|
|
|
|
/**
|
|
* 트랙 → 로그인 직후 랜딩 라우트(모바일).
|
|
* · admin/ops/business → 탭 홈(/(tabs)) — 모바일엔 별도 admin 화면 없음, 홈이 역할 진입 허브
|
|
* · agency(장치·시공) → 현장 탭(/(tabs)/field) — 체크리스트 허브
|
|
* · visitor(관람객) → 티켓 지갑(/tickets) — B2C 진입
|
|
*/
|
|
export function landingPathForTrack(track: Track): string {
|
|
switch (track) {
|
|
case 'agency':
|
|
return '/(tabs)/field';
|
|
case 'visitor':
|
|
return '/tickets';
|
|
case 'admin':
|
|
case 'ops':
|
|
case 'business':
|
|
default:
|
|
return '/(tabs)';
|
|
}
|
|
}
|
|
|
|
/** 입력으로부터 랜딩 라우트 계산(예외 시 탭 홈 폴백). */
|
|
export function landingPathFor(input: LandingInput): string {
|
|
try {
|
|
return landingPathForTrack(resolveLandingTrack(input));
|
|
} catch {
|
|
return '/(tabs)';
|
|
}
|
|
}
|