platform/lms-adm-fe release promotion snapshot

This commit is contained in:
2026-09-22 06:35:22 +00:00
parent 6a5bd04ee2
commit 9644daa900
5 changed files with 11 additions and 24 deletions
+1
View File
@@ -451,6 +451,7 @@ export function InstructorLayout({ session, route, onNavigate, onLogout, courses
</div> </div>
<div className="min-w-0"> <div className="min-w-0">
<p className="truncate text-[14px] font-black text-[#111827]">{displayName}</p> <p className="truncate text-[14px] font-black text-[#111827]">{displayName}</p>
<p className="mt-1 break-all text-[11px] leading-4 text-[#64748b]">{session.user.email}</p>
</div> </div>
</div> </div>
+4 -1
View File
@@ -1,4 +1,5 @@
export type CurriculumWeek = { export type CurriculumWeek = {
canDelete?: boolean;
week: number; week: number;
title: string; title: string;
tags: string[]; tags: string[];
@@ -223,8 +224,10 @@ export async function createInstructorCurriculumMap(
export async function deleteInstructorCurriculumWeek( export async function deleteInstructorCurriculumWeek(
accessToken: string, accessToken: string,
week: number, week: number,
courseId?: string | null,
): Promise<InstructorCurriculumResponse> { ): Promise<InstructorCurriculumResponse> {
const response = await fetch(`${LMS_API_BASE_URL}/instructor/curriculum/weeks/${week}`, { const query = courseId ? `?courseId=${encodeURIComponent(courseId)}` : '';
const response = await fetch(`${LMS_API_BASE_URL}/instructor/curriculum/weeks/${week}${query}`, {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
Authorization: `Bearer ${accessToken}`, Authorization: `Bearer ${accessToken}`,
+2 -2
View File
@@ -156,7 +156,7 @@ export function CurriculumPage({ session, selectedCourseId }: { session: AuthSes
const primaryActionDisabled = saving || !selectedWeek || (activeTab === 'apply' && !selectedGroup); const primaryActionDisabled = saving || !selectedWeek || (activeTab === 'apply' && !selectedGroup);
const selectedTopics = activeTab === 'edit' ? draftTopics : selectedWeek?.topics ?? []; const selectedTopics = activeTab === 'edit' ? draftTopics : selectedWeek?.topics ?? [];
const selectedTopicDetails = activeTab === 'edit' ? draftTopicDetails : selectedWeek?.detail.topicDetails ?? []; const selectedTopicDetails = activeTab === 'edit' ? draftTopicDetails : selectedWeek?.detail.topicDetails ?? [];
const selectedWeekDeletable = Boolean(selectedWeek?.tags.includes('추가')); const selectedWeekDeletable = selectedWeek?.canDelete === true;
const tagOptionLabels = useMemo(() => new Set(tagOptions.map((option) => option.label)), [tagOptions]); const tagOptionLabels = useMemo(() => new Set(tagOptions.map((option) => option.label)), [tagOptions]);
const selectedTagLabel = tagOptionLabels.has(draftTagLabel) const selectedTagLabel = tagOptionLabels.has(draftTagLabel)
? draftTagLabel ? draftTagLabel
@@ -580,7 +580,7 @@ export function CurriculumPage({ session, selectedCourseId }: { session: AuthSes
setError(null); setError(null);
try { try {
const payload = await deleteInstructorCurriculumWeek(session.accessToken, selectedWeek.week); const payload = await deleteInstructorCurriculumWeek(session.accessToken, selectedWeek.week, selectedCourseId);
applyPayload(payload, { selectProgress: true }); applyPayload(payload, { selectProgress: true });
showToast({ showToast({
title: '주차가 삭제되었습니다.', title: '주차가 삭제되었습니다.',
-3
View File
@@ -135,9 +135,6 @@ export function LoginPage({ onLogin }: LoginPageProps) {
/> />
아이디 기억 아이디 기억
</label> </label>
<button className="text-[12px] font-extrabold text-[#4f46e5]" type="button">
비밀번호를 잊으셨나요?
</button>
</div> </div>
<button <button
+4 -18
View File
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useState, type ReactNode } from 'react'; import { useEffect, useMemo, useState, type ReactNode } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { Activity, Battery, Car, CircleAlert, KeyRound, Loader2, Plus, RefreshCw, Search, Settings, ShieldAlert, Timer, Trash2, Users, X, type LucideIcon } from 'lucide-react'; import { Activity, Car, CircleAlert, KeyRound, Loader2, Plus, RefreshCw, Search, Settings, ShieldAlert, Timer, Trash2, Users, X, type LucideIcon } from 'lucide-react';
import { ConfirmDialog } from '../../components/ConfirmDialog'; import { ConfirmDialog } from '../../components/ConfirmDialog';
import { PageHeader } from '../../components/PageHeader'; import { PageHeader } from '../../components/PageHeader';
import { PaginationBar } from '../../components/PaginationBar'; import { PaginationBar } from '../../components/PaginationBar';
@@ -435,7 +435,7 @@ export function PlatformsPage({ session }: { session: AuthSession }) {
<div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#cbd5e1] px-4 py-3"> <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[#cbd5e1] px-4 py-3">
<div> <div>
<h2 className="text-[15px] font-black text-[#111827]">플랫폼 리스트</h2> <h2 className="text-[15px] font-black text-[#111827]">플랫폼 리스트</h2>
<p className="mt-1 text-[12px] font-bold text-[#64748b]">배터리, 가동 시간, 할당 그룹 상태 조회</p> <p className="mt-1 text-[12px] font-bold text-[#64748b]">가동 시간, 할당 그룹 상태 조회</p>
</div> </div>
<label className="flex h-9 w-full max-w-[260px] items-center gap-2 rounded-md border border-[#d1d9e6] bg-white px-3 text-[#94a3b8]"> <label className="flex h-9 w-full max-w-[260px] items-center gap-2 rounded-md border border-[#d1d9e6] bg-white px-3 text-[#94a3b8]">
@@ -446,12 +446,11 @@ export function PlatformsPage({ session }: { session: AuthSession }) {
<div className="overflow-x-auto"> <div className="overflow-x-auto">
<div className="xl:min-w-[1020px]"> <div className="xl:min-w-[1020px]">
<div className="hidden select-none gap-4 grid-cols-[44px_200px_110px_92px_90px_110px_150px_184px] items-center border-b border-[#cbd5e1] bg-[#f8fafc] px-4 py-3 text-center text-[11px] font-bold text-[#64748b] xl:grid"> <div className="hidden select-none gap-4 grid-cols-[44px_200px_110px_92px_110px_150px_184px] items-center border-b border-[#cbd5e1] bg-[#f8fafc] px-4 py-3 text-center text-[11px] font-bold text-[#64748b] xl:grid">
<span>No.</span> <span>No.</span>
<span>플랫폼</span> <span>플랫폼</span>
<span>연결</span> <span>연결</span>
<span>상태</span> <span>상태</span>
<span>배터리</span>
<span>가동 시간</span> <span>가동 시간</span>
<span>할당</span> <span>할당</span>
<span>관리</span> <span>관리</span>
@@ -469,7 +468,7 @@ export function PlatformsPage({ session }: { session: AuthSession }) {
</div> </div>
) : pagedPlatforms.length > 0 ? ( ) : pagedPlatforms.length > 0 ? (
pagedPlatforms.map((platform, index) => ( pagedPlatforms.map((platform, index) => (
<article className="grid select-none gap-4 px-4 py-4 xl:grid-cols-[44px_200px_110px_92px_90px_110px_150px_184px] xl:items-center" key={platform.id}> <article className="grid select-none gap-4 px-4 py-4 xl:grid-cols-[44px_200px_110px_92px_110px_150px_184px] xl:items-center" key={platform.id}>
<div className="text-center"> <div className="text-center">
<p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">번호</p> <p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">번호</p>
<span className="text-[13px] font-bold text-[#64748b]">{filteredPlatforms.length - ((page - 1) * pageSize + index)}</span> <span className="text-[13px] font-bold text-[#64748b]">{filteredPlatforms.length - ((page - 1) * pageSize + index)}</span>
@@ -504,19 +503,6 @@ export function PlatformsPage({ session }: { session: AuthSession }) {
<span className={`rounded px-1.5 py-0.5 text-[11px] font-bold ${statusTone(platform.status)}`}>{platform.status}</span> <span className={`rounded px-1.5 py-0.5 text-[11px] font-bold ${statusTone(platform.status)}`}>{platform.status}</span>
</div> </div>
<div>
<div className="mb-2 flex items-center justify-between text-[12px] font-bold text-[#475569] xl:justify-center">
<span className="inline-flex items-center gap-1.5 xl:hidden">
<Battery size={13} aria-hidden="true" />
배터리
</span>
<span className="font-semibold text-[#4f46e5]">{platform.battery}%</span>
</div>
<div className="h-1.5 overflow-hidden rounded-full bg-[#dbe3ef]">
<div className="h-full rounded-full bg-[#4f46e5]" style={{ width: `${platform.battery}%` }} />
</div>
</div>
<PlatformMeta icon={Timer} label="가동 시간" value={platform.uptime} /> <PlatformMeta icon={Timer} label="가동 시간" value={platform.uptime} />
<div className="text-center"> <div className="text-center">
<p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">할당</p> <p className="mb-2 text-[11px] font-bold text-[#94a3b8] xl:hidden">할당</p>