forked from TrustUp-app/TrustUp-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCreateAccountScreen.tsx
More file actions
224 lines (209 loc) · 9.33 KB
/
Copy pathCreateAccountScreen.tsx
File metadata and controls
224 lines (209 loc) · 9.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import React, { useEffect } from 'react';
import { View, Text, TextInput, TouchableOpacity, Image, ScrollView } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import { useCreateAccount } from '../../hooks/auth/use-create-account';
// Centralized color palette shared with Tailwind
const colors = require('../../theme/colors.json');
interface CreateAccountScreenProps {
onBack?: () => void;
onSuccess?: () => void;
}
const CreateAccountScreen = ({ onBack, onSuccess }: CreateAccountScreenProps) => {
const {
formState,
errors,
isSubmitting,
showSuccess,
handleWalletAddressChange,
handleUsernameChange,
handleDisplayNameChange,
handleTermsAcceptedChange,
pickImage,
createAccount,
isFormValid,
} = useCreateAccount();
const { profileImage, walletAddress, username, displayName, termsAccepted } = formState;
// Notifies the parent once account creation succeeds. AuthContext's
// completeAuth() (called inside createAccount) already flips the app into
// the signed-in state on its own — this is a courtesy callback for any
// parent-level bookkeeping (e.g. resetting which auth screen was active).
useEffect(() => {
if (showSuccess) {
onSuccess?.();
}
}, [showSuccess, onSuccess]);
return (
<View className="flex-1 bg-background">
{/* Header */}
<View className="flex-row items-center border-b border-gray-100 bg-white px-6 pb-4 pt-12">
<TouchableOpacity onPress={onBack} className="mr-3" accessibilityLabel="Go back">
<Ionicons name="chevron-back" size={24} color={colors.text} />
</TouchableOpacity>
<Text className="text-xl font-bold text-text">Create Account</Text>
</View>
<ScrollView className="flex-1" showsVerticalScrollIndicator={false}>
<View className="px-6 pb-8 pt-8">
{/* Profile Picture Upload */}
<View className="mb-6 items-center">
<View className="relative">
<View className="h-32 w-32 items-center justify-center rounded-full bg-white shadow-sm">
{profileImage ? (
<Image source={{ uri: profileImage }} className="h-32 w-32 rounded-full" />
) : (
<Ionicons name="person-outline" size={48} color={colors.textMuted} />
)}
</View>
<TouchableOpacity
onPress={pickImage}
className="absolute bottom-0 right-0 h-10 w-10 items-center justify-center rounded-full bg-primary shadow-md"
accessibilityLabel="Upload profile picture">
<Ionicons name="cloud-upload-outline" size={20} color="white" />
</TouchableOpacity>
</View>
<Text className="mt-3 text-sm text-textMuted">Upload profile picture (optional)</Text>
{errors.profileImage ? (
<Text className="mt-1 text-xs text-red-500">{errors.profileImage}</Text>
) : null}
</View>
{/* Wallet Address Input */}
<View className="mb-4">
<Text className="mb-2 text-sm text-textMuted">Wallet Address</Text>
<View className="flex-row items-center rounded-xl bg-white px-4 py-4 shadow-sm">
<Ionicons name="wallet-outline" size={20} color={colors.textMuted} className="mr-3" />
<TextInput
placeholder="G..."
placeholderTextColor={colors.placeholder}
value={walletAddress}
onChangeText={handleWalletAddressChange}
className="ml-3 flex-1 text-base text-text"
autoCapitalize="characters"
accessibilityLabel="Wallet address input"
/>
</View>
{errors.walletAddress ? (
<Text className="mt-1 text-xs text-red-500">{errors.walletAddress}</Text>
) : null}
</View>
{/* Username Input */}
<View className="mb-4">
<Text className="mb-2 text-sm text-textMuted">Username</Text>
<View className="flex-row items-center rounded-xl bg-white px-4 py-4 shadow-sm">
<Ionicons name="person-outline" size={20} color={colors.textMuted} className="mr-3" />
<Text className="ml-3 text-base text-text">@</Text>
<TextInput
placeholder="josue_crypto"
placeholderTextColor={colors.placeholder}
value={username}
onChangeText={handleUsernameChange}
className="ml-1 flex-1 text-base text-text"
autoCapitalize="none"
accessibilityLabel="Username input"
/>
</View>
{errors.username ? (
<Text className="mt-1 text-xs text-red-500">{errors.username}</Text>
) : null}
</View>
{/* Display Name Input */}
<View className="mb-6">
<Text className="mb-2 text-sm text-textMuted">Display Name</Text>
<View className="flex-row items-center rounded-xl bg-white px-4 py-4 shadow-sm">
<Ionicons name="person-outline" size={20} color={colors.textMuted} className="mr-3" />
<TextInput
placeholder="Josué Martínez"
placeholderTextColor={colors.placeholder}
value={displayName}
onChangeText={handleDisplayNameChange}
className="ml-3 flex-1 text-base text-text"
accessibilityLabel="Display name input"
/>
</View>
{errors.displayName ? (
<Text className="mt-1 text-xs text-red-500">{errors.displayName}</Text>
) : null}
</View>
{/* Info Box */}
<View className="mb-6 flex-row rounded-xl bg-primarySoft p-4">
<View className="mr-3 h-10 w-10 items-center justify-center rounded-full bg-primaryTint">
<Ionicons name="information" size={24} color="white" />
</View>
<View className="flex-1">
<Text className="mb-1 text-sm font-semibold text-primary">
Your wallet is your identity
</Text>
<Text className="text-xs leading-5 text-primary">
Make sure you have access to your wallet address. This will be used to verify your
transactions and build your reputation.
</Text>
</View>
</View>
{/* Terms & Conditions Checkbox */}
<TouchableOpacity
onPress={() => handleTermsAcceptedChange(!termsAccepted)}
className="mb-6 flex-row items-start"
activeOpacity={0.7}
accessibilityLabel="Accept terms and conditions"
accessibilityRole="checkbox">
<View
className={`h-5 w-5 rounded ${
termsAccepted ? 'bg-primary' : 'border-2 border-gray-300 bg-white'
} mr-3 mt-0.5 items-center justify-center`}>
{termsAccepted && <Ionicons name="checkmark" size={16} color="white" />}
</View>
<Text className="flex-1 text-sm text-textMuted">
By creating an account, you agree to our{' '}
<Text className="font-semibold text-primary">Terms of Service</Text> and{' '}
<Text className="font-semibold text-primary">Privacy Policy</Text>
</Text>
</TouchableOpacity>
{errors.general ? (
<Text className="mb-4 text-center text-sm text-red-500">{errors.general}</Text>
) : null}
{/* Create Account Button */}
<TouchableOpacity
onPress={createAccount}
disabled={!isFormValid() || isSubmitting}
className={`flex-row items-center justify-center rounded-xl py-4 ${
isFormValid() && !isSubmitting ? 'bg-cta' : 'bg-gray-300'
}`}
activeOpacity={0.8}
accessibilityLabel="Create account button">
{isSubmitting ? (
<>
<Text className="mr-2 text-base font-semibold text-white">Creating Account...</Text>
<Ionicons name="hourglass" size={18} color="white" />
</>
) : (
<>
<Text
className={`mr-2 text-base font-semibold ${isFormValid() ? 'text-white' : 'text-gray-500'}`}>
Create Account
</Text>
<Ionicons
name="arrow-forward"
size={18}
color={isFormValid() ? colors.white : colors.textSecondary}
/>
</>
)}
</TouchableOpacity>
</View>
</ScrollView>
{/* Success Notification */}
{showSuccess && (
<View className="absolute left-6 right-6 top-20 flex-row items-center rounded-xl bg-success p-4 shadow-lg">
<View className="mr-3 h-10 w-10 items-center justify-center rounded-full bg-white">
<Ionicons name="checkmark-circle" size={28} color={colors.success} />
</View>
<View className="flex-1">
<Text className="mb-1 text-base font-bold text-white">
Account Created Successfully!
</Text>
<Text className="text-sm text-white">Welcome to TrustUp, @{username}</Text>
</View>
</View>
)}
</View>
);
};
export default CreateAccountScreen;