@towsila/expo-ui-library 1.0.0

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.
Files changed (104) hide show
  1. package/README.md +142 -0
  2. package/package.json +55 -0
  3. package/src/assets/customIcons/arrow.svg +3 -0
  4. package/src/assets/customIcons/arrow_back.svg +3 -0
  5. package/src/assets/customIcons/ban.svg +4 -0
  6. package/src/assets/customIcons/checkmark.svg +4 -0
  7. package/src/assets/customIcons/close.svg +5 -0
  8. package/src/assets/customIcons/dark_mode.svg +3 -0
  9. package/src/assets/customIcons/dark_suspended.svg +67 -0
  10. package/src/assets/customIcons/document.svg +4 -0
  11. package/src/assets/customIcons/email.svg +3 -0
  12. package/src/assets/customIcons/eye.svg +5 -0
  13. package/src/assets/customIcons/eye_off.svg +7 -0
  14. package/src/assets/customIcons/humberger.svg +5 -0
  15. package/src/assets/customIcons/information.svg +6 -0
  16. package/src/assets/customIcons/light_mode.svg +18 -0
  17. package/src/assets/customIcons/light_suspended.svg +67 -0
  18. package/src/assets/customIcons/lock_closed.svg +4 -0
  19. package/src/assets/customIcons/logout.svg +4 -0
  20. package/src/assets/customIcons/person.svg +4 -0
  21. package/src/assets/customIcons/phone.svg +3 -0
  22. package/src/assets/customIcons/phone_dark.svg +36 -0
  23. package/src/assets/customIcons/phone_light.svg +36 -0
  24. package/src/assets/customIcons/shield.svg +4 -0
  25. package/src/assets/customIcons/trash.svg +9 -0
  26. package/src/assets/customIcons/warning.svg +5 -0
  27. package/src/assets/icons/google.svg +9 -0
  28. package/src/assets/images/bg_dark.svg +5 -0
  29. package/src/assets/images/bg_dark_v1.svg +5 -0
  30. package/src/assets/images/bg_light.svg +5 -0
  31. package/src/assets/images/bg_light_v1.svg +5 -0
  32. package/src/assets/images/en.jpg +0 -0
  33. package/src/assets/images/fr.jpg +0 -0
  34. package/src/components/icons/ban.tsx +77 -0
  35. package/src/components/icons/chatIcon.tsx +19 -0
  36. package/src/components/icons/homeIcon.tsx +25 -0
  37. package/src/components/icons/profileIcon.tsx +29 -0
  38. package/src/components/icons/settingsIcon.tsx +22 -0
  39. package/src/components/reusable/templatePage.tsx +94 -0
  40. package/src/components/reusable/templateSubPage.tsx +66 -0
  41. package/src/components/screens/AccountStatusScreen.tsx +102 -0
  42. package/src/components/screens/AddReportScreen.tsx +135 -0
  43. package/src/components/screens/LegalScreen.tsx +41 -0
  44. package/src/components/screens/VerificationCodeScreen.tsx +66 -0
  45. package/src/components/screens/aboutScreen.tsx +139 -0
  46. package/src/components/screens/forgotPasswordScreen.tsx +60 -0
  47. package/src/components/screens/loginScreen.tsx +165 -0
  48. package/src/components/screens/onBoarding.tsx +178 -0
  49. package/src/components/screens/resetPassword.tsx +115 -0
  50. package/src/components/screens/settingScreen.tsx +85 -0
  51. package/src/components/screens/signUpScreen.tsx +119 -0
  52. package/src/components/screens/splashScreen.tsx +170 -0
  53. package/src/components/ui/OTPInput.tsx +73 -0
  54. package/src/components/ui/PageTopBar.tsx +41 -0
  55. package/src/components/ui/asidebar.tsx +151 -0
  56. package/src/components/ui/badge.tsx +21 -0
  57. package/src/components/ui/button.tsx +58 -0
  58. package/src/components/ui/customPopup.tsx +176 -0
  59. package/src/components/ui/dynamicForm.tsx +144 -0
  60. package/src/components/ui/error.tsx +23 -0
  61. package/src/components/ui/input.tsx +121 -0
  62. package/src/components/ui/languageSelect.tsx +99 -0
  63. package/src/components/ui/pageIndicator.tsx +58 -0
  64. package/src/components/ui/passwordRequirmentCard.tsx +55 -0
  65. package/src/components/ui/sharpButton.tsx +67 -0
  66. package/src/components/ui/sharpContainer.tsx +180 -0
  67. package/src/components/ui/sharpDynamicForm.tsx +148 -0
  68. package/src/components/ui/sharpInput.tsx +148 -0
  69. package/src/components/ui/sharpOtpInput.tsx +228 -0
  70. package/src/components/ui/sharpSelect.tsx +155 -0
  71. package/src/components/ui/successDialog.tsx +97 -0
  72. package/src/components/ui/termsPopup.tsx +56 -0
  73. package/src/components/ui/themeToggle.tsx +98 -0
  74. package/src/components/ui/toast.tsx +163 -0
  75. package/src/components/ui/warningModel.tsx +132 -0
  76. package/src/constants/language.ts +15 -0
  77. package/src/context/LanguageContext.tsx +49 -0
  78. package/src/context/LocationPermissionProvider.tsx +106 -0
  79. package/src/context/ThemeContext.tsx +70 -0
  80. package/src/hooks/useCountdown.ts +21 -0
  81. package/src/hooks/useForgotPasswordForm.ts +46 -0
  82. package/src/hooks/useForm.ts +52 -0
  83. package/src/hooks/useLoginForm.ts +25 -0
  84. package/src/hooks/useResetPasswordForm.ts +75 -0
  85. package/src/hooks/useSignup.tsx +34 -0
  86. package/src/hooks/useSubmitReport.ts +47 -0
  87. package/src/hooks/useUpdateUser.tsx +81 -0
  88. package/src/icons/index.ts +36 -0
  89. package/src/index.ts +62 -0
  90. package/src/service/createApi.ts +57 -0
  91. package/src/service/sendEmail.ts +11 -0
  92. package/src/tokens/themes.ts +19 -0
  93. package/src/tokens/typography.ts +16 -0
  94. package/src/types/formFields.ts +13 -0
  95. package/src/types/icon.ts +6 -0
  96. package/src/types/language.ts +7 -0
  97. package/src/types/menu.ts +9 -0
  98. package/src/types/settingsFields.tsx +9 -0
  99. package/src/types/svg.d.ts +6 -0
  100. package/src/types/validateForm.ts +8 -0
  101. package/src/utils/helpers/groupSettings.ts +21 -0
  102. package/src/utils/inputValidator/customValidator.ts +36 -0
  103. package/src/utils/inputValidator/generalTerms.ts +19 -0
  104. package/src/utils/inputValidator/registerValidator.ts +31 -0
@@ -0,0 +1,106 @@
1
+ import * as Location from "expo-location";
2
+ import {
3
+ createContext,
4
+ useContext,
5
+ useEffect,
6
+ useCallback,
7
+ useRef,
8
+ useState,
9
+ ReactNode,
10
+ } from "react";
11
+
12
+ type Coords = {
13
+ latitude: number;
14
+ longitude: number;
15
+ } | null;
16
+
17
+ type LocationPermissionContextType = {
18
+ granted: boolean | null; // null = still checking
19
+ coords: Coords;
20
+ recheck: () => Promise<void>;
21
+ };
22
+
23
+ const LocationPermissionContext = createContext<
24
+ LocationPermissionContextType | undefined
25
+ >(undefined);
26
+
27
+ export const LocationPermissionProvider = ({
28
+ children,
29
+ }: {
30
+ children: ReactNode;
31
+ }) => {
32
+ const [granted, setGranted] = useState<boolean | null>(null);
33
+ const [coords, setCoords] = useState<Coords>(null);
34
+ const subscriptionRef = useRef<Location.LocationSubscription | null>(null);
35
+
36
+ const startWatching = useCallback(async () => {
37
+ subscriptionRef.current?.remove();
38
+
39
+ subscriptionRef.current = await Location.watchPositionAsync(
40
+ {
41
+ accuracy: Location.Accuracy.Balanced,
42
+ timeInterval: 5000,
43
+ distanceInterval: 20,
44
+ },
45
+ (location) => {
46
+ setCoords({
47
+ latitude: location.coords.latitude,
48
+ longitude: location.coords.longitude,
49
+ });
50
+ }
51
+ );
52
+ }, []);
53
+
54
+ const recheck = useCallback(async () => {
55
+ const { status } = await Location.getForegroundPermissionsAsync();
56
+ console.log("CURRENT PERMISSION STATUS:", status);
57
+ let finalStatus = status;
58
+ if (status !== "granted") {
59
+ const { status: newStatus } =
60
+ await Location.requestForegroundPermissionsAsync();
61
+ finalStatus = newStatus;
62
+ }
63
+
64
+ const isGranted = finalStatus === "granted";
65
+ setGranted(isGranted);
66
+
67
+ if (isGranted) {
68
+ try {
69
+ const initial = await Location.getCurrentPositionAsync({
70
+ accuracy: Location.Accuracy.Balanced,
71
+ });
72
+ setCoords({
73
+ latitude: initial.coords.latitude,
74
+ longitude: initial.coords.longitude,
75
+ });
76
+ } catch {
77
+ // watcher below will populate it shortly
78
+ }
79
+ await startWatching();
80
+ }
81
+ }, [startWatching]);
82
+
83
+ useEffect(() => {
84
+ recheck();
85
+
86
+ return () => {
87
+ subscriptionRef.current?.remove();
88
+ };
89
+ }, [recheck]);
90
+
91
+ return (
92
+ <LocationPermissionContext.Provider value={{ granted, coords, recheck }}>
93
+ {children}
94
+ </LocationPermissionContext.Provider>
95
+ );
96
+ };
97
+
98
+ export const useLocationPermission = () => {
99
+ const context = useContext(LocationPermissionContext);
100
+ if (!context) {
101
+ throw new Error(
102
+ "useLocationPermission must be used inside LocationPermissionProvider"
103
+ );
104
+ }
105
+ return context;
106
+ };
@@ -0,0 +1,70 @@
1
+ import React, { createContext, useContext, useEffect, useState } from "react";
2
+ import { useColorScheme } from "react-native";
3
+ import AsyncStorage from "@react-native-async-storage/async-storage";
4
+ import { AppTheme } from "../tokens/themes";
5
+
6
+ const THEME_KEY = "app_theme_preference";
7
+
8
+ type ThemeContextValue = {
9
+ isDark: boolean;
10
+ scheme: "light" | "dark";
11
+ colors: AppTheme;
12
+ toggleTheme: () => void;
13
+ isLoaded: boolean;
14
+ };
15
+
16
+ const ThemeContext = createContext<ThemeContextValue | null>(null);
17
+
18
+ export function ThemeProvider({
19
+ lightTheme,
20
+ darkTheme,
21
+ children,
22
+ }: {
23
+ lightTheme: AppTheme;
24
+ darkTheme: AppTheme;
25
+ children: React.ReactNode;
26
+ }) {
27
+ const systemScheme = useColorScheme() ?? "light";
28
+ console.log("RAW useColorScheme() result:", useColorScheme());
29
+ console.log("systemScheme used:", systemScheme);
30
+ const [override, setOverride] = useState<"light" | "dark" | null>(null);
31
+ const [isLoaded, setIsLoaded] = useState(false);
32
+
33
+ useEffect(() => {
34
+ AsyncStorage.getItem(THEME_KEY).then((saved) => {
35
+ if (saved === "light" || saved === "dark") setOverride(saved);
36
+ setIsLoaded(true);
37
+ });
38
+ }, []);
39
+
40
+ const scheme = override ?? (systemScheme as "light" | "dark");
41
+ const isDark = scheme === "dark";
42
+ console.log("ThemeContext — scheme:", scheme, "isDark:", isDark, "lightTheme.background.main:", lightTheme.background.main, "darkTheme.background.main:", darkTheme.background.main);
43
+
44
+
45
+ const toggleTheme = async () => {
46
+ const next = isDark ? "light" : "dark";
47
+ setOverride(next);
48
+ await AsyncStorage.setItem(THEME_KEY, next);
49
+ };
50
+
51
+ return (
52
+ <ThemeContext.Provider
53
+ value={{
54
+ isDark,
55
+ scheme,
56
+ colors: isDark ? darkTheme : lightTheme,
57
+ toggleTheme,
58
+ isLoaded,
59
+ }}
60
+ >
61
+ {children}
62
+ </ThemeContext.Provider>
63
+ );
64
+ }
65
+
66
+ export function useAppTheme() {
67
+ const ctx = useContext(ThemeContext);
68
+ if (!ctx) throw new Error("useAppTheme must be used inside ThemeProvider");
69
+ return ctx;
70
+ }
@@ -0,0 +1,21 @@
1
+ import { useState, useEffect, useCallback } from "react";
2
+
3
+ export function useCountdown(initialSeconds: number) {
4
+ const [count, setCount] = useState(initialSeconds);
5
+
6
+ useEffect(() => {
7
+ if (count <= 0) return;
8
+
9
+ const timer = setInterval(() => {
10
+ setCount((prev) => (prev <= 1 ? 0 : prev - 1));
11
+ }, 1000);
12
+
13
+ return () => clearInterval(timer);
14
+ }, [count]);
15
+
16
+ const reset = useCallback((seconds: number = initialSeconds) => {
17
+ setCount(seconds);
18
+ }, [initialSeconds]);
19
+
20
+ return { count, reset };
21
+ }
@@ -0,0 +1,46 @@
1
+ // import { useState } from "react";
2
+ // import { FieldConfig } from "../types/validateForm";
3
+ // import { validateForm } from "../utils/inputValidator/registerValidator";
4
+ // import "../utils/inputValidator/customValidator";
5
+
6
+ import { useForm } from "./useForm";
7
+
8
+ // export function useForgotPasswordForm({
9
+ // onSubmit,
10
+ // }: {
11
+ // onSubmit: (input: string) => Promise<void>;
12
+ // }) {
13
+ // const [input, setInput] = useState("");
14
+ // const [errors, setErrors] = useState<Record<string, string>>({});
15
+
16
+ // const fields: FieldConfig[] = [
17
+ // { name: "input", type: "email", label: "Email" },
18
+ // ];
19
+
20
+ // const clearError = (field: string) => {
21
+ // setErrors((prev) => ({ ...prev, [field]: "" }));
22
+ // };
23
+
24
+ // const handleSubmit = async () => {
25
+ // const newErrors = validateForm(fields, { input });
26
+ // setErrors(newErrors);
27
+ // if (Object.keys(newErrors).length > 0) return;
28
+
29
+ // await onSubmit(input);
30
+ // setInput("");
31
+ // };
32
+
33
+ // return {
34
+ // input, setInput,
35
+ // errors, clearError,
36
+ // handleSubmit,
37
+ // };
38
+ // }
39
+
40
+ export function useForgotPasswordForm({ onSubmit }: { onSubmit: (input: string) => Promise<void> }) {
41
+ return useForm({
42
+ initialValues: { input: "" },
43
+ fields: [{ name: "input", type: "email", label: "Email" }],
44
+ onSubmit: async (values) => onSubmit(values.input),
45
+ });
46
+ }
@@ -0,0 +1,52 @@
1
+ import { useState } from "react";
2
+ import { validateForm } from "../utils/inputValidator/registerValidator";
3
+ import { FieldConfig } from "../types/validateForm";
4
+
5
+ interface UseFormProps<T extends Record<string, string>> {
6
+ initialValues: T;
7
+ fields: FieldConfig[];
8
+ onSubmit: (values: T) => Promise<void>;
9
+ }
10
+
11
+ export function useForm<T extends Record<string, string>>({
12
+ initialValues,
13
+ fields,
14
+ onSubmit,
15
+ }: UseFormProps<T>) {
16
+ const [values, setValues] = useState<T>(initialValues);
17
+ const [errors, setErrors] = useState<Record<string, string>>({});
18
+ const [loading, setLoading] = useState(false);
19
+
20
+ const setValue = (key: keyof T, value: string) => {
21
+ setValues((prev) => ({ ...prev, [key]: value }));
22
+ };
23
+
24
+ const clearError = (field: string) => {
25
+ setErrors((prev) => ({ ...prev, [field]: "" }));
26
+ };
27
+
28
+ const handleSubmit = async () => {
29
+ const newErrors = validateForm(fields, values);
30
+ setErrors(newErrors);
31
+ if (Object.keys(newErrors).length > 0) return;
32
+ setLoading(true);
33
+ try {
34
+ await onSubmit(values);
35
+ setValues(initialValues);
36
+ } catch (err: any) {
37
+ throw err;
38
+ } finally {
39
+ setLoading(false);
40
+ }
41
+ };
42
+
43
+ return {
44
+ values,
45
+ setValue,
46
+ errors,
47
+ clearError,
48
+ handleSubmit,
49
+ loading,
50
+ setErrors,
51
+ };
52
+ }
@@ -0,0 +1,25 @@
1
+ import { useState } from "react";
2
+ import { useForm } from "./useForm";
3
+
4
+ export function useLoginForm({
5
+ onLogin,
6
+ }: {
7
+ onLogin: (email: string, password: string) => Promise<void>;
8
+ }) {
9
+ const [showPassword, setShowPassword] = useState(false);
10
+
11
+ const form = useForm({
12
+ initialValues: { email: "", password: "" },
13
+ fields: [
14
+ { name: "email", type: "email", required: true },
15
+ { name: "password", type: "password", required: true, minLength: 8 },
16
+ ],
17
+ onSubmit: async (values) => onLogin(values.email, values.password),
18
+ });
19
+
20
+ return {
21
+ ...form,
22
+ showPassword,
23
+ setShowPassword,
24
+ };
25
+ }
@@ -0,0 +1,75 @@
1
+ import { useState } from "react";
2
+ import { FieldConfig } from "../types/validateForm";
3
+ import { validateForm } from "../utils/inputValidator/registerValidator";
4
+ import "../utils/inputValidator/customValidator";
5
+
6
+ export function useResetPasswordForm({
7
+ onReset,
8
+ includeOldPassword = false,
9
+ }: {
10
+ onReset: (password: string, oldPassword?: string) => Promise<void>;
11
+ includeOldPassword?: boolean;
12
+ }) {
13
+ const [oldPassword, setOldPassword] = useState("");
14
+ const [password, setPassword] = useState("");
15
+ const [confirmPassword, setConfirmPassword] = useState("");
16
+ const [showOldPassword, setShowOldPassword] = useState(false);
17
+ const [showPassword, setShowPassword] = useState(false);
18
+ const [showConfirmPassword, setShowConfirmPassword] = useState(false);
19
+ const [errors, setErrors] = useState<Record<string, string>>({});
20
+ const [loading, setLoading] = useState(false);
21
+
22
+ const clearError = (field: string) => {
23
+ setErrors((prev) => ({ ...prev, [field]: "" }));
24
+ };
25
+
26
+ const handleSubmit = async () => {
27
+ const fields: FieldConfig[] = [
28
+ ...(includeOldPassword ?
29
+ [{ name: "oldPassword", type: "password", label: "Old Password" }] : []),
30
+ { name: "password", type: "password", label: "Password" },
31
+ { name: "confirmPassword", type: "confirmPassword", label: "Confirm Password" },
32
+ ];
33
+
34
+ const formValues = {
35
+ ...(includeOldPassword ? { oldPassword } : {}),
36
+ password,
37
+ confirmPassword,
38
+ };
39
+ const newErrors = validateForm(fields, formValues);
40
+ setErrors(newErrors);
41
+ if (Object.keys(newErrors).length > 0) return;
42
+ setLoading(true);
43
+ try{
44
+ await onReset(password, includeOldPassword ? oldPassword : undefined);
45
+ setOldPassword("");
46
+ setPassword("");
47
+ setConfirmPassword("");
48
+ }catch(err:any){
49
+ throw err;
50
+ }finally{
51
+ setLoading(false);
52
+ }
53
+
54
+ };
55
+
56
+ const passwordChecks = [
57
+ password.length >= 8,
58
+ /[a-zA-Z]/.test(password),
59
+ /[0-9]/.test(password),
60
+ /[!@#$%^&*(),.?":{}|<>]/.test(password),
61
+ ];
62
+
63
+ return {
64
+ oldPassword, setOldPassword,
65
+ password, setPassword,
66
+ confirmPassword, setConfirmPassword,
67
+ showOldPassword, setShowOldPassword,
68
+ showPassword, setShowPassword,
69
+ showConfirmPassword, setShowConfirmPassword,
70
+ errors, clearError,
71
+ handleSubmit,
72
+ passwordChecks,
73
+ loading,
74
+ };
75
+ }
@@ -0,0 +1,34 @@
1
+ import { useState } from "react";
2
+ import { validateForm } from "../utils/inputValidator/registerValidator";
3
+ import { Field } from "../types/formFields";
4
+
5
+ type UseFormSubmitProps = {
6
+ fields: Field[];
7
+ formState: Record<string, string>;
8
+ onSubmit: (formState: Record<string, string>) => Promise<void>;
9
+ };
10
+
11
+ export const useFormSubmit = ({ fields, formState, onSubmit }: UseFormSubmitProps) => {
12
+ const [errors, setErrors] = useState<Record<string, string>>({});
13
+ const [loading, setLoading] = useState(false);
14
+
15
+ const handleSubmit = async () => {
16
+ const newErrors = validateForm(fields, formState);
17
+ setErrors(newErrors);
18
+ if (Object.keys(newErrors).length > 0) return;
19
+ setLoading(true);
20
+ try {
21
+ await onSubmit(formState);
22
+ } catch (error: any) {
23
+ console.error("Signup error:", error);
24
+ } finally {
25
+ setLoading(false);
26
+ }
27
+ };
28
+
29
+ const clearError = (name: string) => {
30
+ setErrors((prev) => ({ ...prev, [name]: "" }));
31
+ };
32
+
33
+ return { handleSubmit, loading, errors, clearError, setErrors };
34
+ };
@@ -0,0 +1,47 @@
1
+ // import { useState } from "react";
2
+ // import { validateForm } from "../utils/inputValidator/registerValidator";
3
+ // import { FieldConfig } from "../types/validateForm";
4
+
5
+ import { useForm } from "./useForm";
6
+
7
+ // export function useSubmitReport({onSubmit}: {onSubmit:(target: string, reason: string)=>Promise<void>}){
8
+ // const [target, setTarget] = useState("");
9
+ // const [reason, setReason] = useState("");
10
+ // const [errors, setErrors] = useState<Record<string, string>>({});
11
+
12
+ // const fields:FieldConfig[] = [
13
+ // {name:"target", type:"text", required:true},
14
+ // {name:"reason", type:"text", required:true}
15
+ // ];
16
+ // const clearError = (field: string)=>{
17
+ // setErrors((prev)=>({...prev, [field]:""}))
18
+ // }
19
+ // const handleSubmit = async() => {
20
+ // const newErrors = validateForm(fields, {target, reason});
21
+ // setErrors(newErrors);
22
+ // if (Object.keys(newErrors).length > 0) return;
23
+ // try{
24
+ // await onSubmit(target, reason);
25
+ // setTarget("");
26
+ // setReason("");
27
+ // }catch (err: any){
28
+ // throw err;
29
+ // }
30
+ // }
31
+ // return{
32
+ // target, setTarget,
33
+ // reason, setReason,
34
+ // errors, setErrors,
35
+ // handleSubmit, clearError
36
+ // }
37
+ // }
38
+ export function useSubmitReport({onSubmit}:{onSubmit:(target: string, reason: string) => Promise<void>}){
39
+ return useForm({
40
+ initialValues:{target:"", reason: ""},
41
+ fields:[
42
+ {name:"target", type:"text",label:"Target", required:true},
43
+ {name:"reason", type:"text",label:"Reason", required:true}
44
+ ],
45
+ onSubmit: async(values) => onSubmit(values.target, values.reason)
46
+ });
47
+ }
@@ -0,0 +1,81 @@
1
+ // import { useState } from "react";
2
+ // import { validateForm } from "../utils/inputValidator/registerValidator";
3
+
4
+ // const fields = [
5
+ // { name: "firstname", type: "text", label: "Firstname" },
6
+ // { name: "lastname", type: "text", label: "Lastname" },
7
+ // { name: "phone", type: "phone", label: "Phone" },
8
+ // ];
9
+ // export function useUpdateUser({
10
+ // onUpdate
11
+ // }: {
12
+ // onUpdate: (formData: Record<string, string>) => Promise<void>
13
+ // }){
14
+ // const [loading, setLoading] = useState(false);
15
+ // const [errors, setErrors] = useState<Record<string, string>>({});
16
+ // const clearError = (field: string) => {
17
+ // setErrors((prev) => ({ ...prev, [field]: "" }));
18
+ // };
19
+
20
+ // const handleUpdate = async (formData: Record<string, any>) => {
21
+ // const newErrors = validateForm(fields, formData);
22
+ // setErrors(newErrors);
23
+ // if (Object.keys(newErrors).length > 0) return;
24
+
25
+ // setLoading(true);
26
+ // try {
27
+ // await onUpdate(formData);
28
+ // } catch (err: any) {
29
+ // } finally {
30
+ // setLoading(false);
31
+ // }
32
+ // };
33
+
34
+ // return {
35
+ // loading,
36
+ // errors,
37
+ // clearError,
38
+ // handleUpdate,
39
+ // };
40
+ // }
41
+
42
+
43
+ import { useState } from "react";
44
+ import { validateForm } from "../utils/inputValidator/registerValidator";
45
+ import { FieldConfig } from "../types/validateForm";
46
+
47
+ type UseUpdateUserProps = {
48
+ fields: FieldConfig[];
49
+ formState: Record<string, string>;
50
+ onUpdate: (formState: Record<string, string>) => Promise<void>;
51
+ };
52
+
53
+ export const useUpdateUser = ({
54
+ fields,
55
+ formState,
56
+ onUpdate,
57
+ }: UseUpdateUserProps) => {
58
+ const [errors, setErrors] = useState<Record<string, string>>({});
59
+ const [loading, setLoading] = useState(false);
60
+
61
+ const handleUpdate = async () => {
62
+ const newErrors = validateForm(fields, formState);
63
+ setErrors(newErrors);
64
+ if (Object.keys(newErrors).length > 0) return;
65
+
66
+ setLoading(true);
67
+ try {
68
+ await onUpdate(formState);
69
+ } catch (err: any) {
70
+ throw err;
71
+ } finally {
72
+ setLoading(false);
73
+ }
74
+ };
75
+
76
+ const clearError = (name: string) => {
77
+ setErrors((prev) => ({ ...prev, [name]: "" }));
78
+ };
79
+
80
+ return { handleUpdate, loading, errors, clearError, setErrors };
81
+ };
@@ -0,0 +1,36 @@
1
+ export { default as MailIcon } from "../assets/customIcons/email.svg";
2
+ export { default as LockIcon } from "../assets/customIcons/lock_closed.svg";
3
+ export { default as EyeIcon } from "../assets/customIcons/eye.svg";
4
+ export { default as EyeOffIcon } from "../assets/customIcons/eye_off.svg";
5
+ export { default as ArrowIcon } from "../assets/customIcons/arrow.svg";
6
+ export { default as ArrowBackIcon } from "../assets/customIcons/arrow_back.svg";
7
+ export { default as PhoneIcon } from "../assets/customIcons/phone.svg";
8
+ export {default as PersonIcon} from "../assets/customIcons/person.svg";
9
+ // export {default as HelpDarkIcon} from "../assets/customIcons/help_dark.svg";
10
+ // export {default as HelpLightIcon} from "../assets/customIcons/help_light.svg";
11
+ // export {default as HomeDarkIcon} from "../assets/customIcons/home_dark.svg";
12
+ // export {default as HomeLightIcon} from "../assets/customIcons/home_light.svg";
13
+ // export {default as SettingsDarkIcon} from "../assets/customIcons/settings_dark.svg";
14
+ // export {default as SettingsLightIcon} from "../assets/customIcons/settings_light.svg";
15
+ // export {default as ProfileLightIcon} from "../assets/customIcons/profile_light.svg";
16
+ // export {default as ProfileDarkIcon} from "../assets/customIcons/profile_dark.svg";
17
+ export {default as HomeIcon} from "../components/icons/homeIcon";
18
+ export {default as ProfileIcon} from "../components/icons/profileIcon";
19
+ export {default as SettingsIcon} from "../components/icons/settingsIcon";
20
+ export {default as ChatIcon} from "../components/icons/chatIcon";
21
+ export {default as LogoutIcon} from "../assets/customIcons/logout.svg";
22
+ export {default as LightModeIcon} from "../assets/customIcons/light_mode.svg";
23
+ export {default as DarkModeIcon} from "../assets/customIcons/dark_mode.svg";
24
+ export {default as HumbergerIcon} from "../assets/customIcons/humberger.svg";
25
+ export {default as ShieldIcon} from "../assets/customIcons/shield.svg";
26
+ export {default as DocumentIcon} from "../assets/customIcons/document.svg";
27
+ export {default as InformationIcon} from "../assets/customIcons/information.svg";
28
+ export {default as WarningIcon} from "../assets/customIcons/warning.svg";
29
+ export {default as SuccessDark} from "../assets/customIcons/phone_dark.svg";
30
+ export {default as SuccessLight} from "../assets/customIcons/phone_light.svg";
31
+ export {default as TrashIcon} from "../assets/customIcons/trash.svg";
32
+ export {default as CheckMarkIcon} from "../assets/customIcons/checkmark.svg";
33
+ export {default as BanIcon} from "../assets/customIcons/ban.svg";
34
+ export {default as BanImage} from "../components/icons/ban";
35
+ export {default as TruckForbiddenLight} from "../assets/customIcons/light_suspended.svg";
36
+ export {default as TruckForbiddenDark} from "../assets/customIcons/dark_suspended.svg";
package/src/index.ts ADDED
@@ -0,0 +1,62 @@
1
+ export {default as OnBoarding} from './components/screens/onBoarding';
2
+ export type {AppTheme} from './tokens/themes';
3
+ export { ThemeProvider, useAppTheme } from "./context/ThemeContext";
4
+ export { Fonts, textSize } from "./tokens/typography";
5
+ export {default as Button} from "./components/ui/button";
6
+ export {default as PageIndicator} from "./components/ui/pageIndicator";
7
+ export type {Language} from "./context/LanguageContext";
8
+ export { LanguageProvider, useLanguage } from "./context/LanguageContext";
9
+ export { validateForm, registerValidator } from "./utils/inputValidator/registerValidator";
10
+ export type { FieldConfig } from "./types/validateForm";
11
+ export { default as LoginScreen } from "./components/screens/loginScreen";
12
+ export { useLoginForm } from "./hooks/useLoginForm";
13
+ export {default as Input} from "./components/ui/input";
14
+ export {default as ErrorMessage} from "./components/ui/error";
15
+ export {default as PageTopBar} from "./components/ui/PageTopBar";
16
+ export {default as ForgotPwScreen} from "./components/screens/forgotPasswordScreen";
17
+ export {useForgotPasswordForm} from "./hooks/useForgotPasswordForm";
18
+ export {default as TemplateSubPage} from "./components/reusable/templateSubPage";
19
+ export {default as OTPInput} from "./components/ui/OTPInput"
20
+ export {default as VerificationCodeScreen} from "./components/screens/VerificationCodeScreen";
21
+ export {useCountdown} from "./hooks/useCountdown";
22
+ export {default as ResetPasswordScreen} from "./components/screens/resetPassword";
23
+ export {useResetPasswordForm} from "./hooks/useResetPasswordForm";
24
+ export {default as PasswordRequirementCard} from "./components/ui/passwordRequirmentCard";
25
+ export {default as SuccessDialog} from "./components/ui/successDialog";
26
+ export { LocationPermissionProvider, useLocationPermission } from "./context/LocationPermissionProvider";
27
+ export {createApiClient} from "./service/createApi";
28
+ export {default as CustomPopUp} from "./components/ui/customPopup";
29
+ export {default as TermsPopup} from "./components/ui/termsPopup";
30
+ export {default as SignUpScreen} from "./components/screens/signUpScreen";
31
+ export {DynamicForm} from "./components/ui/dynamicForm";
32
+ export {Field} from "./types/formFields";
33
+ export {default as TemplatePage} from "./components/reusable/templatePage";
34
+ export {useFormSubmit} from "./hooks/useSignup";
35
+ export {Menu} from "./types/menu";
36
+ export {LanguageType} from "./types/language";
37
+ export {default as LanguageSelect} from "./components/ui/languageSelect";
38
+ export {default as AsideBar} from './components/ui/asidebar';
39
+ export {default as SplashScreen} from "./components/screens/splashScreen";
40
+ export {default as SharpButton} from "./components/ui/sharpButton";
41
+ export {default as SharpContainer} from "./components/ui/sharpContainer";
42
+ export {SharpDynamicForm} from "./components/ui/sharpDynamicForm";
43
+ export {default as SharpInput} from "./components/ui/sharpInput";
44
+ export {default as SharpOtpInput} from "./components/ui/sharpOtpInput";
45
+ export * from "./icons";
46
+ export {IconType} from "./types/icon";
47
+ export {default as ThemeToggle} from "./components/ui/themeToggle";
48
+ export {Settings} from "./types/settingsFields";
49
+ export {groupSettings} from "./utils/helpers/groupSettings";
50
+ export {default as SettingsScreen} from "./components/screens/settingScreen";
51
+ export {useUpdateUser} from "./hooks/useUpdateUser";
52
+ export {default as LegalScreen} from "./components/screens/LegalScreen";
53
+ export {default as AddReportScreen} from "./components/screens/AddReportScreen";
54
+ export {useSubmitReport} from "./hooks/useSubmitReport";
55
+ export {default as SharpSelect} from "./components/ui/sharpSelect";
56
+ export {useForm} from "./hooks/useForm";
57
+ export {default as AboutScreen} from "./components/screens/aboutScreen";
58
+ export {default as Badge} from "./components/ui/badge";
59
+ export {default as WarningModel} from "./components/ui/warningModel";
60
+ export {default as Toast} from "./components/ui/toast";
61
+ export {default as AccountStatusScreen} from "./components/screens/AccountStatusScreen";
62
+ export {sendEmail} from "./service/sendEmail";