diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index bd364f7..3f116b4 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -18,6 +18,7 @@ import TagBindingList from './pages/TagBindingList' import UpdateQueueList from './pages/UpdateQueueList' import AuditLog from './pages/AuditLog' import SystemSettings from './pages/SystemSettings' +import MobileApp from './pages/MobileApp' import WorklogList from './pages/uiws/WorklogList' import ScheduleCalendar from './pages/uiws/ScheduleCalendar' import MessageBox from './pages/uiws/MessageBox' @@ -52,6 +53,7 @@ export default function App() { } /> } /> } /> + } /> } /> diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 6b9aa05..54afe7f 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -3,7 +3,7 @@ import { LayoutDashboard, Store, FileText, RefreshCw, Bell, Cpu, ClipboardList, Zap, Users, Package, Building2, Brain, Link2, ListOrdered, NotebookPen, CalendarDays, Mail, BarChart3, - ScrollText, Settings + ScrollText, Settings, Smartphone } from 'lucide-react' const nav = [ @@ -27,6 +27,7 @@ const nav = [ { to: '/schedules', icon: CalendarDays, label: '일정 관리' }, { to: '/messages', icon: Mail, label: '쪽지' }, { to: '/work-stats', icon: BarChart3, label: '업무 통계' }, + { to: '/mobile-app', icon: Smartphone, label: '모바일 앱 설치' }, ] export default function Sidebar() { 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 다운로드 후 설정 → 보안 → "알 수 없는 소스" 허용 → 설치. + 앱스토어 등록이 필요 없습니다. +
+
+
+ )} +
+ ) +}