continue generating flow, add backend connection on main tabs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Platform, View } from "react-native";
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background } from "../../assets";
|
||||
import { gutters, Palette } from "../../styles";
|
||||
@@ -7,8 +7,81 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { BlurView } from "expo-blur";
|
||||
import EditInput from "./components/EditInput";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import { useGlobal } from "reactn";
|
||||
import firebase, { usersRef } from "../../config/firebase";
|
||||
import { goBack } from "../../navigation/NavigationService";
|
||||
import { checkIfEmailIsValid } from "../../actions/signupActions";
|
||||
import { Text } from "react-native";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
|
||||
const ChangeEmailAddress = () => {
|
||||
const [email, setEmail] = useState("");
|
||||
const [originalEmail, setOriginalEmail] = useState("");
|
||||
const [emailError, setEmailError] = useState("");
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
const [currentUserData] = useGlobal("currentUserData");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [currentPassword, setCurrentPassword] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
const authEmail = firebase.auth().currentUser?.email || "";
|
||||
const profileEmail = (currentUserData?.email || authEmail || "").trim();
|
||||
setEmail((prev) => (prev ? prev : profileEmail));
|
||||
setOriginalEmail(profileEmail);
|
||||
}, [currentUserData?.email]);
|
||||
|
||||
const onChangeEmail = (val) => {
|
||||
setEmail(val);
|
||||
const trimmed = (val || "").trim();
|
||||
if (trimmed.length === 0) {
|
||||
setEmailError("");
|
||||
return;
|
||||
}
|
||||
if (!checkIfEmailIsValid({ email: trimmed })) {
|
||||
setEmailError("Adresse email invalide");
|
||||
} else {
|
||||
setEmailError("");
|
||||
}
|
||||
};
|
||||
|
||||
const onSave = async () => {
|
||||
const val = (email || "").trim();
|
||||
if (!val) return;
|
||||
try {
|
||||
setLoading(true);
|
||||
const user = firebase.auth().currentUser;
|
||||
const uid = user?.uid;
|
||||
if (!user || !uid) return;
|
||||
|
||||
// Reauthenticate user with current password before sensitive update
|
||||
try {
|
||||
const credential = firebase.auth.EmailAuthProvider.credential(
|
||||
user.email,
|
||||
currentPassword,
|
||||
);
|
||||
await user.reauthenticateWithCredential(credential);
|
||||
} catch (reauthErr) {
|
||||
throw {
|
||||
code: "auth/wrong-password",
|
||||
message: "Mot de passe incorrect.",
|
||||
};
|
||||
}
|
||||
|
||||
await user.updateEmail(val);
|
||||
await usersRef.doc(uid).set({ email: val }, { merge: true });
|
||||
setTooltip({ type: "success", text: "Email mis à jour" });
|
||||
goBack();
|
||||
} catch (e) {
|
||||
console.log("ChangeEmailAddress error", e?.message);
|
||||
const msg =
|
||||
e?.code === "auth/requires-recent-login"
|
||||
? "Veuillez vous reconnecter pour changer l'adresse email"
|
||||
: e?.message || "Mise à jour impossible";
|
||||
setTooltip({ type: "error", text: msg });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Page
|
||||
headerType="NAVIGATE"
|
||||
@@ -35,15 +108,49 @@ const ChangeEmailAddress = () => {
|
||||
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
||||
}
|
||||
>
|
||||
<EditInput placeholder="Adresse mail" label="Adresse mail" />
|
||||
<EditInput
|
||||
placeholder="Adresse mail"
|
||||
label="Adresse mail"
|
||||
value={email}
|
||||
setValue={onChangeEmail}
|
||||
type="email-address"
|
||||
/>
|
||||
<View style={{ height: 10 }} />
|
||||
<EditInput
|
||||
placeholder="Mot de passe actuel"
|
||||
label="Mot de passe actuel"
|
||||
value={currentPassword}
|
||||
setValue={setCurrentPassword}
|
||||
type="password"
|
||||
/>
|
||||
{!!emailError && (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 12,
|
||||
color: Palette.red,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
marginTop: 6,
|
||||
}}
|
||||
>
|
||||
{emailError}
|
||||
</Text>
|
||||
)}
|
||||
</BlurView>
|
||||
</View>
|
||||
<GradientButton
|
||||
title="Enregistrer les modifications"
|
||||
title={loading ? "Chargement..." : "Enregistrer les modifications"}
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={onSave}
|
||||
disabled={
|
||||
loading ||
|
||||
!email?.trim() ||
|
||||
!!emailError ||
|
||||
email.trim() === originalEmail.trim() ||
|
||||
!currentPassword?.trim()
|
||||
}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { View, Text, Pressable, Platform } from "react-native";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background } from "../../assets";
|
||||
import { gutters, Palette } from "../../styles";
|
||||
@@ -8,8 +8,42 @@ import { BlurView } from "expo-blur";
|
||||
import EditInput from "./components/EditInput";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import { useGlobal } from "reactn";
|
||||
import firebase from "../../config/firebase";
|
||||
import { navigate } from "../../navigation/NavigationService";
|
||||
import { Routes } from "../../navigation";
|
||||
|
||||
const ChangePassword = () => {
|
||||
const [oldPassword, setOldPassword] = useState("");
|
||||
const [newPassword, setNewPassword] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
|
||||
const onSave = async () => {
|
||||
const oldVal = (oldPassword || "").trim();
|
||||
const newVal = (newPassword || "").trim();
|
||||
if (!oldVal || !newVal) return;
|
||||
try {
|
||||
setLoading(true);
|
||||
const user = firebase.auth().currentUser;
|
||||
if (!user?.email) return;
|
||||
|
||||
const credential = firebase.auth.EmailAuthProvider.credential(
|
||||
user.email,
|
||||
oldVal,
|
||||
);
|
||||
await user.reauthenticateWithCredential(credential);
|
||||
await user.updatePassword(newVal);
|
||||
setTooltip({ type: "success", text: "Mot de passe mis à jour" });
|
||||
navigate(Routes.Settings);
|
||||
} catch (e) {
|
||||
console.log("ChangePassword error", e?.message);
|
||||
const msg = e?.message || "Mise à jour impossible";
|
||||
setTooltip({ type: "error", text: msg });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Page
|
||||
headerType="NAVIGATE"
|
||||
@@ -38,9 +72,18 @@ const ChangePassword = () => {
|
||||
}
|
||||
>
|
||||
<EditInput
|
||||
placeholder="Mot de passe"
|
||||
label="Mot de passe"
|
||||
placeholder="Mot de passe actuel"
|
||||
label="Mot de passe actuel"
|
||||
type="password"
|
||||
value={oldPassword}
|
||||
setValue={setOldPassword}
|
||||
/>
|
||||
<EditInput
|
||||
placeholder="Nouveau mot de passe"
|
||||
label="Nouveau mot de passe"
|
||||
type="password"
|
||||
value={newPassword}
|
||||
setValue={setNewPassword}
|
||||
/>
|
||||
<Pressable>
|
||||
<Text
|
||||
@@ -56,11 +99,13 @@ const ChangePassword = () => {
|
||||
</BlurView>
|
||||
</View>
|
||||
<GradientButton
|
||||
title="Enregistrer les modifications"
|
||||
title={loading ? "Chargement..." : "Enregistrer les modifications"}
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={onSave}
|
||||
disabled={loading || !oldPassword?.trim() || !newPassword?.trim()}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { View, Text, Image, TextInput, Platform } from "react-native";
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background, img } from "../../assets";
|
||||
import { gutters, Palette } from "../../styles";
|
||||
@@ -10,8 +10,61 @@ import GradientButton from "../../components/GradientButton";
|
||||
import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { goBack } from "../../navigation/NavigationService";
|
||||
import EditInput from "./components/EditInput";
|
||||
import { useGlobal } from "reactn";
|
||||
import firebase, { usersRef } from "../../config/firebase";
|
||||
|
||||
const EditProfile = () => {
|
||||
const [currentUserData] = useGlobal("currentUserData");
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
|
||||
const [pseudo, setPseudo] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentUserData?.userName && !pseudo) {
|
||||
setPseudo(currentUserData.userName);
|
||||
}
|
||||
}, [currentUserData?.userName]);
|
||||
|
||||
const onSave = async () => {
|
||||
const raw = pseudo || "";
|
||||
const val = raw.trim();
|
||||
if (!val) return;
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const uid = firebase.auth().currentUser?.uid;
|
||||
if (!uid) return;
|
||||
|
||||
// Check uniqueness (case-insensitive)
|
||||
const lower = val.toLowerCase();
|
||||
const snap = await usersRef
|
||||
.where("userNameLower", "==", lower)
|
||||
.limit(1)
|
||||
.get();
|
||||
if (!snap.empty && snap.docs[0].id !== uid) {
|
||||
setTooltip({ text: "Ce pseudo est déjà pris", type: "error" });
|
||||
return;
|
||||
}
|
||||
|
||||
await usersRef.doc(uid).set(
|
||||
{
|
||||
userName: val,
|
||||
userNameLower: lower,
|
||||
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
|
||||
},
|
||||
{ merge: true },
|
||||
);
|
||||
|
||||
setTooltip({ text: "Pseudo mis à jour", type: "success" });
|
||||
goBack();
|
||||
} catch (e) {
|
||||
console.log("EditProfile onSave error", e?.message);
|
||||
setTooltip({ text: e?.message || "Mise à jour impossible", type: "error" });
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Page
|
||||
headerType="NAVIGATE"
|
||||
@@ -56,15 +109,16 @@ const EditProfile = () => {
|
||||
Modifier la photo
|
||||
</Text>
|
||||
</View>
|
||||
<EditInput label="Pseudo" placeholder="Pseudo" />
|
||||
<EditInput label="Pseudo" placeholder="Pseudo" value={pseudo} setValue={setPseudo} />
|
||||
|
||||
<GradientButton
|
||||
title="Enregistrer les modifications"
|
||||
title={loading ? "Chargement..." : "Enregistrer les modifications"}
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
}}
|
||||
onPress={goBack}
|
||||
onPress={onSave}
|
||||
disabled={loading || !pseudo?.trim() || pseudo?.trim() === (currentUserData?.userName || "")}
|
||||
/>
|
||||
</BlurView>
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React from "reactn";
|
||||
import React, { useEffect, useGlobal } from "reactn";
|
||||
import Page from "../../layouts/Page";
|
||||
import { gutters, Palette, Style } from "../../styles";
|
||||
import { background } from "../../assets";
|
||||
@@ -8,11 +8,33 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import { BlurView } from "expo-blur";
|
||||
import Switch from "../../components/Switch";
|
||||
import { useState } from "react";
|
||||
import firebase, { usersRef } from "../../config/firebase";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
|
||||
export default (props) => {
|
||||
const [currentUID] = useGlobal("currentUID");
|
||||
const [currentUserData] = useGlobal("currentUserData");
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
|
||||
const [isSwitch, setIsSwitch] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsSwitch(!!currentUserData?.notifications);
|
||||
}, [currentUserData?.notifications]);
|
||||
|
||||
const onToggle = async (next) => {
|
||||
try {
|
||||
setIsSwitch(next);
|
||||
const uid = currentUID || firebase.auth().currentUser?.uid;
|
||||
if (!uid) return;
|
||||
await usersRef.doc(uid).set({ notifications: next }, { merge: true });
|
||||
setTooltip({ type: "success", text: "Préférence enregistrée" });
|
||||
} catch (e) {
|
||||
setIsSwitch(!next);
|
||||
setTooltip({ type: "error", text: e?.message || "Enregistrement impossible" });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Page
|
||||
headerType="NAVIGATE"
|
||||
@@ -50,7 +72,7 @@ export default (props) => {
|
||||
>
|
||||
Notifications
|
||||
</Text>
|
||||
<Switch value={isSwitch} setValue={setIsSwitch} />
|
||||
<Switch value={isSwitch} setValue={onToggle} />
|
||||
</View>
|
||||
<Text
|
||||
style={{
|
||||
|
||||
+119
-18
@@ -15,15 +15,25 @@ import { responsiveHeight } from "react-native-responsive-dimensions";
|
||||
import Style, { gutters, size } from "../../styles/Style";
|
||||
import { Palette } from "../../styles";
|
||||
import { FONT_FAMILY } from "../../styles/Fonts";
|
||||
import GradientButton from "../../components/GradientButton";
|
||||
import BorderGradient from "../../components/BorderGradient/BorderGradient";
|
||||
import MusicCard from "../Library/components/MusicCard";
|
||||
import { useUser } from "../../providers/UserDataProvider";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { navigate } from "../../navigation/NavigationService";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useGlobal } from "reactn";
|
||||
import Animated, { Easing, FadeIn, FadeOut } from "react-native-reanimated";
|
||||
import alert from "../../components/Alert";
|
||||
import { projectsRef } from "../../config/firebase";
|
||||
|
||||
const Profile = () => {
|
||||
const [selected, setSelected] = useState("Chansons");
|
||||
const [currentUserData] = useGlobal("currentUserData");
|
||||
const { userProjects } = useUser();
|
||||
const [, setTooltip] = useGlobal("_tooltip");
|
||||
const [menuTop, setMenuTop] = useState(0);
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const [selectedProjectId, setSelectedProjectId] = useState(null);
|
||||
|
||||
const onPressMenu = (item) => {
|
||||
setSelected(item);
|
||||
@@ -74,31 +84,29 @@ const Profile = () => {
|
||||
fontFamily: FONT_FAMILY.InterSemiBold,
|
||||
}}
|
||||
>
|
||||
elia.mrn
|
||||
{currentUserData?.userName}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ ...Style.containerRow, gap: 10, marginTop: 10 }}>
|
||||
<View style={{ flex: 1, alignItems: "center" }}>
|
||||
<Text style={styles.value}>0</Text>
|
||||
<Text style={styles.value}>
|
||||
{currentUserData?.playlist?.length || 0}
|
||||
</Text>
|
||||
<Text style={styles.label}>playbacks</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1, alignItems: "center" }}>
|
||||
<Text style={styles.value}>880</Text>
|
||||
<Text style={styles.value}>
|
||||
{currentUserData?.followBy?.length || 0}
|
||||
</Text>
|
||||
<Text style={styles.label}>abonnés</Text>
|
||||
</View>
|
||||
<View style={{ flex: 1, alignItems: "center" }}>
|
||||
<Text style={styles.value}>6</Text>
|
||||
<Text style={styles.value}>
|
||||
{currentUserData?.following?.length || 0}
|
||||
</Text>
|
||||
<Text style={styles.label}>abonnements</Text>
|
||||
</View>
|
||||
</View>
|
||||
<GradientButton
|
||||
title="Suivre"
|
||||
containerStyle={{
|
||||
width: "80%",
|
||||
alignSelf: "center",
|
||||
marginTop: 18,
|
||||
}}
|
||||
/>
|
||||
</BlurView>
|
||||
</View>
|
||||
<View
|
||||
@@ -176,20 +184,113 @@ const Profile = () => {
|
||||
{selected === "Chansons" && (
|
||||
<View style={{ flex: 1 }}>
|
||||
<FlatList
|
||||
data={Array.from({ length: 3 })}
|
||||
data={Array.isArray(userProjects) ? userProjects : []}
|
||||
contentContainerStyle={{
|
||||
gap: 10,
|
||||
}}
|
||||
renderItem={() => (
|
||||
keyExtractor={(item) => item.id}
|
||||
renderItem={({ item }) => (
|
||||
<MusicCard
|
||||
title={item?.title || "Sans titre"}
|
||||
subtitle={currentUserData?.userName || "MusicLand"}
|
||||
imageUri={item?.coverUrl || null}
|
||||
projectId={item?.id}
|
||||
likedBy={item?.likedBy || []}
|
||||
onPress={() =>
|
||||
navigate(Routes.MusicDetails, {
|
||||
action: "userProfile",
|
||||
})
|
||||
navigate(Routes.MusicDetails, { projectId: item.id })
|
||||
}
|
||||
onPressMore={(posTop) => {
|
||||
setSelectedProjectId(item.id);
|
||||
if (showMenu) {
|
||||
if (posTop === menuTop) {
|
||||
setShowMenu(false);
|
||||
} else {
|
||||
setShowMenu(false);
|
||||
setTimeout(() => {
|
||||
setMenuTop(posTop);
|
||||
setShowMenu(true);
|
||||
}, 200);
|
||||
}
|
||||
} else {
|
||||
setMenuTop(posTop);
|
||||
setShowMenu(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{showMenu && (
|
||||
<Animated.View
|
||||
entering={FadeIn.duration(200).easing(Easing.ease)}
|
||||
exiting={FadeOut.duration(200).easing(Easing.ease)}
|
||||
style={{ position: "absolute", right: 0, top: menuTop, zIndex: 2 }}
|
||||
>
|
||||
<BlurView
|
||||
intensity={20}
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 10,
|
||||
backgroundColor: Palette.glass,
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
gap: 10,
|
||||
}}
|
||||
experimentalBlurMethod={
|
||||
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
|
||||
}
|
||||
>
|
||||
<Pressable onPress={() => setShowMenu(false)}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
Annuler
|
||||
</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
setShowMenu(false);
|
||||
alert(
|
||||
"Confirmer la suppression",
|
||||
"Cette action supprimera définitivement ce projet.",
|
||||
[
|
||||
{ text: "Annuler", style: "cancel", onPress: () => {} },
|
||||
{
|
||||
text: "Supprimer",
|
||||
onPress: async () => {
|
||||
try {
|
||||
if (!selectedProjectId) return;
|
||||
await projectsRef.doc(selectedProjectId).delete();
|
||||
setTooltip({ type: "success", text: "Projet supprimé" });
|
||||
} catch (e) {
|
||||
setTooltip({
|
||||
type: "error",
|
||||
text: e?.message || "Suppression impossible",
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
{ cancelable: true },
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: Palette.white,
|
||||
fontFamily: FONT_FAMILY.InterRegular,
|
||||
}}
|
||||
>
|
||||
Supprimer
|
||||
</Text>
|
||||
</Pressable>
|
||||
</BlurView>
|
||||
</Animated.View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { View, Text } from "react-native";
|
||||
import { View } from "react-native";
|
||||
import React from "react";
|
||||
import Page from "../../layouts/Page";
|
||||
import { background } from "../../assets";
|
||||
@@ -9,6 +9,7 @@ import BorderGradientButton from "../../components/BorderGradientButton";
|
||||
import { SheetManager } from "react-native-actions-sheet";
|
||||
import { navigate } from "../../navigation/NavigationService";
|
||||
import { Routes } from "../../navigation";
|
||||
import { useUserData } from "../../providers/UserDataProvider";
|
||||
|
||||
const SETTINGS = [
|
||||
{
|
||||
@@ -42,6 +43,17 @@ const SETTINGS = [
|
||||
];
|
||||
|
||||
const Settings = () => {
|
||||
const { onSignOut } = useUserData();
|
||||
|
||||
const handleSignOut = async () => {
|
||||
try {
|
||||
await onSignOut();
|
||||
} catch (e) {
|
||||
console.log("Sign out error", e?.message);
|
||||
} finally {
|
||||
navigate(Routes.Login);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Page
|
||||
headerType="NAVIGATION"
|
||||
@@ -65,10 +77,7 @@ const Settings = () => {
|
||||
))}
|
||||
</View>
|
||||
<View style={{ width: "80%", gap: 5, alignSelf: "center" }}>
|
||||
<BorderGradientButton
|
||||
title="Déconnexion"
|
||||
onPress={() => navigate(Routes.Login)}
|
||||
/>
|
||||
<BorderGradientButton title="Déconnexion" onPress={handleSignOut} />
|
||||
<BorderGradientButton
|
||||
title="Supprimer mon profil"
|
||||
titleStyle={{
|
||||
|
||||
@@ -12,7 +12,7 @@ import { FONT_FAMILY } from "../../../styles/Fonts";
|
||||
import { BlurView } from "expo-blur";
|
||||
import { icons } from "../../../assets";
|
||||
|
||||
const EditInput = ({ label = "", placeholder = "", type = "default" }) => {
|
||||
const EditInput = ({ label = "", placeholder = "", type = "default", value = "", setValue = () => {} }) => {
|
||||
const [showPassword, setShowPassword] = useState(false);
|
||||
|
||||
return (
|
||||
@@ -65,6 +65,8 @@ const EditInput = ({ label = "", placeholder = "", type = "default" }) => {
|
||||
flex: 1,
|
||||
}}
|
||||
keyboardType={type}
|
||||
value={value}
|
||||
onChangeText={setValue}
|
||||
{...(type === "password" && {
|
||||
secureTextEntry: !showPassword,
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user