government ui complated

This commit is contained in:
Samandar Turgunboyev
2026-02-05 16:09:03 +05:00
parent 5d31fe8ff4
commit 754f11804a
76 changed files with 2459 additions and 672 deletions

View File

@@ -41,7 +41,14 @@ export function NotificationTab() {
if (isLoading) {
return (
<View style={styles.loadingContainer}>
<View
style={[
styles.loadingContainer,
{
backgroundColor: isDark ? '#0f172a' : '#f8fafc',
},
]}
>
<View style={styles.loadingContent}>
<ActivityIndicator size="large" color="#3b82f6" />
</View>
@@ -51,10 +58,12 @@ export function NotificationTab() {
if (isError) {
return (
<View style={styles.errorContainer}>
<View style={styles.errorContent}>
<View style={[styles.errorContainer, { backgroundColor: isDark ? '#0f172a' : '#f8fafc' }]}>
<View style={[styles.errorContent, { backgroundColor: isDark ? '#1e293b' : '#ffffff' }]}>
<Text style={styles.errorTitle}>{t('Xatolik yuz berdi')}</Text>
<Text style={styles.errorMessage}>{t("Bildirishnomalarni yuklashda muammo bo'ldi")}</Text>
<Text style={[styles.errorMessage, { color: isDark ? '#cbd5e1' : '#64748b' }]}>
{t("Bildirishnomalarni yuklashda muammo bo'ldi")}
</Text>
<TouchableOpacity style={styles.retryButton} onPress={() => refetch()}>
<Text style={styles.retryButtonText}>{t('Qayta urinish')}</Text>
</TouchableOpacity>
@@ -64,13 +73,13 @@ export function NotificationTab() {
}
return (
<View style={styles.container}>
<View style={[styles.header, { backgroundColor: isDark ? '#0f172a' : '#fff' }]}>
<View style={[styles.container, { backgroundColor: isDark ? '#0f172a' : '#f8fafc' }]}>
<View style={[styles.header, { backgroundColor: isDark ? '#0f172a' : '#f8fafc' }]}>
<Pressable onPress={() => router.push('/profile')}>
<ArrowLeft color={isDark ? '#fff' : '#0f172a'} />
</Pressable>
<Text style={[styles.headerTitle, { color: isDark ? '#fff' : '#0f172a' }]}>
<Text style={[styles.headerTitle, { color: isDark ? '#f1f5f9' : '#0f172a' }]}>
{t('Bildirishnomalar')}
</Text>
</View>
@@ -102,12 +111,14 @@ export function NotificationTab() {
function NotificationCard({ item }: { item: NotificationListDataRes }) {
const queryClient = useQueryClient();
const { isDark } = useTheme();
const { t } = useTranslation();
const [scaleAnim] = useState(new Animated.Value(1));
const { mutate } = useMutation({
mutationFn: (id: number) => user_api.is_ready_id(id),
onSuccess: () => {
queryClient.refetchQueries({ queryKey: ['notification-list'] });
queryClient.refetchQueries({ queryKey: ['notifications-list'] });
},
});
@@ -145,21 +156,54 @@ function NotificationCard({ item }: { item: NotificationListDataRes }) {
onPressIn={handlePressIn}
onPressOut={handlePressOut}
onPress={() => handlePress(item.id)}
style={[styles.card, !item.is_read && styles.unreadCard]}
style={[
styles.card,
!item.is_read && styles.unreadCard,
{
backgroundColor: isDark ? '#283046' : '#e0f2fe',
borderColor: isDark ? '#3b82f6' : '#3b82f6',
},
]}
>
<View style={styles.cardContent}>
<View style={styles.cardHeader}>
<Text style={[styles.cardTitle, !item.is_read && styles.unreadTitle]} numberOfLines={1}>
<Text
style={[
styles.cardTitle,
!item.is_read && styles.unreadTitle,
{ color: isDark ? '#3b82f6' : '#1e40af' },
]}
numberOfLines={1}
>
{item.title}
</Text>
{!item.is_read && <View style={styles.unreadIndicator} />}
{!item.is_read && (
<View
style={[
styles.unreadIndicator,
{
backgroundColor: isDark ? '#3b82f6' : '#3b82f6',
},
]}
/>
)}
</View>
<Text style={styles.cardMessage} numberOfLines={2}>
<Text
style={[
styles.cardMessage,
{
color: isDark ? '#cbd5e1' : '#64748b',
},
]}
numberOfLines={2}
>
{item.description}
</Text>
<Text style={styles.cardTime}>{formatDate(item.created_at, t)}</Text>
<Text style={[styles.cardTime, { color: isDark ? '#94a3b8' : '#94a3b8' }]}>
{formatDate(item.created_at, t)}
</Text>
</View>
</TouchableOpacity>
</Animated.View>
@@ -187,12 +231,9 @@ function formatDate(date: string, t: any) {
});
}
/* ---------------- STYLES ---------------- */
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0a0c17',
},
listContent: {
padding: 16,
@@ -202,41 +243,23 @@ const styles = StyleSheet.create({
/* Card Styles */
card: {
flexDirection: 'row',
backgroundColor: '#121826',
padding: 16,
borderRadius: 24,
borderWidth: 1,
borderColor: 'rgba(60, 70, 90, 0.18)',
shadowColor: '#000',
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.35,
shadowRadius: 16,
elevation: 10,
shadowOpacity: 0.25,
shadowRadius: 12,
elevation: 8,
overflow: 'hidden',
},
unreadCard: {
backgroundColor: '#1a2236',
borderColor: 'rgba(59, 130, 246, 0.4)',
shadowColor: '#3b82f6',
shadowOpacity: 0.28,
shadowRadius: 20,
elevation: 12,
},
iconContainer: {
width: 56,
height: 56,
borderRadius: 20,
backgroundColor: 'rgba(30, 38, 56, 0.7)',
alignItems: 'center',
justifyContent: 'center',
marginRight: 16,
},
unreadIconContainer: {
backgroundColor: 'rgba(59, 130, 246, 0.22)',
},
iconText: {
fontSize: 32,
shadowOpacity: 0.3,
shadowRadius: 16,
elevation: 10,
},
cardContent: {
flex: 1,
justifyContent: 'center',
@@ -248,20 +271,20 @@ const styles = StyleSheet.create({
},
cardTitle: {
flex: 1,
color: '#d1d5db',
fontSize: 16.5,
fontWeight: '600',
letterSpacing: -0.1,
},
unreadTitle: {
color: '#f1f5f9',
fontWeight: '700',
// unread title rang
},
unreadIndicator: {
width: 10,
height: 10,
borderRadius: 5,
backgroundColor: '#3b82f6',
marginLeft: 8,
shadowColor: '#3b82f6',
shadowOffset: { width: 0, height: 0 },
@@ -269,13 +292,11 @@ const styles = StyleSheet.create({
shadowRadius: 6,
},
cardMessage: {
color: '#9ca3af',
fontSize: 14.5,
lineHeight: 21,
marginBottom: 8,
},
cardTime: {
color: '#64748b',
fontSize: 12.5,
fontWeight: '500',
opacity: 0.9,
@@ -284,7 +305,7 @@ const styles = StyleSheet.create({
/* Loading State */
loadingContainer: {
flex: 1,
backgroundColor: '#0a0c17',
alignItems: 'center',
justifyContent: 'center',
},
@@ -292,40 +313,22 @@ const styles = StyleSheet.create({
alignItems: 'center',
padding: 32,
},
loadingText: {
marginTop: 16,
color: '#94a3b8',
fontSize: 15,
fontWeight: '500',
},
/* Error State */
errorContainer: {
flex: 1,
backgroundColor: '#0a0c17',
alignItems: 'center',
justifyContent: 'center',
padding: 24,
},
errorContent: {
alignItems: 'center',
backgroundColor: '#151b2e',
padding: 32,
borderRadius: 24,
maxWidth: 320,
},
errorIconContainer: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: '#1e2638',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 20,
},
errorIcon: {
fontSize: 40,
},
errorTitle: {
color: '#ef4444',
fontSize: 20,
@@ -333,7 +336,6 @@ const styles = StyleSheet.create({
marginBottom: 8,
},
errorMessage: {
color: '#94a3b8',
fontSize: 14,
textAlign: 'center',
marginBottom: 24,
@@ -356,52 +358,19 @@ const styles = StyleSheet.create({
fontWeight: '700',
},
/* Empty State */
emptyContainer: {
flex: 1,
backgroundColor: '#0a0c17',
alignItems: 'center',
justifyContent: 'center',
padding: 24,
},
emptyContent: {
alignItems: 'center',
maxWidth: 300,
},
emptyIconContainer: {
width: 100,
height: 100,
borderRadius: 50,
backgroundColor: '#151b2e',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 24,
borderWidth: 2,
borderColor: '#1e2638',
},
emptyIcon: {
fontSize: 50,
},
emptyTitle: {
color: '#ffffff',
fontSize: 22,
fontWeight: '700',
marginBottom: 12,
textAlign: 'center',
},
emptyMessage: {
color: '#94a3b8',
fontSize: 15,
textAlign: 'center',
lineHeight: 22,
},
/* Header */
header: {
padding: 16,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
gap: 10,
elevation: 3,
},
headerTitle: { fontSize: 18, fontWeight: '700', lineHeight: 24 },
headerTitle: {
fontSize: 18,
fontWeight: '700',
lineHeight: 24,
},
});