Files
blog-frontend/src/components/chess/chessUi.ts
박원엽 cc4fb0f947
All checks were successful
Deploy blog-frontend / build-and-deploy (push) Successful in 2m16s
feat: add chess resign and undo actions
2026-06-24 09:01:13 +09:00

61 lines
1.7 KiB
TypeScript

import axios from 'axios';
import { ChessOutcome } from '@/types';
export type OutcomeFilter = 'ALL' | 'IN_PROGRESS' | 'WIN' | 'LOSS' | 'DRAW';
export const outcomeLabels: Record<ChessOutcome, string> = {
IN_PROGRESS: '진행중',
WIN: '승',
LOSS: '패',
DRAW: '무',
UNKNOWN: '미정',
};
export const outcomeBadgeTones: Record<ChessOutcome, 'neutral' | 'info' | 'success' | 'warning' | 'danger'> = {
IN_PROGRESS: 'info',
WIN: 'success',
LOSS: 'danger',
DRAW: 'warning',
UNKNOWN: 'neutral',
};
export const getChessOutcomeLabel = (outcome: ChessOutcome, status?: string) => {
if (status === 'RESIGNED' && outcome === 'LOSS') return '기권패';
return outcomeLabels[outcome];
};
export const formatChessDateTime = (value?: string) => {
if (!value) return '';
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return new Intl.DateTimeFormat('ko-KR', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
}).format(date);
};
export const getChessErrorMessage = (error: unknown, fallback = '요청을 처리하지 못했습니다.') => {
if (axios.isAxiosError(error)) {
if (error.response?.status === 401 || error.response?.status === 403) {
return '로그인이 필요합니다.';
}
const message = error.response?.data?.message;
if (typeof message === 'string' && message.trim()) return message;
}
if (error instanceof Error && error.message) return error.message;
return fallback;
};
export const isAuthError = (error: unknown) => {
return axios.isAxiosError(error) && (error.response?.status === 401 || error.response?.status === 403);
};