guardia-messenger/app/(auth)/login.tsx
DESKTOP-TKLFCPRython f29f525c77 refactor: 101.79.17.164 → zioinfo.co.kr 전체 도메인 변환 + Manager UI 배포
- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스)
- Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포
- 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:09:17 +09:00

126 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from 'react'
import {
View, Text, TextInput, TouchableOpacity, StyleSheet,
KeyboardAvoidingView, Platform, ActivityIndicator, Alert, ScrollView,
} from 'react-native'
import { useAuth } from '../../hooks/useAuth'
import { COLORS } from '../../constants/Config'
export default function LoginScreen() {
const { login } = useAuth()
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const handleLogin = async () => {
if (!username.trim() || !password.trim()) {
Alert.alert('입력 오류', '아이디와 비밀번호를 입력해주세요.')
return
}
setLoading(true)
try {
await login(username.trim(), password)
} catch (e: any) {
const msg = e.response?.data?.detail ?? '로그인에 실패했습니다.'
Alert.alert('로그인 실패', msg)
} finally {
setLoading(false)
}
}
return (
<KeyboardAvoidingView
style={s.container}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<ScrollView contentContainerStyle={s.inner} keyboardShouldPersistTaps="handled">
{/* 로고 영역 */}
<View style={s.logoBox}>
<Text style={s.logoIcon}>🛡</Text>
<Text style={s.logoTitle}>GUARDiA</Text>
<Text style={s.logoSub}>AI </Text>
<View style={s.badge}>
<Text style={s.badgeText}>()</Text>
</View>
</View>
{/* 로그인 카드 */}
<View style={s.card}>
<Text style={s.cardTitle}></Text>
<View style={s.field}>
<Text style={s.label}></Text>
<TextInput
style={s.input}
value={username}
onChangeText={setUsername}
placeholder="관리자 아이디"
placeholderTextColor={COLORS.muted}
autoCapitalize="none"
autoCorrect={false}
returnKeyType="next"
/>
</View>
<View style={s.field}>
<Text style={s.label}></Text>
<TextInput
style={s.input}
value={password}
onChangeText={setPassword}
placeholder="비밀번호"
placeholderTextColor={COLORS.muted}
secureTextEntry
returnKeyType="done"
onSubmitEditing={handleLogin}
/>
</View>
<TouchableOpacity
style={[s.btn, loading && s.btnDisabled]}
onPress={handleLogin}
disabled={loading}
>
{loading
? <ActivityIndicator color="#fff" />
: <Text style={s.btnText}></Text>
}
</TouchableOpacity>
<Text style={s.hint}>GUARDiA ITSM </Text>
</View>
<Text style={s.version}>v1.0.0 · zioinfo.co.kr</Text>
</ScrollView>
</KeyboardAvoidingView>
)
}
const s = StyleSheet.create({
container: { flex: 1, backgroundColor: COLORS.primary },
inner: { flexGrow: 1, justifyContent: 'center', padding: 24 },
logoBox: { alignItems: 'center', marginBottom: 32 },
logoIcon: { fontSize: 56, marginBottom: 8 },
logoTitle: { fontSize: 32, fontWeight: '800', color: '#fff', letterSpacing: 2 },
logoSub: { fontSize: 13, color: '#aac4e8', marginTop: 4 },
badge: { marginTop: 10, backgroundColor: 'rgba(255,255,255,.15)',
paddingHorizontal: 14, paddingVertical: 4, borderRadius: 20 },
badgeText: { color: '#fff', fontSize: 11, fontWeight: '600' },
card: { backgroundColor: '#fff', borderRadius: 16, padding: 24,
shadowColor: '#000', shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.15, shadowRadius: 24, elevation: 8 },
cardTitle: { fontSize: 18, fontWeight: '700', color: COLORS.primary,
marginBottom: 20, textAlign: 'center' },
field: { marginBottom: 14 },
label: { fontSize: 12, fontWeight: '600', color: COLORS.muted,
marginBottom: 6, textTransform: 'uppercase', letterSpacing: .5 },
input: { borderWidth: 1.5, borderColor: COLORS.border, borderRadius: 10,
padding: 13, fontSize: 15, color: COLORS.text, backgroundColor: '#fafafa' },
btn: { backgroundColor: COLORS.primary, borderRadius: 10, padding: 15,
alignItems: 'center', marginTop: 8 },
btnDisabled: { opacity: .6 },
btnText: { color: '#fff', fontSize: 16, fontWeight: '700' },
hint: { textAlign: 'center', color: COLORS.muted, fontSize: 12, marginTop: 16 },
version: { textAlign: 'center', color: 'rgba(255,255,255,.4)', fontSize: 11, marginTop: 24 },
})