guardia-messenger/app/(tabs)/settings.tsx

121 lines
5.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { View, Text, StyleSheet, TouchableOpacity, ScrollView, Alert, Switch, Linking } from 'react-native'
import { COLORS } from '../../constants/Config'
import { useAuth } from '../../hooks/useAuth'
import { useState } from 'react'
import LineIcon from '../../components/LineIcon'
type IconName = Parameters<typeof LineIcon>[0]['name']
function MenuItem({ iconName, label, value, onPress, danger, toggle, enabled, onToggle }:
{ iconName: IconName; label: string; value?: string; onPress?: () => void; danger?: boolean
toggle?: boolean; enabled?: boolean; onToggle?: (v: boolean) => void }) {
return (
<TouchableOpacity style={s.item} onPress={onPress} disabled={toggle}>
<View style={[s.itemIcon, { backgroundColor: danger ? '#fee2e2' : 'rgba(0,160,200,.08)' }]}>
<LineIcon name={iconName} size={18} color={danger ? COLORS.danger : COLORS.accent} />
</View>
<View style={{ flex: 1 }}>
<Text style={[s.itemLabel, danger && { color: COLORS.danger }]}>{label}</Text>
{value && <Text style={s.itemValue}>{value}</Text>}
</View>
{toggle
? <Switch value={enabled} onValueChange={onToggle} trackColor={{ true: COLORS.accent }} />
: <Text style={s.chevron}></Text>
}
</TouchableOpacity>
)
}
export default function SettingsScreen() {
const { user, logout } = useAuth()
const [pushEnabled, setPush] = useState(true)
const [darkMode, setDark] = useState(false)
const handleLogout = () => {
Alert.alert('로그아웃', '정말 로그아웃하시겠습니까?', [
{ text: '취소', style: 'cancel' },
{ text: '로그아웃', style: 'destructive', onPress: logout },
])
}
return (
<ScrollView style={{ flex: 1, backgroundColor: COLORS.bg }}>
{/* 프로필 카드 */}
<View style={s.profile}>
<View style={s.avatar}>
<Text style={s.avatarText}>{(user?.display_name ?? user?.username ?? 'U')[0].toUpperCase()}</Text>
</View>
<View>
<Text style={s.displayName}>{user?.display_name ?? user?.username}</Text>
<Text style={s.role}>{user?.role ?? '-'}</Text>
{user?.email && <Text style={s.email}>{user.email}</Text>}
</View>
</View>
{/* 서버 정보 */}
<View style={s.section}>
<Text style={s.sectionTitle}> </Text>
<MenuItem iconName="globe" label="GUARDiA 서버" value="zioinfo.co.kr:8443" />
<MenuItem iconName="lock" label="HTTPS 보안 연결" value="TLS 1.3" />
<MenuItem iconName="dashboard" label="API 버전" value="v2.0.0" />
</View>
{/* 알림 설정 */}
<View style={s.section}>
<Text style={s.sectionTitle}></Text>
<MenuItem iconName="bell" label="푸시 알림" toggle enabled={pushEnabled} onToggle={setPush} />
<MenuItem iconName="alert" label="긴급 알림 (인시던트)" toggle enabled={true} onToggle={() => {}} />
<MenuItem iconName="sr" label="SR 상태 알림" toggle enabled={true} onToggle={() => {}} />
</View>
{/* 앱 설정 */}
<View style={s.section}>
<Text style={s.sectionTitle}> </Text>
<MenuItem iconName="settings" label="다크 모드" toggle enabled={darkMode} onToggle={setDark} />
<MenuItem iconName="globe" label="언어" value="한국어" />
<MenuItem iconName="ai" label="앱 버전" value="1.0.0 (build 1)" />
</View>
{/* 지원 */}
<View style={s.section}>
<Text style={s.sectionTitle}></Text>
<MenuItem iconName="server" label="사용 가이드"
onPress={() => Linking.openURL('http://zioinfo.co.kr:8090')} />
<MenuItem iconName="lock" label="GUARDiA ITSM 웹"
onPress={() => Linking.openURL('https://zioinfo.co.kr:8443')} />
<MenuItem iconName="mail" label="문의하기"
onPress={() => Linking.openURL('mailto:guardia@zioinfo.co.kr')} />
<MenuItem iconName="building" label="(주)지오정보기술" value="zioinfo.co.kr" />
</View>
{/* 로그아웃 */}
<View style={s.section}>
<MenuItem iconName="user" label="로그아웃" onPress={handleLogout} danger />
</View>
<View style={{ height: 32 }} />
</ScrollView>
)
}
const s = StyleSheet.create({
profile: { backgroundColor:COLORS.primary, padding:24,
flexDirection:'row', alignItems:'center', gap:16 },
avatar: { width:56, height:56, borderRadius:28,
backgroundColor:'rgba(255,255,255,.2)', justifyContent:'center', alignItems:'center' },
avatarText: { fontSize:24, fontWeight:'800', color:'#fff' },
displayName: { fontSize:18, fontWeight:'700', color:'#fff' },
role: { fontSize:12, color:'#aac4e8', marginTop:2 },
email: { fontSize:12, color:'#aac4e8' },
section: { backgroundColor:'#fff', marginHorizontal:0, marginTop:12 },
sectionTitle:{ fontSize:12, fontWeight:'600', color:COLORS.muted,
paddingHorizontal:16, paddingTop:14, paddingBottom:6,
textTransform:'uppercase', letterSpacing:.5 },
item: { flexDirection:'row', alignItems:'center', paddingHorizontal:16,
paddingVertical:14, borderBottomWidth:1, borderBottomColor:'#f1f5f9', gap:12 },
itemIcon: { width:34, height:34, borderRadius:9, alignItems:'center', justifyContent:'center' },
itemLabel: { fontSize:14, color:COLORS.text, fontWeight:'500' },
itemValue: { fontSize:12, color:COLORS.muted, marginTop:2 },
chevron: { fontSize:20, color:COLORS.muted },
})