From cc6e3b2c2a5f0f28b17f7622c51a8d7101f44044 Mon Sep 17 00:00:00 2001 From: GUARDiA Date: Sun, 21 Jun 2026 10:27:22 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=86=94=EB=A3=A8=EC=85=98=20=ED=8F=AC?= =?UTF-8?q?=ED=84=B8=20=ED=99=88=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=9D=B4?= =?UTF-8?q?=EC=8B=9D=20+=20=EC=86=94=EB=A3=A8=EC=85=98=20=EC=86=8C?= =?UTF-8?q?=EA=B0=9C=20=EC=B5=9C=EC=8B=A0=ED=99=94=20+=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20=EB=A9=94=EC=8B=A0=EC=A0=80=EC=95=B1=20QR=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 2 + frontend/src/components/Sidebar.tsx | 9 +- frontend/src/pages/MobileApp.tsx | 123 ++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 frontend/src/pages/MobileApp.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 682a225..a28c289 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -22,6 +22,7 @@ import AiTools from './pages/AiTools' import UserManagement from './pages/UserManagement' import AuditLog from './pages/AuditLog' import SystemSettings from './pages/SystemSettings' +import MobileApp from './pages/MobileApp' // UIWS 이식 업무 모듈(업무일지·일정·쪽지·통계) — 기존 라우트 보존, 신규 메뉴만 추가 import UiwsLayout from './components/uiws/UiwsLayout' import WorklogList from './pages/uiws/WorklogList' @@ -64,6 +65,7 @@ export default function App() { } /> + } /> {/* 업무(UIWS 이식) — 인증 사용자 전체(Viewer+). UiwsLayout = .uiws-scope 다크/라이트 토큰 */} } /> diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 3f5576f..c5bb579 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -4,7 +4,7 @@ import { LayoutDashboard, FileText, Image, Package, Megaphone, ListTree, Palette, Languages, Search, FileInput, MessageSquareWarning, Share2, UsersRound, Sparkles, BarChart3, ShieldCheck, ScrollText, Settings, FileStack, - BookOpen, CalendarDays, Mail, + BookOpen, CalendarDays, Mail, Smartphone, } from 'lucide-react' import { currentRole, hasRole } from './rbac' import ThemeToggle from './uiws/ThemeToggle' @@ -44,6 +44,10 @@ const uiwsLinks: Link[] = [ { to: '/uiws/message', label: '쪽지', icon: Mail }, { to: '/uiws/stats', label: '업무통계', icon: BarChart3 }, ] +// 통합 메신저 앱(읽기전용 QR 설치) — 인증 사용자 전체 +const appLinks: Link[] = [ + { to: '/admin/mobile-app', label: '모바일 앱 설치', icon: Smartphone }, +] const linkClass = ({ isActive }: { isActive: boolean }) => `flex items-center gap-3 px-5 py-2 text-sm transition-colors ${ @@ -98,6 +102,9 @@ export default function Sidebar() {
+
+
+
{visibleAdmin.length > 0 && (
diff --git a/frontend/src/pages/MobileApp.tsx b/frontend/src/pages/MobileApp.tsx new file mode 100644 index 0000000..e09ba86 --- /dev/null +++ b/frontend/src/pages/MobileApp.tsx @@ -0,0 +1,123 @@ +import { useEffect, useState } from 'react' +import { Smartphone, Download, Copy, Check, ExternalLink, RefreshCw } from 'lucide-react' + +// 중앙 APK 저장소(ITSM)의 공개 엔드포인트 — 인증 불필요·CORS 허용 (읽기전용) +// 업로드·버전 관리는 GUARDiA Manager/ITSM에서 일원화. 본 화면은 표시 전용. +const ITSM_APP_BASE = 'https://zioinfo.co.kr:8443' + +interface AppInfo { + has_version: boolean + app_name?: string + version?: string + platform?: string + file_size_mb?: number + release_notes?: string + download_count?: number + qr_url?: string + landing_url?: string + download_url?: string + updated_at?: string +} + +export default function MobileApp() { + const [info, setInfo] = useState(null) + const [loading, setLoading] = useState(true) + const [err, setErr] = useState('') + const [copied, setCopied] = useState(false) + + const load = () => { + setLoading(true); setErr('') + fetch(`${ITSM_APP_BASE}/api/app/public-latest`) + .then(r => r.json()) + .then((d: AppInfo) => setInfo(d)) + .catch(() => setErr('버전 정보를 불러올 수 없습니다. (중앙 앱 저장소 연결 실패)')) + .finally(() => setLoading(false)) + } + useEffect(() => { load() }, []) + + const copyLink = async () => { + if (!info?.landing_url) return + try { + await navigator.clipboard.writeText(info.landing_url) + setCopied(true); setTimeout(() => setCopied(false), 2000) + } catch { /* clipboard 권한 없을 때 무시 */ } + } + + return ( +
+
+
+ +

GUARDiA 통합 메신저 앱 설치

+
+ +
+ +

+ QR 코드를 스캔하면 GUARDiA Messenger 앱 설치 페이지로 이동합니다. + 앱스토어 설치가 필요 없으며, 앱 업로드·버전 관리는 GUARDiA Manager에서 일원화되어 있습니다. +

+ + {loading &&
불러오는 중…
} + {err &&
{err}
} + + {!loading && !err && info && !info.has_version && ( +
+ + 아직 등록된 앱 버전이 없습니다.
+ GUARDiA Manager에서 APK를 업로드하면 여기에 QR이 표시됩니다. +
+ )} + + {!loading && !err && info?.has_version && ( +
+
+ 앱 설치 QR +
+
+
+ {info.app_name || 'GUARDiA Messenger'} + v{info.version} +
+
+ {info.platform} · {info.file_size_mb ? `${info.file_size_mb}MB` : ''} + {info.download_count != null && ` · 다운로드 ${info.download_count}회`} +
+ + {info.release_notes && ( +
+
변경점
+
+ {info.release_notes} +
+
+ )} + +
+ + 설치 페이지 열기 + + + APK 직접 다운로드 + + +
+ +
+ 📱 Android: APK 다운로드 후 설정 → 보안 → "알 수 없는 소스" 허용 → 설치. + 앱스토어 등록이 필요 없습니다. +
+
+
+ )} +
+ ) +}