Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node

This commit is contained in:
kjs
2026-03-12 14:23:34 +09:00
99 changed files with 14205 additions and 1442 deletions

View File

@@ -6,8 +6,17 @@ import { LoginForm } from "@/components/auth/LoginForm";
import { LoginFooter } from "@/components/auth/LoginFooter";
export default function LoginPage() {
const { formData, isLoading, error, showPassword, handleInputChange, handleLogin, togglePasswordVisibility } =
useLogin();
const {
formData,
isLoading,
error,
showPassword,
isPopMode,
handleInputChange,
handleLogin,
togglePasswordVisibility,
togglePopMode,
} = useLogin();
return (
<div className="flex min-h-screen flex-col items-center justify-center bg-muted/40 p-4">
@@ -19,9 +28,11 @@ export default function LoginPage() {
isLoading={isLoading}
error={error}
showPassword={showPassword}
isPopMode={isPopMode}
onInputChange={handleInputChange}
onSubmit={handleLogin}
onTogglePassword={togglePasswordVisibility}
onTogglePop={togglePopMode}
/>
<LoginFooter />

View File

@@ -3,7 +3,7 @@
import React, { useEffect, useState } from "react";
import { useParams, useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Loader2, ArrowLeft, Smartphone, Tablet, RotateCcw, RotateCw } from "lucide-react";
import { Loader2, ArrowLeft, Smartphone, Tablet, RotateCcw, RotateCw, LayoutGrid, Monitor } from "lucide-react";
import { screenApi } from "@/lib/api/screen";
import { ScreenDefinition } from "@/types/screen";
import { useRouter } from "next/navigation";
@@ -285,14 +285,23 @@ function PopScreenViewPage() {
</div>
)}
{/* 일반 모드 네비게이션 바 */}
{!isPreviewMode && (
<div className="sticky top-0 z-50 flex h-10 items-center justify-between border-b bg-white/80 px-3 backdrop-blur">
<Button variant="ghost" size="sm" onClick={() => router.push("/pop")} className="gap-1 text-xs">
<LayoutGrid className="h-3.5 w-3.5" />
POP
</Button>
<span className="text-xs text-gray-500">{screen.screenName}</span>
<Button variant="ghost" size="sm" onClick={() => router.push("/")} className="gap-1 text-xs">
<Monitor className="h-3.5 w-3.5" />
PC
</Button>
</div>
)}
{/* POP 화면 컨텐츠 */}
<div className={`flex-1 flex flex-col overflow-auto ${isPreviewMode ? "py-4 items-center" : "bg-white"}`}>
{/* 현재 모드 표시 (일반 모드) */}
{!isPreviewMode && (
<div className="absolute top-2 right-2 z-10 bg-black/50 text-white text-xs px-2 py-1 rounded">
{currentModeKey.replace("_", " ")}
</div>
)}
<div
className={`bg-white transition-all duration-300 ${isPreviewMode ? "shadow-2xl rounded-3xl overflow-auto border-8 border-foreground" : "w-full min-h-full"}`}

View File

@@ -458,6 +458,14 @@ select {
border-color: hsl(var(--destructive)) !important;
}
/* 채번 세그먼트 포커스 스타일 (shadcn Input과 동일한 3단 구조) */
.numbering-segment:focus-within {
box-shadow: 0 0 0 3px hsl(var(--ring) / 0.5);
outline: 2px solid hsl(var(--ring));
outline-offset: 2px;
}
/* 필수 입력 경고 문구 (입력 필드 아래, 레이아웃 영향 없음) */
.validation-error-msg-wrapper {
height: 0;