fix: align access console status actions
This commit is contained in:
@@ -21,7 +21,7 @@ function accessBadge(record: AccessRecord): { className: string; label: string }
|
|||||||
}
|
}
|
||||||
const status = record.status ?? 'APPROVED';
|
const status = record.status ?? 'APPROVED';
|
||||||
if (status === 'APPROVED') {
|
if (status === 'APPROVED') {
|
||||||
return { className: 'amber', label: '입장대기' };
|
return { className: STATUS_CLASS.APPROVED, label: STATUS_LABEL.APPROVED };
|
||||||
}
|
}
|
||||||
return { className: STATUS_CLASS[status], label: STATUS_LABEL[status] };
|
return { className: STATUS_CLASS[status], label: STATUS_LABEL[status] };
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ export const AccessConsolePage: React.FC = () => {
|
|||||||
<span className="badge badge-gray">금일완료</span>
|
<span className="badge badge-gray">금일완료</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="status-cell">
|
<span className="status-cell">
|
||||||
<span className="badge badge-amber">입장대기</span>
|
<span className={`badge badge-${STATUS_CLASS.APPROVED}`}>{STATUS_LABEL.APPROVED}</span>
|
||||||
<button
|
<button
|
||||||
className="btn-success"
|
className="btn-success"
|
||||||
disabled={busy}
|
disabled={busy}
|
||||||
@@ -207,7 +207,7 @@ export const AccessConsolePage: React.FC = () => {
|
|||||||
})()}
|
})()}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{r.inside && hasEnteredToday(r) && (
|
{r.inside && hasEnteredToday(r) ? (
|
||||||
<button
|
<button
|
||||||
className="btn-danger"
|
className="btn-danger"
|
||||||
disabled={busy}
|
disabled={busy}
|
||||||
@@ -216,6 +216,17 @@ export const AccessConsolePage: React.FC = () => {
|
|||||||
forceCheckOut(r.visitRequestId);
|
forceCheckOut(r.visitRequestId);
|
||||||
}}
|
}}
|
||||||
>퇴장</button>
|
>퇴장</button>
|
||||||
|
) : r.status === 'APPROVED' && !hasExitedToday(r) ? (
|
||||||
|
<button
|
||||||
|
className="btn-success"
|
||||||
|
disabled={busy}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
forceCheckIn(r.visitRequestId);
|
||||||
|
}}
|
||||||
|
>입장</button>
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { formatVisitRange } from '../status';
|
|||||||
import { Dialog } from '../components/Dialog';
|
import { Dialog } from '../components/Dialog';
|
||||||
|
|
||||||
type SortKey = 'visitorName' | 'company' | 'zoneName' | 'purpose' | 'visitFrom';
|
type SortKey = 'visitorName' | 'company' | 'zoneName' | 'purpose' | 'visitFrom';
|
||||||
|
type BusyAction = 'approve' | 'reject';
|
||||||
|
|
||||||
const COLUMNS: { key: SortKey; label: string }[] = [
|
const COLUMNS: { key: SortKey; label: string }[] = [
|
||||||
{ key: 'visitorName', label: '방문자' },
|
{ key: 'visitorName', label: '방문자' },
|
||||||
@@ -18,7 +19,7 @@ export const ApprovalQueuePage: React.FC = () => {
|
|||||||
const [items, setItems] = useState<VisitRequestView[]>([]);
|
const [items, setItems] = useState<VisitRequestView[]>([]);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [busyId, setBusyId] = useState<number | null>(null);
|
const [busyAction, setBusyAction] = useState<{ id: number; action: BusyAction } | null>(null);
|
||||||
const [sortKey, setSortKey] = useState<SortKey | null>(null);
|
const [sortKey, setSortKey] = useState<SortKey | null>(null);
|
||||||
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
|
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
|
||||||
const [rejectingId, setRejectingId] = useState<number | null>(null);
|
const [rejectingId, setRejectingId] = useState<number | null>(null);
|
||||||
@@ -56,14 +57,14 @@ export const ApprovalQueuePage: React.FC = () => {
|
|||||||
|
|
||||||
const approve = async (id: number) => {
|
const approve = async (id: number) => {
|
||||||
setError(null);
|
setError(null);
|
||||||
setBusyId(id);
|
setBusyAction({ id, action: 'approve' });
|
||||||
try {
|
try {
|
||||||
await approveRequest(id);
|
await approveRequest(id);
|
||||||
load();
|
load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(e instanceof Error ? e.message : '처리 실패');
|
setError(e instanceof Error ? e.message : '처리 실패');
|
||||||
} finally {
|
} finally {
|
||||||
setBusyId(null);
|
setBusyAction(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -72,14 +73,14 @@ export const ApprovalQueuePage: React.FC = () => {
|
|||||||
setRejectingId(null);
|
setRejectingId(null);
|
||||||
if (id == null) return;
|
if (id == null) return;
|
||||||
setError(null);
|
setError(null);
|
||||||
setBusyId(id);
|
setBusyAction({ id, action: 'reject' });
|
||||||
try {
|
try {
|
||||||
await rejectRequest(id, comment);
|
await rejectRequest(id, comment);
|
||||||
load();
|
load();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(e instanceof Error ? e.message : '처리 실패');
|
setError(e instanceof Error ? e.message : '처리 실패');
|
||||||
} finally {
|
} finally {
|
||||||
setBusyId(null);
|
setBusyAction(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,8 +120,26 @@ export const ApprovalQueuePage: React.FC = () => {
|
|||||||
<td>{r.purpose}</td>
|
<td>{r.purpose}</td>
|
||||||
<td>{formatVisitRange(r.visitFrom, r.visitTo)}</td>
|
<td>{formatVisitRange(r.visitFrom, r.visitTo)}</td>
|
||||||
<td className="action-cell">
|
<td className="action-cell">
|
||||||
<button className="btn-success" disabled={busyId === r.id} onClick={() => approve(r.id)}>승인</button>
|
<button
|
||||||
<button className="btn-danger" disabled={busyId === r.id} onClick={() => setRejectingId(r.id)}>반려</button>
|
className="btn-success"
|
||||||
|
disabled={busyAction?.id === r.id && busyAction.action === 'approve'}
|
||||||
|
onClick={() => {
|
||||||
|
if (busyAction?.id === r.id) return;
|
||||||
|
approve(r.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{busyAction?.id === r.id && busyAction.action === 'approve' ? '처리 중...' : '승인'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn-danger"
|
||||||
|
disabled={busyAction?.id === r.id && busyAction.action === 'reject'}
|
||||||
|
onClick={() => {
|
||||||
|
if (busyAction?.id === r.id) return;
|
||||||
|
setRejectingId(r.id);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{busyAction?.id === r.id && busyAction.action === 'reject' ? '처리 중...' : '반려'}
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user