@nextsparkjs/mobile 0.1.0-beta.147 → 0.1.0-beta.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/app/(app)/_layout.tsx +0 -216
- package/templates/app/(app)/customer/[id].tsx +0 -68
- package/templates/app/(app)/customer/create.tsx +0 -24
- package/templates/app/(app)/customers.tsx +0 -164
- package/templates/app/(app)/index.tsx +0 -310
- package/templates/app/(app)/notifications.tsx +0 -242
- package/templates/app/(app)/profile.tsx +0 -254
- package/templates/app/(app)/settings.tsx +0 -241
- package/templates/app/(app)/task/[id].tsx +0 -70
- package/templates/app/(app)/task/create.tsx +0 -24
- package/templates/app/(app)/tasks.tsx +0 -164
- package/templates/app/_layout.tsx +0 -54
- package/templates/app/index.tsx +0 -35
- package/templates/app/login.tsx +0 -179
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Profile Screen - User information and settings
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { View, Text, TextInput, ScrollView, StyleSheet } from 'react-native'
|
|
6
|
-
import { useAuth } from '@nextsparkjs/mobile'
|
|
7
|
-
import { Colors } from '@/src/constants/colors'
|
|
8
|
-
|
|
9
|
-
export default function ProfileScreen() {
|
|
10
|
-
const { user } = useAuth()
|
|
11
|
-
|
|
12
|
-
// Split name into first and last name
|
|
13
|
-
const nameParts = user?.name?.split(' ') || ['', '']
|
|
14
|
-
const firstName = nameParts[0] || ''
|
|
15
|
-
const lastName = nameParts.slice(1).join(' ') || ''
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<ScrollView style={styles.container}>
|
|
19
|
-
{/* Page Header */}
|
|
20
|
-
<View style={styles.header}>
|
|
21
|
-
<Text style={styles.pageTitle}>Información Personal</Text>
|
|
22
|
-
<Text style={styles.pageSubtitle}>
|
|
23
|
-
Gestiona tu información personal y preferencias básicas de tu cuenta.
|
|
24
|
-
</Text>
|
|
25
|
-
</View>
|
|
26
|
-
|
|
27
|
-
{/* Personal Data Card */}
|
|
28
|
-
<View style={styles.card}>
|
|
29
|
-
<View style={styles.cardHeader}>
|
|
30
|
-
<Text style={styles.cardIcon}>👤</Text>
|
|
31
|
-
<View>
|
|
32
|
-
<Text style={styles.cardTitle}>Datos Personales</Text>
|
|
33
|
-
<Text style={styles.cardSubtitle}>
|
|
34
|
-
Actualiza tu nombre, país, zona horaria e idioma preferido
|
|
35
|
-
</Text>
|
|
36
|
-
</View>
|
|
37
|
-
</View>
|
|
38
|
-
|
|
39
|
-
{/* Name Field */}
|
|
40
|
-
<View style={styles.field}>
|
|
41
|
-
<Text style={styles.label}>Nombre</Text>
|
|
42
|
-
<TextInput
|
|
43
|
-
style={styles.input}
|
|
44
|
-
value={firstName}
|
|
45
|
-
editable={false}
|
|
46
|
-
placeholder="Tu nombre"
|
|
47
|
-
placeholderTextColor={Colors.foregroundMuted}
|
|
48
|
-
/>
|
|
49
|
-
</View>
|
|
50
|
-
|
|
51
|
-
{/* Last Name Field */}
|
|
52
|
-
<View style={styles.field}>
|
|
53
|
-
<Text style={styles.label}>Apellido</Text>
|
|
54
|
-
<TextInput
|
|
55
|
-
style={styles.input}
|
|
56
|
-
value={lastName}
|
|
57
|
-
editable={false}
|
|
58
|
-
placeholder="Tu apellido"
|
|
59
|
-
placeholderTextColor={Colors.foregroundMuted}
|
|
60
|
-
/>
|
|
61
|
-
</View>
|
|
62
|
-
|
|
63
|
-
{/* Email Field */}
|
|
64
|
-
<View style={styles.field}>
|
|
65
|
-
<Text style={styles.label}>Email</Text>
|
|
66
|
-
<View style={styles.emailInputWrapper}>
|
|
67
|
-
<Text style={styles.emailIcon}>✉</Text>
|
|
68
|
-
<TextInput
|
|
69
|
-
style={[styles.input, styles.emailInput]}
|
|
70
|
-
value={user?.email || ''}
|
|
71
|
-
editable={false}
|
|
72
|
-
placeholder="Tu email"
|
|
73
|
-
placeholderTextColor={Colors.foregroundMuted}
|
|
74
|
-
/>
|
|
75
|
-
</View>
|
|
76
|
-
<Text style={styles.hint}>No se puede cambiar</Text>
|
|
77
|
-
</View>
|
|
78
|
-
|
|
79
|
-
{/* Auth Method */}
|
|
80
|
-
<View style={styles.field}>
|
|
81
|
-
<Text style={styles.label}>Método de Autenticación</Text>
|
|
82
|
-
<View style={styles.readOnlyRow}>
|
|
83
|
-
<Text style={styles.readOnlyIcon}>✉</Text>
|
|
84
|
-
<Text style={styles.readOnlyText}>Email</Text>
|
|
85
|
-
</View>
|
|
86
|
-
</View>
|
|
87
|
-
|
|
88
|
-
{/* Verification Status */}
|
|
89
|
-
<View style={styles.field}>
|
|
90
|
-
<Text style={styles.label}>Estado de Verificación</Text>
|
|
91
|
-
<View style={styles.readOnlyRow}>
|
|
92
|
-
<Text style={styles.verifiedIcon}>✓</Text>
|
|
93
|
-
<Text style={styles.verifiedText}>Verificado</Text>
|
|
94
|
-
</View>
|
|
95
|
-
</View>
|
|
96
|
-
|
|
97
|
-
{/* Language */}
|
|
98
|
-
<View style={styles.field}>
|
|
99
|
-
<Text style={styles.label}>Idioma</Text>
|
|
100
|
-
<View style={styles.selectWrapper}>
|
|
101
|
-
<Text style={styles.selectIcon}>文</Text>
|
|
102
|
-
<Text style={styles.selectText}>Español</Text>
|
|
103
|
-
<Text style={styles.selectChevron}>⌄</Text>
|
|
104
|
-
</View>
|
|
105
|
-
</View>
|
|
106
|
-
</View>
|
|
107
|
-
|
|
108
|
-
<View style={styles.spacer} />
|
|
109
|
-
</ScrollView>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const styles = StyleSheet.create({
|
|
114
|
-
container: {
|
|
115
|
-
flex: 1,
|
|
116
|
-
backgroundColor: Colors.backgroundSecondary,
|
|
117
|
-
},
|
|
118
|
-
header: {
|
|
119
|
-
padding: 20,
|
|
120
|
-
},
|
|
121
|
-
pageTitle: {
|
|
122
|
-
fontSize: 28,
|
|
123
|
-
fontWeight: '700',
|
|
124
|
-
color: Colors.foreground,
|
|
125
|
-
marginBottom: 8,
|
|
126
|
-
},
|
|
127
|
-
pageSubtitle: {
|
|
128
|
-
fontSize: 15,
|
|
129
|
-
color: Colors.foregroundSecondary,
|
|
130
|
-
lineHeight: 22,
|
|
131
|
-
},
|
|
132
|
-
card: {
|
|
133
|
-
backgroundColor: Colors.card,
|
|
134
|
-
marginHorizontal: 16,
|
|
135
|
-
borderRadius: 12,
|
|
136
|
-
padding: 20,
|
|
137
|
-
borderWidth: 1,
|
|
138
|
-
borderColor: Colors.border,
|
|
139
|
-
},
|
|
140
|
-
cardHeader: {
|
|
141
|
-
flexDirection: 'row',
|
|
142
|
-
alignItems: 'flex-start',
|
|
143
|
-
gap: 12,
|
|
144
|
-
marginBottom: 24,
|
|
145
|
-
},
|
|
146
|
-
cardIcon: {
|
|
147
|
-
fontSize: 20,
|
|
148
|
-
marginTop: 2,
|
|
149
|
-
},
|
|
150
|
-
cardTitle: {
|
|
151
|
-
fontSize: 18,
|
|
152
|
-
fontWeight: '600',
|
|
153
|
-
color: Colors.foreground,
|
|
154
|
-
},
|
|
155
|
-
cardSubtitle: {
|
|
156
|
-
fontSize: 14,
|
|
157
|
-
color: Colors.foregroundSecondary,
|
|
158
|
-
marginTop: 4,
|
|
159
|
-
lineHeight: 20,
|
|
160
|
-
},
|
|
161
|
-
field: {
|
|
162
|
-
marginBottom: 20,
|
|
163
|
-
},
|
|
164
|
-
label: {
|
|
165
|
-
fontSize: 14,
|
|
166
|
-
fontWeight: '500',
|
|
167
|
-
color: Colors.foreground,
|
|
168
|
-
marginBottom: 8,
|
|
169
|
-
},
|
|
170
|
-
input: {
|
|
171
|
-
backgroundColor: Colors.backgroundSecondary,
|
|
172
|
-
borderWidth: 1,
|
|
173
|
-
borderColor: Colors.border,
|
|
174
|
-
borderRadius: 8,
|
|
175
|
-
paddingHorizontal: 14,
|
|
176
|
-
paddingVertical: 12,
|
|
177
|
-
fontSize: 15,
|
|
178
|
-
color: Colors.foreground,
|
|
179
|
-
},
|
|
180
|
-
emailInputWrapper: {
|
|
181
|
-
flexDirection: 'row',
|
|
182
|
-
alignItems: 'center',
|
|
183
|
-
backgroundColor: Colors.backgroundSecondary,
|
|
184
|
-
borderWidth: 1,
|
|
185
|
-
borderColor: Colors.border,
|
|
186
|
-
borderRadius: 8,
|
|
187
|
-
paddingHorizontal: 14,
|
|
188
|
-
},
|
|
189
|
-
emailIcon: {
|
|
190
|
-
fontSize: 16,
|
|
191
|
-
color: Colors.foregroundMuted,
|
|
192
|
-
marginRight: 10,
|
|
193
|
-
},
|
|
194
|
-
emailInput: {
|
|
195
|
-
flex: 1,
|
|
196
|
-
borderWidth: 0,
|
|
197
|
-
paddingHorizontal: 0,
|
|
198
|
-
backgroundColor: 'transparent',
|
|
199
|
-
},
|
|
200
|
-
hint: {
|
|
201
|
-
fontSize: 12,
|
|
202
|
-
color: Colors.foregroundMuted,
|
|
203
|
-
marginTop: 6,
|
|
204
|
-
},
|
|
205
|
-
readOnlyRow: {
|
|
206
|
-
flexDirection: 'row',
|
|
207
|
-
alignItems: 'center',
|
|
208
|
-
gap: 8,
|
|
209
|
-
},
|
|
210
|
-
readOnlyIcon: {
|
|
211
|
-
fontSize: 16,
|
|
212
|
-
color: Colors.foregroundSecondary,
|
|
213
|
-
},
|
|
214
|
-
readOnlyText: {
|
|
215
|
-
fontSize: 15,
|
|
216
|
-
color: Colors.foreground,
|
|
217
|
-
},
|
|
218
|
-
verifiedIcon: {
|
|
219
|
-
fontSize: 16,
|
|
220
|
-
color: Colors.success,
|
|
221
|
-
},
|
|
222
|
-
verifiedText: {
|
|
223
|
-
fontSize: 15,
|
|
224
|
-
color: Colors.success,
|
|
225
|
-
fontWeight: '500',
|
|
226
|
-
},
|
|
227
|
-
selectWrapper: {
|
|
228
|
-
flexDirection: 'row',
|
|
229
|
-
alignItems: 'center',
|
|
230
|
-
backgroundColor: Colors.backgroundSecondary,
|
|
231
|
-
borderWidth: 1,
|
|
232
|
-
borderColor: Colors.border,
|
|
233
|
-
borderRadius: 8,
|
|
234
|
-
paddingHorizontal: 14,
|
|
235
|
-
paddingVertical: 12,
|
|
236
|
-
},
|
|
237
|
-
selectIcon: {
|
|
238
|
-
fontSize: 16,
|
|
239
|
-
color: Colors.foregroundSecondary,
|
|
240
|
-
marginRight: 10,
|
|
241
|
-
},
|
|
242
|
-
selectText: {
|
|
243
|
-
flex: 1,
|
|
244
|
-
fontSize: 15,
|
|
245
|
-
color: Colors.foreground,
|
|
246
|
-
},
|
|
247
|
-
selectChevron: {
|
|
248
|
-
fontSize: 16,
|
|
249
|
-
color: Colors.foregroundSecondary,
|
|
250
|
-
},
|
|
251
|
-
spacer: {
|
|
252
|
-
height: 40,
|
|
253
|
-
},
|
|
254
|
-
})
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Settings Screen
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { View, Text, TouchableOpacity, ScrollView, StyleSheet, Switch } from 'react-native'
|
|
6
|
-
import { useState } from 'react'
|
|
7
|
-
import { router } from 'expo-router'
|
|
8
|
-
import { Colors } from '@/src/constants/colors'
|
|
9
|
-
|
|
10
|
-
interface SettingItem {
|
|
11
|
-
key: string
|
|
12
|
-
label: string
|
|
13
|
-
description?: string
|
|
14
|
-
icon: string
|
|
15
|
-
type: 'navigation' | 'toggle'
|
|
16
|
-
screen?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const SETTINGS_SECTIONS = [
|
|
20
|
-
{
|
|
21
|
-
title: 'Cuenta',
|
|
22
|
-
items: [
|
|
23
|
-
{
|
|
24
|
-
key: 'profile',
|
|
25
|
-
label: 'Información Personal',
|
|
26
|
-
description: 'Nombre, email, idioma',
|
|
27
|
-
icon: '👤',
|
|
28
|
-
type: 'navigation' as const,
|
|
29
|
-
screen: 'profile',
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
key: 'security',
|
|
33
|
-
label: 'Seguridad',
|
|
34
|
-
description: 'Contraseña, autenticación',
|
|
35
|
-
icon: '🔒',
|
|
36
|
-
type: 'navigation' as const,
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
title: 'Preferencias',
|
|
42
|
-
items: [
|
|
43
|
-
{
|
|
44
|
-
key: 'notifications',
|
|
45
|
-
label: 'Notificaciones',
|
|
46
|
-
icon: '🔔',
|
|
47
|
-
type: 'toggle' as const,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
key: 'darkMode',
|
|
51
|
-
label: 'Modo Oscuro',
|
|
52
|
-
icon: '🌙',
|
|
53
|
-
type: 'toggle' as const,
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
title: 'Soporte',
|
|
59
|
-
items: [
|
|
60
|
-
{
|
|
61
|
-
key: 'help',
|
|
62
|
-
label: 'Centro de Ayuda',
|
|
63
|
-
icon: '❓',
|
|
64
|
-
type: 'navigation' as const,
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
key: 'feedback',
|
|
68
|
-
label: 'Enviar Comentarios',
|
|
69
|
-
icon: '💬',
|
|
70
|
-
type: 'navigation' as const,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
]
|
|
75
|
-
|
|
76
|
-
export default function SettingsScreen() {
|
|
77
|
-
const [toggleStates, setToggleStates] = useState<Record<string, boolean>>({
|
|
78
|
-
notifications: true,
|
|
79
|
-
darkMode: false,
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
const handleToggle = (key: string) => {
|
|
83
|
-
setToggleStates((prev) => ({ ...prev, [key]: !prev[key] }))
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const handleNavigation = (item: SettingItem) => {
|
|
87
|
-
if (item.screen) {
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
|
-
router.push(`/(app)/${item.screen}` as any)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<ScrollView style={styles.container}>
|
|
95
|
-
{/* Page Header */}
|
|
96
|
-
<View style={styles.header}>
|
|
97
|
-
<Text style={styles.pageTitle}>Ajustes</Text>
|
|
98
|
-
<Text style={styles.pageSubtitle}>
|
|
99
|
-
Configura tu cuenta y preferencias
|
|
100
|
-
</Text>
|
|
101
|
-
</View>
|
|
102
|
-
|
|
103
|
-
{/* Settings Sections */}
|
|
104
|
-
{SETTINGS_SECTIONS.map((section) => (
|
|
105
|
-
<View key={section.title} style={styles.section}>
|
|
106
|
-
<Text style={styles.sectionTitle}>{section.title}</Text>
|
|
107
|
-
<View style={styles.sectionContent}>
|
|
108
|
-
{section.items.map((item, index) => (
|
|
109
|
-
<TouchableOpacity
|
|
110
|
-
key={item.key}
|
|
111
|
-
style={[
|
|
112
|
-
styles.settingItem,
|
|
113
|
-
index < section.items.length - 1 && styles.settingItemBorder,
|
|
114
|
-
]}
|
|
115
|
-
onPress={() =>
|
|
116
|
-
item.type === 'navigation'
|
|
117
|
-
? handleNavigation(item)
|
|
118
|
-
: handleToggle(item.key)
|
|
119
|
-
}
|
|
120
|
-
activeOpacity={0.7}
|
|
121
|
-
>
|
|
122
|
-
<Text style={styles.settingIcon}>{item.icon}</Text>
|
|
123
|
-
<View style={styles.settingInfo}>
|
|
124
|
-
<Text style={styles.settingLabel}>{item.label}</Text>
|
|
125
|
-
{'description' in item && item.description && (
|
|
126
|
-
<Text style={styles.settingDescription}>
|
|
127
|
-
{item.description}
|
|
128
|
-
</Text>
|
|
129
|
-
)}
|
|
130
|
-
</View>
|
|
131
|
-
{item.type === 'navigation' ? (
|
|
132
|
-
<Text style={styles.chevron}>›</Text>
|
|
133
|
-
) : (
|
|
134
|
-
<Switch
|
|
135
|
-
value={toggleStates[item.key]}
|
|
136
|
-
onValueChange={() => handleToggle(item.key)}
|
|
137
|
-
trackColor={{
|
|
138
|
-
false: Colors.border,
|
|
139
|
-
true: Colors.primary,
|
|
140
|
-
}}
|
|
141
|
-
thumbColor={Colors.background}
|
|
142
|
-
/>
|
|
143
|
-
)}
|
|
144
|
-
</TouchableOpacity>
|
|
145
|
-
))}
|
|
146
|
-
</View>
|
|
147
|
-
</View>
|
|
148
|
-
))}
|
|
149
|
-
|
|
150
|
-
{/* App Version */}
|
|
151
|
-
<View style={styles.footer}>
|
|
152
|
-
<Text style={styles.versionText}>NextSpark Mobile v1.0.0</Text>
|
|
153
|
-
</View>
|
|
154
|
-
|
|
155
|
-
<View style={styles.spacer} />
|
|
156
|
-
</ScrollView>
|
|
157
|
-
)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const styles = StyleSheet.create({
|
|
161
|
-
container: {
|
|
162
|
-
flex: 1,
|
|
163
|
-
backgroundColor: Colors.backgroundSecondary,
|
|
164
|
-
},
|
|
165
|
-
header: {
|
|
166
|
-
padding: 20,
|
|
167
|
-
paddingBottom: 12,
|
|
168
|
-
},
|
|
169
|
-
pageTitle: {
|
|
170
|
-
fontSize: 28,
|
|
171
|
-
fontWeight: '700',
|
|
172
|
-
color: Colors.foreground,
|
|
173
|
-
marginBottom: 4,
|
|
174
|
-
},
|
|
175
|
-
pageSubtitle: {
|
|
176
|
-
fontSize: 15,
|
|
177
|
-
color: Colors.foregroundSecondary,
|
|
178
|
-
},
|
|
179
|
-
section: {
|
|
180
|
-
marginBottom: 24,
|
|
181
|
-
},
|
|
182
|
-
sectionTitle: {
|
|
183
|
-
fontSize: 13,
|
|
184
|
-
fontWeight: '600',
|
|
185
|
-
color: Colors.foregroundSecondary,
|
|
186
|
-
textTransform: 'uppercase',
|
|
187
|
-
letterSpacing: 0.5,
|
|
188
|
-
marginHorizontal: 20,
|
|
189
|
-
marginBottom: 8,
|
|
190
|
-
},
|
|
191
|
-
sectionContent: {
|
|
192
|
-
backgroundColor: Colors.card,
|
|
193
|
-
marginHorizontal: 16,
|
|
194
|
-
borderRadius: 12,
|
|
195
|
-
borderWidth: 1,
|
|
196
|
-
borderColor: Colors.border,
|
|
197
|
-
},
|
|
198
|
-
settingItem: {
|
|
199
|
-
flexDirection: 'row',
|
|
200
|
-
alignItems: 'center',
|
|
201
|
-
paddingVertical: 14,
|
|
202
|
-
paddingHorizontal: 16,
|
|
203
|
-
},
|
|
204
|
-
settingItemBorder: {
|
|
205
|
-
borderBottomWidth: 1,
|
|
206
|
-
borderBottomColor: Colors.border,
|
|
207
|
-
},
|
|
208
|
-
settingIcon: {
|
|
209
|
-
fontSize: 20,
|
|
210
|
-
width: 32,
|
|
211
|
-
},
|
|
212
|
-
settingInfo: {
|
|
213
|
-
flex: 1,
|
|
214
|
-
},
|
|
215
|
-
settingLabel: {
|
|
216
|
-
fontSize: 16,
|
|
217
|
-
color: Colors.foreground,
|
|
218
|
-
fontWeight: '400',
|
|
219
|
-
},
|
|
220
|
-
settingDescription: {
|
|
221
|
-
fontSize: 13,
|
|
222
|
-
color: Colors.foregroundSecondary,
|
|
223
|
-
marginTop: 2,
|
|
224
|
-
},
|
|
225
|
-
chevron: {
|
|
226
|
-
fontSize: 24,
|
|
227
|
-
color: Colors.foregroundMuted,
|
|
228
|
-
fontWeight: '300',
|
|
229
|
-
},
|
|
230
|
-
footer: {
|
|
231
|
-
alignItems: 'center',
|
|
232
|
-
paddingVertical: 20,
|
|
233
|
-
},
|
|
234
|
-
versionText: {
|
|
235
|
-
fontSize: 13,
|
|
236
|
-
color: Colors.foregroundMuted,
|
|
237
|
-
},
|
|
238
|
-
spacer: {
|
|
239
|
-
height: 40,
|
|
240
|
-
},
|
|
241
|
-
})
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Edit Task Screen
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native'
|
|
6
|
-
import { useLocalSearchParams, router } from 'expo-router'
|
|
7
|
-
import { TaskForm } from '@/src/components/entities/tasks'
|
|
8
|
-
import { useTask, useUpdateTask, useDeleteTask, type UpdateTaskInput } from '@/src/entities/tasks'
|
|
9
|
-
|
|
10
|
-
export default function EditTaskScreen() {
|
|
11
|
-
const { id } = useLocalSearchParams<{ id: string }>()
|
|
12
|
-
const { data, isLoading, error } = useTask(id)
|
|
13
|
-
const updateTask = useUpdateTask()
|
|
14
|
-
const deleteTask = useDeleteTask()
|
|
15
|
-
|
|
16
|
-
const handleSubmit = async (formData: UpdateTaskInput) => {
|
|
17
|
-
if (!id) return
|
|
18
|
-
await updateTask.mutateAsync({ id, data: formData })
|
|
19
|
-
router.back()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const handleDelete = async () => {
|
|
23
|
-
if (!id) return
|
|
24
|
-
await deleteTask.mutateAsync(id)
|
|
25
|
-
router.back()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (isLoading) {
|
|
29
|
-
return (
|
|
30
|
-
<View style={styles.centerContainer}>
|
|
31
|
-
<ActivityIndicator size="large" color="#3B82F6" />
|
|
32
|
-
</View>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (error || !data) {
|
|
37
|
-
return (
|
|
38
|
-
<View style={styles.centerContainer}>
|
|
39
|
-
<Text style={styles.errorText}>
|
|
40
|
-
{error instanceof Error ? error.message : 'Task not found'}
|
|
41
|
-
</Text>
|
|
42
|
-
</View>
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<TaskForm
|
|
48
|
-
mode="edit"
|
|
49
|
-
initialData={data.data}
|
|
50
|
-
onSubmit={handleSubmit}
|
|
51
|
-
onDelete={handleDelete}
|
|
52
|
-
isLoading={updateTask.isPending || deleteTask.isPending}
|
|
53
|
-
/>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const styles = StyleSheet.create({
|
|
58
|
-
centerContainer: {
|
|
59
|
-
flex: 1,
|
|
60
|
-
justifyContent: 'center',
|
|
61
|
-
alignItems: 'center',
|
|
62
|
-
backgroundColor: '#F9FAFB',
|
|
63
|
-
},
|
|
64
|
-
errorText: {
|
|
65
|
-
fontSize: 16,
|
|
66
|
-
color: '#DC2626',
|
|
67
|
-
textAlign: 'center',
|
|
68
|
-
paddingHorizontal: 32,
|
|
69
|
-
},
|
|
70
|
-
})
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create Task Screen
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { router } from 'expo-router'
|
|
6
|
-
import { TaskForm } from '@/src/components/entities/tasks'
|
|
7
|
-
import { useCreateTask, type CreateTaskInput } from '@/src/entities/tasks'
|
|
8
|
-
|
|
9
|
-
export default function CreateTaskScreen() {
|
|
10
|
-
const createTask = useCreateTask()
|
|
11
|
-
|
|
12
|
-
const handleSubmit = async (data: CreateTaskInput) => {
|
|
13
|
-
await createTask.mutateAsync(data)
|
|
14
|
-
router.back()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<TaskForm
|
|
19
|
-
mode="create"
|
|
20
|
-
onSubmit={handleSubmit}
|
|
21
|
-
isLoading={createTask.isPending}
|
|
22
|
-
/>
|
|
23
|
-
)
|
|
24
|
-
}
|