moved files to monorepo and updated controllers to start with /api
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
View, Text, TextInput, TouchableOpacity,
|
||||
ActivityIndicator, ScrollView, useColorScheme,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
|
||||
export default function EditProfile({ onClose }: { onClose: () => void }) {
|
||||
const dark = useColorScheme() === "dark";
|
||||
const accent = dark ? "#E07B45" : "#C4622D";
|
||||
const { user, updateUser } = useAuth();
|
||||
|
||||
const [newEmail, setNewEmail] = useState("");
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [confirmPass, setConfirmPass] = useState("");
|
||||
const [showPass, setShowPass] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [success, setSuccess] = useState("");
|
||||
|
||||
const inputClass = `rounded-xl px-4 py-3.5 text-sm font-sans border ${
|
||||
dark
|
||||
? "bg-obsidian-100 border-border-dark text-ink-dark"
|
||||
: "bg-parchment-100 border-border-light text-ink-light"
|
||||
}`;
|
||||
|
||||
const save = async () => {
|
||||
setError("");
|
||||
setSuccess("");
|
||||
|
||||
if (newPassword && newPassword !== confirmPass) {
|
||||
setError("Passwords don't match.");
|
||||
return;
|
||||
}
|
||||
if (!newEmail && !newPassword) {
|
||||
setError("Enter a new email or password to update.");
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
await updateUser(
|
||||
newEmail || undefined,
|
||||
newPassword || undefined,
|
||||
);
|
||||
setSuccess("Profile updated successfully.");
|
||||
setNewEmail("");
|
||||
setNewPassword("");
|
||||
setConfirmPass("");
|
||||
} catch (e: any) {
|
||||
setError(e.message ?? "Update failed. Please try again.");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView className={`flex-1 ${dark ? "bg-obsidian-200" : "bg-parchment-50"}`}>
|
||||
{/* Header */}
|
||||
<View className={`flex-row items-center px-4 py-4 border-b ${
|
||||
dark ? "border-border-dark" : "border-border-light"
|
||||
}`}>
|
||||
<Text className={`flex-1 text-xl font-display font-bold ${dark ? "text-ink-dark" : "text-ink-light"}`}>
|
||||
Edit Profile
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress={onClose}
|
||||
className={`w-8 h-8 rounded-full items-center justify-center ${dark ? "bg-obsidian-50" : "bg-parchment-200"}`}
|
||||
>
|
||||
<Ionicons name="close" size={18} color={dark ? "#706D67" : "#8A8278"} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView
|
||||
contentContainerStyle={{ padding: 16, paddingBottom: 40 }}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
{/* Current email (read-only) */}
|
||||
<View className={`mb-5 px-4 py-3.5 rounded-xl border ${
|
||||
dark ? "bg-obsidian-50 border-border-dark" : "bg-parchment-200 border-border-light"
|
||||
}`}>
|
||||
<Text className={`text-xs font-sans font-semibold mb-0.5 ${dark ? "text-muted-dark" : "text-muted-light"}`}>
|
||||
CURRENT EMAIL
|
||||
</Text>
|
||||
<Text className={`text-sm font-sans ${dark ? "text-ink-dark" : "text-ink-light"}`}>
|
||||
{user?.email}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Change email
|
||||
TODO fix this show if email is taken and there is also a bug when trying to
|
||||
change email many times ill fix it later if i feel like it or someone else can
|
||||
*/}
|
||||
<Text className={`text-xs font-sans font-semibold mb-1.5 ${dark ? "text-muted-dark" : "text-muted-light"}`}>
|
||||
NEW EMAIL
|
||||
</Text>
|
||||
<TextInput
|
||||
className={`${inputClass} mb-5`}
|
||||
placeholder="Leave blank to keep current"
|
||||
placeholderTextColor={dark ? "#706D67" : "#8A8278"}
|
||||
value={newEmail}
|
||||
onChangeText={setNewEmail}
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
autoComplete="email"
|
||||
/>
|
||||
|
||||
{/* Divider */}
|
||||
<View className={`h-px mb-5 ${dark ? "bg-border-dark" : "bg-border-light"}`} />
|
||||
|
||||
{/* New password */}
|
||||
<Text className={`text-xs font-sans font-semibold mb-1.5 ${dark ? "text-muted-dark" : "text-muted-light"}`}>
|
||||
NEW PASSWORD
|
||||
</Text>
|
||||
<View className="relative mb-3">
|
||||
<TextInput
|
||||
className={inputClass}
|
||||
placeholder="Leave blank to keep current"
|
||||
placeholderTextColor={dark ? "#706D67" : "#8A8278"}
|
||||
value={newPassword}
|
||||
onChangeText={setNewPassword}
|
||||
secureTextEntry={!showPass}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
onPress={() => setShowPass((v) => !v)}
|
||||
className="absolute right-3 top-3.5"
|
||||
>
|
||||
<Ionicons
|
||||
name={showPass ? "eye-off-outline" : "eye-outline"}
|
||||
size={18}
|
||||
color={dark ? "#706D67" : "#8A8278"}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Confirm password */}
|
||||
<Text className={`text-xs font-sans font-semibold mb-1.5 ${dark ? "text-muted-dark" : "text-muted-light"}`}>
|
||||
CONFIRM NEW PASSWORD
|
||||
</Text>
|
||||
<TextInput
|
||||
className={`${inputClass} mb-5`}
|
||||
placeholder="Repeat new password"
|
||||
placeholderTextColor={dark ? "#706D67" : "#8A8278"}
|
||||
value={confirmPass}
|
||||
onChangeText={setConfirmPass}
|
||||
secureTextEntry={!showPass}
|
||||
/>
|
||||
|
||||
{/* Error */}
|
||||
{error !== "" && (
|
||||
<View className="mb-4 px-3 py-2.5 rounded-xl bg-red-500/10 border border-red-500/20">
|
||||
<Text className="text-xs font-sans text-red-500">{error}</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Success */}
|
||||
{success !== "" && (
|
||||
<View className="mb-4 px-3 py-2.5 rounded-xl"
|
||||
style={{ backgroundColor: dark ? "#2E9E6B20" : "#2E9E6B15",
|
||||
borderWidth: 1, borderColor: "#2E9E6B30" }}>
|
||||
<Text className="text-xs font-sans" style={{ color: "#2E9E6B" }}>
|
||||
{success}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Save button */}
|
||||
<TouchableOpacity
|
||||
onPress={save}
|
||||
disabled={loading}
|
||||
className="py-4 rounded-2xl items-center"
|
||||
style={{ backgroundColor: accent }}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{loading
|
||||
? <ActivityIndicator color="#fff" />
|
||||
: <Text className="text-sm font-sans font-semibold text-white">Save changes</Text>
|
||||
}
|
||||
</TouchableOpacity>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user