203 lines
5.8 KiB
TypeScript
203 lines
5.8 KiB
TypeScript
import React, { useState } from "react";
|
|
import {
|
|
View,
|
|
Text,
|
|
TextInput,
|
|
StyleSheet,
|
|
TouchableOpacity,
|
|
KeyboardAvoidingView,
|
|
Platform,
|
|
Keyboard,
|
|
TouchableWithoutFeedback,
|
|
} from "react-native";
|
|
import { useDispatch, useSelector } from "react-redux";
|
|
import { RootState } from "@/store";
|
|
import { Formik } from "formik";
|
|
import * as Yup from "yup";
|
|
import api from "@/services/axiosClient";
|
|
import { BASE_URL } from "@/constants/config";
|
|
import { setUserData } from "@/store/userSlice";
|
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
import { router } from "expo-router";
|
|
import { useSnackbar } from "@/contexts/Snackbar";
|
|
import Header from "@/components/common/Header";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Overlay } from "@/components/common/Overlay";
|
|
|
|
export default function EditName() {
|
|
const { data } = useSelector((state: RootState) => state.user);
|
|
const [isLoading, setIsLoading] = useState<boolean>();
|
|
const originalName = data?.name || "";
|
|
const dispatch = useDispatch();
|
|
const insets = useSafeAreaInsets();
|
|
const nameSchema = Yup.object().shape({
|
|
name: Yup.string()
|
|
.required("Name is required")
|
|
.max(57, "Name cannot exceed 57 characters"),
|
|
});
|
|
const { showSnackbar } = useSnackbar();
|
|
|
|
const { t } = useTranslation();
|
|
const handleSave = async (values: { name: string }) => {
|
|
try {
|
|
setIsLoading(true);
|
|
await api.put(`${BASE_URL}/api/v1/update-user-information`, {
|
|
name: values.name,
|
|
mobile: data?.mobile,
|
|
});
|
|
|
|
dispatch(setUserData({ name: values.name }));
|
|
showSnackbar(`${t("profile.name-changed")}`, "success");
|
|
router.back();
|
|
} catch (error) {
|
|
showSnackbar(`${t("common.something-went-wrong")}`, "error");
|
|
console.error("Error updating name:", error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Header title={t("profile.edit-name")} showBackButton={true} />
|
|
<KeyboardAvoidingView
|
|
style={styles.container}
|
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
>
|
|
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
|
|
<View style={styles.inner}>
|
|
<Formik
|
|
initialValues={{ name: originalName }}
|
|
validationSchema={nameSchema}
|
|
onSubmit={handleSave}
|
|
enableReinitialize
|
|
>
|
|
{({
|
|
handleChange,
|
|
handleBlur,
|
|
handleSubmit,
|
|
values,
|
|
touched,
|
|
errors,
|
|
}) => {
|
|
const hasChanged = values.name !== originalName;
|
|
const hasError = !!errors.name;
|
|
|
|
return (
|
|
<View style={styles.formContainer}>
|
|
<View style={styles.inputContainer}>
|
|
<Text style={styles.label}>
|
|
{t("profile.enter-name")}
|
|
</Text>
|
|
<TextInput
|
|
style={[
|
|
styles.input,
|
|
{
|
|
borderColor:
|
|
touched.name && errors.name
|
|
? "#D51D10"
|
|
: "#D8DDE7",
|
|
},
|
|
]}
|
|
value={values.name}
|
|
onChangeText={handleChange("name")}
|
|
onBlur={handleBlur("name")}
|
|
placeholder="Enter your name"
|
|
placeholderTextColor="#949CAC"
|
|
/>
|
|
{touched.name && errors.name && (
|
|
<Text style={styles.error}>{errors.name}</Text>
|
|
)}
|
|
</View>
|
|
|
|
<TouchableOpacity
|
|
onPress={handleSubmit as unknown as () => void}
|
|
style={[
|
|
styles.button,
|
|
hasChanged && !hasError
|
|
? styles.buttonEnabled
|
|
: styles.buttonDisabled,
|
|
{ marginBottom: insets.bottom },
|
|
]}
|
|
disabled={!hasChanged || hasError}
|
|
>
|
|
<Text style={styles.buttonText}>{t("profile.save")}</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
);
|
|
}}
|
|
</Formik>
|
|
</View>
|
|
</TouchableWithoutFeedback>
|
|
</KeyboardAvoidingView>
|
|
<Overlay isUploading={isLoading ?? false} />
|
|
</>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: "#F3F5F8",
|
|
paddingHorizontal: 16,
|
|
},
|
|
inner: {
|
|
flex: 1,
|
|
justifyContent: "space-between",
|
|
backgroundColor: "#F3F5F8",
|
|
},
|
|
formContainer: {
|
|
flex: 1,
|
|
},
|
|
inputContainer: {
|
|
marginBottom: 24,
|
|
},
|
|
label: {
|
|
fontSize: 14,
|
|
marginBottom: 8,
|
|
color: "#252A34",
|
|
fontFamily: "Inter",
|
|
lineHeight: 20,
|
|
},
|
|
input: {
|
|
backgroundColor: "#ffffff",
|
|
borderRadius: 4,
|
|
borderWidth: 1,
|
|
height: 40,
|
|
paddingHorizontal: 8,
|
|
fontSize: 14,
|
|
fontFamily: "Inter",
|
|
fontWeight: "500",
|
|
lineHeight: 20,
|
|
},
|
|
error: {
|
|
marginTop: 8,
|
|
color: "#D51D10",
|
|
fontSize: 12,
|
|
fontFamily: "Inter",
|
|
fontWeight: "bold",
|
|
lineHeight: 20,
|
|
},
|
|
button: {
|
|
height: 48,
|
|
borderRadius: 4,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
width: "100%",
|
|
paddingHorizontal: 16,
|
|
},
|
|
buttonEnabled: {
|
|
backgroundColor: "#008761",
|
|
},
|
|
buttonDisabled: {
|
|
backgroundColor: "#B0B7C5", // from Figma: rgba(176, 183, 197)
|
|
},
|
|
buttonText: {
|
|
color: "#FCFCFC",
|
|
fontSize: 14,
|
|
fontFamily: "Inter",
|
|
fontWeight: "bold",
|
|
lineHeight: 20,
|
|
},
|
|
});
|