next-auth-mfelfelani72 0.0.22 → 0.0.24

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 (91) hide show
  1. package/dist/components/Login.d.ts +0 -0
  2. package/dist/components/Login.js +0 -0
  3. package/dist/components/Register.d.ts +0 -0
  4. package/dist/components/Register.js +0 -0
  5. package/dist/components/base/Image.d.ts +7 -0
  6. package/dist/components/base/Image.js +112 -0
  7. package/dist/components/base/LanguageSwitcher.d.ts +0 -0
  8. package/dist/components/base/LanguageSwitcher.js +4 -3
  9. package/dist/components/base/LocalizedLink.d.ts +14 -0
  10. package/dist/components/base/LocalizedLink.js +49 -0
  11. package/dist/components/demo/UiLogin.d.ts +0 -0
  12. package/dist/components/demo/UiLogin.js +0 -0
  13. package/dist/components/demo/UiRegister.d.ts +0 -0
  14. package/dist/components/demo/UiRegister.js +0 -0
  15. package/dist/components/demo/auth/Login.d.ts +3 -0
  16. package/dist/components/demo/auth/Login.js +66 -0
  17. package/dist/components/demo/auth/Register.d.ts +3 -0
  18. package/dist/components/demo/auth/Register.js +73 -0
  19. package/dist/components/demo/auth/layouts/twoColumn/LoginLanding.d.ts +2 -0
  20. package/dist/components/demo/auth/layouts/twoColumn/LoginLanding.js +31 -0
  21. package/dist/components/demo/auth/layouts/twoColumn/RegisterLanding.d.ts +2 -0
  22. package/dist/components/demo/auth/layouts/twoColumn/RegisterLanding.js +31 -0
  23. package/dist/components/demo/auth/layouts/twoColumn/common/theme/default/login/LoginForm.d.ts +2 -0
  24. package/dist/components/demo/auth/layouts/twoColumn/common/theme/default/login/LoginForm.js +29 -0
  25. package/dist/components/demo/auth/layouts/twoColumn/common/theme/default/register/RegisterForm.d.ts +3 -0
  26. package/dist/components/demo/auth/layouts/twoColumn/common/theme/default/register/RegisterForm.js +31 -0
  27. package/dist/components/demo/auth/layouts/twoColumn/desktop/Login.d.ts +2 -0
  28. package/dist/components/demo/auth/layouts/twoColumn/desktop/Login.js +31 -0
  29. package/dist/components/demo/auth/layouts/twoColumn/desktop/Register.d.ts +2 -0
  30. package/dist/components/demo/auth/layouts/twoColumn/desktop/Register.js +31 -0
  31. package/dist/components/demo/auth/layouts/twoColumn/ipad/Login.d.ts +2 -0
  32. package/dist/components/demo/auth/layouts/twoColumn/ipad/Login.js +31 -0
  33. package/dist/components/demo/auth/layouts/twoColumn/ipad/Register.d.ts +2 -0
  34. package/dist/components/demo/auth/layouts/twoColumn/ipad/Register.js +31 -0
  35. package/dist/components/demo/auth/layouts/twoColumn/mobile/Login.d.ts +2 -0
  36. package/dist/components/demo/auth/layouts/twoColumn/mobile/Login.js +22 -0
  37. package/dist/components/demo/auth/layouts/twoColumn/mobile/Register.d.ts +2 -0
  38. package/dist/components/demo/auth/layouts/twoColumn/mobile/Register.js +22 -0
  39. package/dist/configs/env.d.ts +0 -0
  40. package/dist/configs/env.js +0 -0
  41. package/dist/configs/language.d.ts +5 -27
  42. package/dist/configs/language.js +5 -38
  43. package/dist/core/auth.d.ts +0 -0
  44. package/dist/core/auth.js +0 -0
  45. package/dist/hooks/useTranslation.d.ts +2 -4
  46. package/dist/hooks/useTranslation.js +4 -26
  47. package/dist/index.d.ts +3 -1
  48. package/dist/index.js +3 -1
  49. package/dist/interfaces/dictionary.d.ts +0 -0
  50. package/dist/interfaces/dictionary.js +0 -0
  51. package/dist/interfaces/global.d.ts +0 -0
  52. package/dist/interfaces/global.js +0 -0
  53. package/dist/libraries/auth/loginHandler.d.ts +0 -23
  54. package/dist/libraries/auth/loginHandler.js +20 -172
  55. package/dist/libraries/auth/registerHandler.d.ts +5 -0
  56. package/dist/libraries/auth/registerHandler.js +126 -0
  57. package/dist/libraries/cn.d.ts +0 -0
  58. package/dist/libraries/cn.js +0 -0
  59. package/dist/libraries/debounce.d.ts +0 -0
  60. package/dist/libraries/debounce.js +0 -0
  61. package/dist/libraries/detectComponentResponsive.d.ts +0 -0
  62. package/dist/libraries/detectComponentResponsive.js +0 -0
  63. package/dist/libraries/detectDeviceFromUA.d.ts +0 -0
  64. package/dist/libraries/detectDeviceFromUA.js +0 -0
  65. package/dist/libraries/fonts.d.ts +0 -0
  66. package/dist/libraries/fonts.js +0 -0
  67. package/dist/libraries/translation.d.ts +0 -0
  68. package/dist/libraries/translation.js +0 -0
  69. package/dist/locale/auth/en.json +0 -0
  70. package/dist/locale/auth/fa.json +0 -0
  71. package/dist/locale/en.d.ts +5 -0
  72. package/dist/locale/en.js +3 -1
  73. package/dist/locale/fa.d.ts +5 -0
  74. package/dist/locale/fa.js +3 -1
  75. package/dist/locale/index.d.ts +20 -0
  76. package/dist/locale/index.js +1 -7
  77. package/dist/locale/meta/index.d.ts +14 -0
  78. package/dist/locale/meta/index.js +39 -0
  79. package/dist/proxy.d.ts +0 -2
  80. package/dist/proxy.js +15 -21
  81. package/dist/stores/AppStore.d.ts +1 -5
  82. package/dist/stores/AppStore.js +1 -3
  83. package/dist/stores/LangStore.d.ts +0 -0
  84. package/dist/stores/LangStore.js +0 -0
  85. package/dist/types/index.d.ts +28 -0
  86. package/dist/types/index.js +1 -0
  87. package/dist/types.d.ts +0 -0
  88. package/dist/types.js +0 -0
  89. package/dist/utilities/app/cookieUtils.d.ts +0 -0
  90. package/dist/utilities/app/cookieUtils.js +0 -0
  91. package/package.json +7 -1
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,7 @@
1
+ import { ImageProps } from "next/image";
2
+ export interface CustomImageProps extends ImageProps {
3
+ enableLoading?: boolean;
4
+ fallbackElement?: React.ReactNode;
5
+ }
6
+ declare const Image: ({ enableLoading, ...props }: CustomImageProps) => import("react").JSX.Element;
7
+ export default Image;
@@ -0,0 +1,112 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-08 10:10:51
6
+ * @Description:
7
+ */
8
+ "use client";
9
+ var __rest = (this && this.__rest) || function (s, e) {
10
+ var t = {};
11
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
12
+ t[p] = s[p];
13
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
14
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
15
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
16
+ t[p[i]] = s[p[i]];
17
+ }
18
+ return t;
19
+ };
20
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
+ import { useState, useEffect, useRef } from "react";
22
+ // Components
23
+ import NextImage from "next/image";
24
+ import { imageLoader } from "forma-li";
25
+ // Functions
26
+ import * as motion from "motion/react-client";
27
+ import { AnimatePresence } from "motion/react";
28
+ import { cn } from "forma-li";
29
+ // Hooks
30
+ import { useTranslation } from "@/hooks/useTranslation";
31
+ // Constants
32
+ const PHRASE_KEYS = [
33
+ "loading_ahead_of_market",
34
+ "loading_where_news_gather",
35
+ "loading_stay_informed",
36
+ "loading_realtime_intelligence",
37
+ "loading_never_miss",
38
+ "loading_your_edge",
39
+ "loading_all_news_one_hub",
40
+ ];
41
+ const PHRASE_INTERVAL = 3000;
42
+ const FALLBACK_SRC = "/images/svg/baseLogo.svg";
43
+ const SmallSpinner = ({ size }) => {
44
+ const s = Math.max(12, Math.min(size * 0.4, 28));
45
+ return (_jsxs("span", { className: "relative flex items-center justify-center", style: { width: s, height: s }, children: [_jsx(motion.span, { className: "absolute inset-0 rounded-full border-2 border-primary-400/20 dark:border-secondary-400/20" }), _jsx(motion.span, { className: "absolute inset-0 rounded-full border-2 border-transparent border-t-primary-400/60 dark:border-t-secondary-400/60", animate: { rotate: 360 }, transition: { duration: 1, repeat: Infinity, ease: "linear" } }), _jsx(motion.span, { className: "rounded-full bg-primary-400/30 dark:bg-secondary-400/30", style: { width: s * 0.2, height: s * 0.2 }, animate: { scale: [1, 1.5, 1], opacity: [0.3, 0.7, 0.3] }, transition: { duration: 1.2, repeat: Infinity, ease: "easeInOut" } })] }));
46
+ };
47
+ const ImageWithLoading = (_a) => {
48
+ var { className, onLoad, onError, src, fallbackElement } = _a, props = __rest(_a, ["className", "onLoad", "onError", "src", "fallbackElement"]);
49
+ const { t } = useTranslation();
50
+ const [isLoading, setIsLoading] = useState(true);
51
+ const [hasError, setHasError] = useState(false);
52
+ const [phraseIndex, setPhraseIndex] = useState(() => Math.floor(Math.random() * PHRASE_KEYS.length));
53
+ const [containerWidth, setContainerWidth] = useState(0);
54
+ const ref = useRef(null);
55
+ const isFill = props.fill;
56
+ const computedSizes = isFill && !props.sizes
57
+ ? "(max-width:768px) 100vw, (max-width:1200px) 50vw, 33vw"
58
+ : props.sizes;
59
+ // Track container width for responsive text / spinner
60
+ useEffect(() => {
61
+ if (!isLoading || !ref.current)
62
+ return;
63
+ const observer = new ResizeObserver(([entry]) => {
64
+ setContainerWidth(entry.contentRect.width);
65
+ });
66
+ observer.observe(ref.current);
67
+ return () => observer.disconnect();
68
+ }, [isLoading]);
69
+ // Rotate phrases while loading
70
+ useEffect(() => {
71
+ if (!isLoading)
72
+ return;
73
+ const interval = setInterval(() => {
74
+ setPhraseIndex((prev) => (prev + 1) % PHRASE_KEYS.length);
75
+ }, PHRASE_INTERVAL);
76
+ return () => clearInterval(interval);
77
+ }, [isLoading]);
78
+ const showText = containerWidth > 80;
79
+ const fontSize = Math.max(14, Math.min(containerWidth * 0.08, 36));
80
+ const padding = Math.max(8, containerWidth * 0.06);
81
+ // Determine the actual src to use
82
+ const actualSrc = hasError ? FALLBACK_SRC : src;
83
+ return (_jsxs("span", { ref: ref, className: cn("relative overflow-hidden", isFill ? "absolute inset-0" : "inline-block"), children: [_jsx(AnimatePresence, { children: isLoading && (_jsxs(motion.span, { className: "absolute inset-0 z-10 flex items-center justify-center overflow-hidden rounded-[inherit] bg-gray-100 dark:bg-gray-800", initial: { opacity: 1 }, exit: { opacity: 0, scale: 1.04 }, transition: { duration: 0.4, ease: "easeOut" }, children: [_jsx(motion.span, { className: "absolute inset-0 bg-linear-to-r from-transparent via-primary-400/6 to-transparent dark:via-secondary-400/6", style: { backgroundSize: "200% 100%" }, animate: { backgroundPosition: ["200% 0", "-200% 0"] }, transition: { duration: 2, repeat: Infinity, ease: "linear" } }), showText ? (_jsxs("span", { className: "relative z-10 flex flex-col items-center justify-center text-center", style: { padding, maxWidth: "90%" }, children: [_jsx(AnimatePresence, { mode: "wait", children: _jsx(motion.span, { className: "block font-semibold leading-snug text-primary-400 dark:text-secondary-400", style: { fontSize }, initial: { opacity: 0, y: 10, filter: "blur(6px)" }, animate: { opacity: 0.7, y: 0, filter: "blur(0px)" }, exit: { opacity: 0, y: -10, filter: "blur(6px)" }, transition: { duration: 0.5, ease: "easeInOut" }, children: t(PHRASE_KEYS[phraseIndex]) }, phraseIndex) }), _jsx(motion.span, { className: "mt-2 h-0.5 rounded-full bg-primary-400/25 dark:bg-secondary-400/25", style: { width: Math.min(containerWidth * 0.45, 120) }, animate: { scaleX: [0.6, 1, 0.6] }, transition: {
84
+ duration: 2.5,
85
+ repeat: Infinity,
86
+ ease: "easeInOut",
87
+ } })] })) : (_jsx(SmallSpinner, { size: containerWidth }))] }, "image-loader")) }), hasError && fallbackElement && (_jsx("span", { className: cn("absolute inset-0 z-20", className), children: fallbackElement })), _jsx(NextImage, Object.assign({}, props, { src: actualSrc, sizes: computedSizes, loader: imageLoader, className: cn("transition-opacity duration-500 ease-out", isLoading || (hasError && fallbackElement)
88
+ ? "opacity-0"
89
+ : "opacity-100", className), onLoad: (e) => {
90
+ setIsLoading(false);
91
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e);
92
+ }, onError: (e) => {
93
+ if (!hasError) {
94
+ setHasError(true);
95
+ if (fallbackElement)
96
+ setIsLoading(false);
97
+ onError === null || onError === void 0 ? void 0 : onError(e);
98
+ }
99
+ else {
100
+ setIsLoading(false);
101
+ onError === null || onError === void 0 ? void 0 : onError(e);
102
+ }
103
+ } }))] }));
104
+ };
105
+ const Image = (_a) => {
106
+ var { enableLoading = true } = _a, props = __rest(_a, ["enableLoading"]);
107
+ if (!enableLoading) {
108
+ return _jsx(NextImage, Object.assign({}, props, { loader: imageLoader }));
109
+ }
110
+ return _jsx(ImageWithLoading, Object.assign({}, props));
111
+ };
112
+ export default Image;
File without changes
@@ -12,9 +12,10 @@ import { useState, useRef, useEffect } from "react";
12
12
  // Components
13
13
  import { LanguageIcon } from "forma-ui";
14
14
  // Zustand
15
- import { useLangStore } from "../../stores/LangStore";
15
+ import { useLangStore } from "forma-li";
16
16
  // Interfaces
17
- import { languages, getNativeName, getFlag, } from "../../configs/language";
17
+ import { languages } from "../../configs/language";
18
+ import { getLanguage } from "forma-li";
18
19
  export default function LanguageSwitcher() {
19
20
  // Hooks
20
21
  const router = useRouter();
@@ -130,6 +131,6 @@ export default function LanguageSwitcher() {
130
131
  return (_jsxs("button", { onClick: () => handleChange(currentLang), disabled: isActive, className: `w-full flex items-center gap-3 px-4 py-3 text-left transition-all duration-200
131
132
  ${isActive
132
133
  ? "text-primary-600 dark:text-primary-400 cursor-default bg-white/20 dark:bg-white/10"
133
- : "text-Neutral-400 hover:text-primary-600 dark:hover:text-primary-400 hover:bg-white/30 dark:hover:bg-Neutral-700/40 cursor-pointer"}`, children: [_jsx("span", { className: "text-lg", children: getFlag(currentLang) }), _jsx("span", { className: "font-medium", children: getNativeName(currentLang) }), isActive && (_jsx("div", { className: "w-2 h-2 bg-primary-500 dark:bg-primary-400 rounded-full ml-auto shadow-[0_0_12px_rgba(99,102,241,0.4)]" }))] }, currentLang));
134
+ : "text-Neutral-400 hover:text-primary-600 dark:hover:text-primary-400 hover:bg-white/30 dark:hover:bg-Neutral-700/40 cursor-pointer"}`, children: [_jsx("span", { className: "text-lg", children: getLanguage(currentLang).flag }), _jsx("span", { className: "font-medium", children: getLanguage(currentLang).nativeName }), isActive && (_jsx("div", { className: "w-2 h-2 bg-primary-500 dark:bg-primary-400 rounded-full ml-auto shadow-[0_0_12px_rgba(99,102,241,0.4)]" }))] }, currentLang));
134
135
  }) }))] }));
135
136
  }
@@ -0,0 +1,14 @@
1
+ import { LinkProps } from "next/link";
2
+ import { ReactNode } from "react";
3
+ import { UrlObject } from "url";
4
+ interface LocalizedLinkProps extends Omit<LinkProps, "href"> {
5
+ href: string | UrlObject;
6
+ prefetch?: boolean;
7
+ children: ReactNode;
8
+ locale?: string;
9
+ target?: string;
10
+ className?: string;
11
+ style?: any;
12
+ }
13
+ export default function LocalizedLink({ href, prefetch, children, locale, className, ...props }: LocalizedLinkProps): import("react").JSX.Element;
14
+ export {};
@@ -0,0 +1,49 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-05 09:56:22
6
+ * @Description: LocalizedLink با TypeScript
7
+ */
8
+ "use client";
9
+ var __rest = (this && this.__rest) || function (s, e) {
10
+ var t = {};
11
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
12
+ t[p] = s[p];
13
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
14
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
15
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
16
+ t[p[i]] = s[p[i]];
17
+ }
18
+ return t;
19
+ };
20
+ import { jsx as _jsx } from "react/jsx-runtime";
21
+ import Link from "next/link";
22
+ import { usePathname } from "next/navigation";
23
+ export default function LocalizedLink(_a) {
24
+ var { href, prefetch = false, children, locale, className } = _a, props = __rest(_a, ["href", "prefetch", "children", "locale", "className"]);
25
+ const pathname = usePathname();
26
+ const currentLang = locale || pathname.split("/")[1] || "en";
27
+ const isExternal = typeof href === "string" && /^(https?:\/\/|mailto:|tel:|#)/.test(href);
28
+ if (isExternal) {
29
+ return (_jsx("a", Object.assign({ href: href }, props, { className: className, children: children })));
30
+ }
31
+ let normalizedHref;
32
+ if (typeof href === "string") {
33
+ const hasLangPrefix = href.startsWith(`/${currentLang}/`) || href === `/${currentLang}`;
34
+ normalizedHref = hasLangPrefix
35
+ ? href
36
+ : `/${currentLang}${href.startsWith("/") ? href : `/${href}`}`;
37
+ }
38
+ else {
39
+ normalizedHref = Object.assign(Object.assign({}, href), { pathname: href.pathname
40
+ ? href.pathname.startsWith(`/${currentLang}/`) ||
41
+ href.pathname === `/${currentLang}`
42
+ ? href.pathname
43
+ : `/${currentLang}${href.pathname.startsWith("/")
44
+ ? href.pathname
45
+ : `/${href.pathname}`}`
46
+ : undefined });
47
+ }
48
+ return (_jsx(Link, Object.assign({ rel: "preload", scroll: false, prefetch: prefetch, href: normalizedHref }, props, { className: className, children: children })));
49
+ }
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { LoginProps } from "@/types";
3
+ export default function Login({ layout, theme, className }: LoginProps): React.JSX.Element;
@@ -0,0 +1,66 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-04 11:48:20
6
+ * @Description:
7
+ */
8
+ "use client";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { useState, useMemo, lazy } from "react";
11
+ // Components
12
+ const LazyTwoColumn = lazy(() => import("@/components/demo/auth/layouts/twoColumn/LoginLanding"));
13
+ // Constants
14
+ const LAYOUT_MAP = {
15
+ twoColumn: LazyTwoColumn,
16
+ };
17
+ // Functions
18
+ import { cn } from "forma-li";
19
+ export default function Login({ layout, theme, className }) {
20
+ // States
21
+ const [errors, setErrors] = useState({});
22
+ const [message, setMessage] = useState(null);
23
+ // Functions
24
+ const handleSubmit = async (formData) => {
25
+ setMessage(null);
26
+ setErrors({});
27
+ const email = formData.get("email") || "";
28
+ const password = formData.get("password") || "";
29
+ const newErrors = {};
30
+ if (!email.trim())
31
+ newErrors.email = "Email is required";
32
+ else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
33
+ newErrors.email = "Invalid email format";
34
+ if (!password)
35
+ newErrors.password = "Password is required";
36
+ else if (password.length < 6)
37
+ newErrors.password = "Password must be at least 6 characters";
38
+ if (Object.keys(newErrors).length > 0) {
39
+ setErrors(newErrors);
40
+ setMessage("Please fix the errors below.");
41
+ return;
42
+ }
43
+ try {
44
+ const res = await fetch("/api/auth/login", {
45
+ method: "POST",
46
+ headers: { "Content-Type": "application/json" },
47
+ body: JSON.stringify({ email, password }),
48
+ });
49
+ const data = await res.json();
50
+ if (!res.ok) {
51
+ setMessage((data === null || data === void 0 ? void 0 : data.message) || "Login failed");
52
+ return;
53
+ }
54
+ setMessage((data === null || data === void 0 ? void 0 : data.message) || "Login successful");
55
+ }
56
+ catch (err) {
57
+ setMessage((err === null || err === void 0 ? void 0 : err.message) || "Network error");
58
+ }
59
+ };
60
+ const RenderUi = useMemo(() => {
61
+ return LAYOUT_MAP[layout || ""] || LAYOUT_MAP.twoColumn;
62
+ }, [layout]);
63
+ return (_jsx("div", { style: {
64
+ backgroundImage: `url('/images/jpg/${theme || "default"}_auth.jpeg')`,
65
+ }, className: cn("zz-10 w-full max-w-md px-4 max-h-screen bg-cover bg-center bg-fixed overflow-hidden", className), children: _jsx(RenderUi, { onSubmit: handleSubmit, errors: errors, message: message, theme: theme }) }));
66
+ }
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ import type { RegisterProps } from "@/types";
3
+ export default function Register({ layout, theme, className, }: RegisterProps): React.JSX.Element;
@@ -0,0 +1,73 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useState, useMemo, lazy } from "react";
4
+ import { cn } from "forma-li";
5
+ const LazyTwoColumn = lazy(() => import("@/components/demo/auth/layouts/twoColumn/RegisterLanding"));
6
+ const LAYOUT_MAP = {
7
+ twoColumn: LazyTwoColumn,
8
+ };
9
+ export default function Register({ layout = "twoColumn", theme, className, }) {
10
+ const [errors, setErrors] = useState({});
11
+ const [message, setMessage] = useState(null);
12
+ const validate = (formData) => {
13
+ var _a, _b, _c;
14
+ const newErrors = {};
15
+ // const name = formData.get("name")?.toString().trim();
16
+ const email = (_a = formData.get("email")) === null || _a === void 0 ? void 0 : _a.toString().trim();
17
+ const password = (_b = formData.get("password")) === null || _b === void 0 ? void 0 : _b.toString();
18
+ const confirmPassword = (_c = formData.get("confirmPassword")) === null || _c === void 0 ? void 0 : _c.toString();
19
+ // if (!name) newErrors.name = "Name is required";
20
+ if (!email)
21
+ newErrors.email = "Email is required";
22
+ else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
23
+ newErrors.email = "Invalid email format";
24
+ if (!password)
25
+ newErrors.password = "Password is required";
26
+ else if (password.length < 6)
27
+ newErrors.password = "Password must be at least 6 characters";
28
+ if (!confirmPassword)
29
+ newErrors.confirmPassword = "Confirm your password";
30
+ else if (password !== confirmPassword)
31
+ newErrors.confirmPassword = "Passwords do not match";
32
+ return newErrors;
33
+ };
34
+ const handleSubmit = async (formData) => {
35
+ var _a, _b, _c;
36
+ setMessage(null);
37
+ setErrors({});
38
+ const validationErrors = validate(formData);
39
+ if (Object.keys(validationErrors).length > 0) {
40
+ setErrors(validationErrors);
41
+ setMessage("Please fix the errors below.");
42
+ return;
43
+ }
44
+ try {
45
+ // const name = formData.get("name")?.toString().trim();
46
+ const name = "sky";
47
+ const email = (_a = formData.get("email")) === null || _a === void 0 ? void 0 : _a.toString().trim();
48
+ const password = (_b = formData.get("password")) === null || _b === void 0 ? void 0 : _b.toString();
49
+ const confirmPassword = (_c = formData.get("confirmPassword")) === null || _c === void 0 ? void 0 : _c.toString();
50
+ console.log(formData);
51
+ const res = await fetch("/api/auth/register", {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/json" },
54
+ body: JSON.stringify({ name, email, password, confirmPassword }),
55
+ });
56
+ const data = await res.json();
57
+ if (!res.ok) {
58
+ setMessage((data === null || data === void 0 ? void 0 : data.message) || "Registration failed");
59
+ return;
60
+ }
61
+ setMessage((data === null || data === void 0 ? void 0 : data.message) || "Registration successful");
62
+ }
63
+ catch (err) {
64
+ setMessage((err === null || err === void 0 ? void 0 : err.message) || "Network error");
65
+ }
66
+ };
67
+ const RenderUi = useMemo(() => {
68
+ return LAYOUT_MAP[layout] || LAYOUT_MAP.twoColumn;
69
+ }, [layout]);
70
+ return (_jsx("div", { style: {
71
+ backgroundImage: `url('/images/jpg/${theme || "default"}_auth.jpeg')`,
72
+ }, className: cn("z-10 w-full max-w-md px-4 max-h-screen bg-cover bg-center bg-fixed overflow-hidden", className), children: _jsx(RenderUi, { onSubmit: handleSubmit, errors: errors, message: message, theme: theme }) }));
73
+ }
@@ -0,0 +1,2 @@
1
+ import type { LoginComponentProps } from "@/types";
2
+ export default function TwoColumnLayout(props: LoginComponentProps): import("react").JSX.Element | null;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Date: 2025-10-04 11:48:20
5
+ * @Description: TwoColumnLayout with client-side cookie detection
6
+ */
7
+ "use client";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { useState, useEffect } from "react";
10
+ import dynamic from "next/dynamic";
11
+ import { getCookie } from "forma-li";
12
+ // Components
13
+ const LoginDesktop = dynamic(() => import("./desktop/Login"));
14
+ const LoginMobile = dynamic(() => import("./mobile/Login"));
15
+ const LoginIpad = dynamic(() => import("./ipad/Login"));
16
+ // Functions
17
+ import { detectComponentsResponsive } from "forma-li";
18
+ export default function TwoColumnLayout(props) {
19
+ const [deviceType, setDeviceType] = useState();
20
+ useEffect(() => {
21
+ const device = getCookie("device-type");
22
+ if (device) {
23
+ setDeviceType(device);
24
+ }
25
+ });
26
+ const LoginComponent = detectComponentsResponsive(deviceType, LoginMobile, LoginIpad, LoginDesktop);
27
+ if (typeof LoginComponent === "string") {
28
+ return null;
29
+ }
30
+ return _jsx(LoginComponent, Object.assign({}, props));
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { RegisterComponentProps } from "@/types";
2
+ export default function TwoColumnLayout(props: RegisterComponentProps): import("react").JSX.Element | null;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Date: 2025-10-04 11:48:20
5
+ * @Description: TwoColumnLayout with client-side cookie detection
6
+ */
7
+ "use client";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { useState, useEffect } from "react";
10
+ import dynamic from "next/dynamic";
11
+ import { getCookie } from "forma-li";
12
+ // Components
13
+ const RegisterDesktop = dynamic(() => import("./desktop/Register"));
14
+ const RegisterMobile = dynamic(() => import("./mobile/Register"));
15
+ const RegisterIpad = dynamic(() => import("./ipad/Register"));
16
+ // Functions
17
+ import { detectComponentsResponsive } from "forma-li";
18
+ export default function TwoColumnLayout(props) {
19
+ const [deviceType, setDeviceType] = useState();
20
+ useEffect(() => {
21
+ const device = getCookie("device-type");
22
+ if (device) {
23
+ setDeviceType(device);
24
+ }
25
+ });
26
+ const RegisterComponent = detectComponentsResponsive(deviceType, RegisterMobile, RegisterIpad, RegisterDesktop);
27
+ if (typeof RegisterComponent === "string") {
28
+ return null;
29
+ }
30
+ return _jsx(RegisterComponent, Object.assign({}, props));
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { LoginComponentProps } from "@/types";
2
+ export default function LoginForm({ onSubmit, errors, message, }: LoginComponentProps): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-04 11:48:20
6
+ * @Description:
7
+ */
8
+ "use client";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { useState } from "react";
11
+ // Components
12
+ import LocalizedLink from "@/components/base/LocalizedLink";
13
+ import { InputPassword, InputEmail } from "forma-ui";
14
+ const GoogleIcon = () => (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 18 18", children: _jsxs("g", { fill: "none", fillRule: "evenodd", children: [_jsx("path", { fill: "#4285F4", d: "M17.64 9.205c0-.639-.057-1.252-.164-1.841H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z" }), _jsx("path", { fill: "#34A853", d: "M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z" }), _jsx("path", { fill: "#FBBC05", d: "M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" }), _jsx("path", { fill: "#EA4335", d: "M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z" })] }) }));
15
+ // Hooks
16
+ import { useTranslation } from "@/hooks/useTranslation";
17
+ export default function LoginForm({ onSubmit, errors, message, }) {
18
+ // Hooks
19
+ const { t } = useTranslation();
20
+ // States
21
+ const [isLoading, setIsLoading] = useState(false);
22
+ // Functions
23
+ const handleSubmit = (e) => {
24
+ e.preventDefault();
25
+ const formData = new FormData(e.currentTarget);
26
+ onSubmit(formData);
27
+ };
28
+ return (_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col h-full w-full animate-in fade-in slide-in-from-bottom-4 duration-500 justify-between", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex flex-col gap-7", children: [_jsxs("div", { children: [_jsx("label", { className: "xs:text-[16px] text-Neutral-100 mb-1", children: t("email") }), _jsx(InputEmail, { id: "email", name: "email", label: "", validate: t("invalid_email"), placeholder: t("enter_your_email"), className: "flex justify-between h-10 rounded-lg xl:placeholder:text-sm xs:placeholder:text-xs shadow-inner bg-white/20 border-Neutral-200 text-white placeholder:text-Neutral-100" }), (errors === null || errors === void 0 ? void 0 : errors.email) && (_jsx("p", { className: "mt-1 text-sm text-red-300", children: errors.email }))] }), _jsxs("div", { children: [_jsx("label", { className: "xs:text-[16px] text-Neutral-100 mb-1", children: t("password") }), _jsx(InputPassword, { id: "password", name: "password", validate: t("invalid_password"), placeholder: t("enter_your_password"), className: "flex justify-between h-10 rounded-lg xl:placeholder:text-sm xs:placeholder:text-xs shadow-inner bg-white/20 border-Neutral-200 text-white placeholder:text-Neutral-100" }), (errors === null || errors === void 0 ? void 0 : errors.password) && (_jsx("p", { className: "mt-1 text-sm text-red-300", children: errors.password }))] })] }), _jsx("div", { className: "flex justify-end mt-2", children: _jsx(LocalizedLink, { href: "/auth/forgot-password", className: "text-xs text-Neutral-100 hover:text-primary-400 transition-colors", children: t("forgot_password") }) }), message && (_jsx("div", { className: "mt-4 text-center text-sm text-red-300", children: message }))] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-4 mt-6", children: [_jsx("div", { className: "flex-1 h-px bg-Neutral-100" }), _jsx("span", { className: "text-xs text-Neutral-100", children: t("or_continue_with") }), _jsx("div", { className: "flex-1 h-px bg-Neutral-100" })] }), _jsx("div", { className: "flex gap-3 mt-2", children: _jsxs("button", { type: "button", className: "flex-1 flex items-center justify-center gap-2 py-2 rounded-lg border border-Neutral-200 bg-white/20 hover:bg-white/30 transition-all duration-300 text-Neutral-100 cursor-pointer", children: [_jsx(GoogleIcon, {}), _jsx("span", { className: "text-sm", children: t("google") })] }) }), _jsxs("p", { className: "text-center mt-2 text-sm text-Neutral-100", children: [t("dont_have_account"), " ", _jsx(LocalizedLink, { href: "/auth/register", className: "text-primary-400 hover:text-primary-300 font-medium transition-colors", children: t("create_account") })] }), _jsx("button", { type: "submit", disabled: isLoading, className: "w-full mt-2 py-3 rounded-lg bg-linear-to-r from-primary-400 to-primary-500 text-white font-semibold text-sm hover:shadow-lg hover:shadow-primary-400/30 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? (_jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsxs("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), t("loading")] })) : (t("login")) })] })] }));
29
+ }
@@ -0,0 +1,3 @@
1
+ import type { RegisterComponentProps } from "@/types";
2
+ declare const RegisterForm: ({ onSubmit, errors, message, }: RegisterComponentProps) => import("react").JSX.Element;
3
+ export default RegisterForm;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-12-31 07:59:15
6
+ * @Description: Register Form with social login & login link
7
+ */
8
+ "use client";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { useState } from "react";
11
+ // Hooks
12
+ import { useTranslation } from "@/hooks/useTranslation";
13
+ // Components
14
+ import { InputPassword, InputEmail, InputRePassword } from "forma-ui";
15
+ import LocalizedLink from "@/components/base/LocalizedLink";
16
+ // Google SVG Icon Component
17
+ // Interface
18
+ const RegisterForm = ({ onSubmit, errors, message, }) => {
19
+ // Hooks
20
+ const { t } = useTranslation();
21
+ // States
22
+ const [isLoading, setIsLoading] = useState(false);
23
+ const handleSubmit = (e) => {
24
+ e.preventDefault();
25
+ const formData = new FormData(e.currentTarget);
26
+ console.log(formData);
27
+ onSubmit(formData); // ✅ اینجا onSubmit رو صدا بزن
28
+ };
29
+ return (_jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col h-full w-full animate-in fade-in slide-in-from-bottom-4 duration-500 justify-between", children: [_jsx("div", { children: _jsxs("div", { className: "flex flex-col gap-5", children: [_jsxs("div", { children: [_jsx("label", { className: "xs:text-[16px] text-Neutral-100 mb-1", children: t("email") }), _jsx(InputEmail, { id: "email", name: "email", validate: t("invalid_email"), placeholder: t("enter_your_email"), className: "flex justify-between h-10 rounded-lg xl:placeholder:text-sm xs:placeholder:text-xs shadow-inner bg-white/20 border-Neutral-200 text-white placeholder:text-Neutral-100" })] }), _jsxs("div", { children: [_jsx("label", { className: "xs:text-[16px] text-Neutral-100 mb-1", children: t("password") }), _jsx(InputPassword, { id: "password", name: "password", validate: t("invalid_password"), placeholder: t("enter_your_password"), className: "flex justify-between h-10 rounded-lg xl:placeholder:text-sm xs:placeholder:text-xs shadow-inner bg-white/20 border-Neutral-200 text-white placeholder:text-Neutral-100" })] }), _jsx("div", { children: _jsx("label", { className: "xs:text-[16px] text-Neutral-100 mb-1", children: t("confirm_password") }) }), _jsx(InputRePassword, { id: "confirmPassword", name: "confirmPassword", validate: t("mismatch_password"), placeholder: t("confirm_your_password"), className: "flex justify-between px-10 h-10 w-full rounded-lg xl:placeholder:text-sm xs:placeholder:text-xs shadow-inner bg-white/20 border-Neutral-200 text-white placeholder:text-Neutral-100" })] }) }), _jsxs("div", { children: [_jsxs("p", { className: "text-center mt-2 text-sm text-Neutral-100", children: [t("already_have_account?"), " ", _jsx(LocalizedLink, { href: "/auth/login", className: "text-primary-400 hover:text-primary-300 font-medium transition-colors", children: t("login") })] }), _jsx("button", { type: "submit", disabled: isLoading, className: "w-full mt-2 py-3 rounded-lg bg-linear-to-r from-primary-400 to-primary-500 text-white font-semibold text-sm hover:shadow-lg hover:shadow-primary-400/30 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed", children: isLoading ? (_jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsxs("svg", { className: "animate-spin h-4 w-4", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), t("loading")] })) : (t("register")) })] })] }));
30
+ };
31
+ export default RegisterForm;
@@ -0,0 +1,2 @@
1
+ import type { LoginComponentProps } from "@/types";
2
+ export default function LoginDesktop(props: LoginComponentProps): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-04 11:48:20
6
+ * @Description:
7
+ */
8
+ "use client";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { useMemo } from "react";
11
+ import dynamic from "next/dynamic";
12
+ // Hooks
13
+ import { useTranslation } from "@/hooks/useTranslation";
14
+ export default function LoginDesktop(props) {
15
+ // Hooks
16
+ const { t } = useTranslation();
17
+ // Functions
18
+ const Components = useMemo(() => {
19
+ const createDynamicComponent = (name) => {
20
+ return dynamic(() => import(`../common/theme/${props === null || props === void 0 ? void 0 : props.theme}/${name}`).catch(() => import(`../common/theme/default/${name}`)), { ssr: false });
21
+ };
22
+ return {
23
+ LeftSidebar: createDynamicComponent("LeftSidebar"),
24
+ RightSidebar: createDynamicComponent("RightSidebar"),
25
+ LoginForm: createDynamicComponent("login/LoginForm"),
26
+ LoginDetails: createDynamicComponent("login/LoginDetails"),
27
+ };
28
+ }, [props === null || props === void 0 ? void 0 : props.theme]);
29
+ const { LeftSidebar, RightSidebar, LoginForm, LoginDetails } = Components;
30
+ return (_jsx("div", { className: "flex flex-row h-screen w-full items-center justify-center", children: _jsxs("div", { className: "relative inline-flex flex-row z-120 max-w-[60dvw] h-[77dvh]", children: [_jsx(LeftSidebar, { title: t("login_title"), description: t("login_description"), children: _jsx(LoginForm, Object.assign({}, props)) }), _jsx(RightSidebar, { children: _jsx(LoginDetails, {}) })] }) }));
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { RegisterComponentProps } from "@/types";
2
+ export default function RegisterDesktop(props: RegisterComponentProps): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ /*
2
+ * @Author: Mohammad Felfelani
3
+ * @Email: mfelfelani72@gmail.com
4
+ * @Team:
5
+ * @Date: 2025-10-04 11:48:20
6
+ * @Description:
7
+ */
8
+ "use client";
9
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { useMemo } from "react";
11
+ import dynamic from "next/dynamic";
12
+ // Hooks
13
+ import { useTranslation } from "@/hooks/useTranslation";
14
+ export default function RegisterDesktop(props) {
15
+ // Hooks
16
+ const { t } = useTranslation();
17
+ // Functions
18
+ const Components = useMemo(() => {
19
+ const createDynamicComponent = (name) => {
20
+ return dynamic(() => import(`../common/theme/${props === null || props === void 0 ? void 0 : props.theme}/${name}`).catch(() => import(`../common/theme/default/${name}`)), { ssr: false });
21
+ };
22
+ return {
23
+ LeftSidebar: createDynamicComponent("LeftSidebar"),
24
+ RightSidebar: createDynamicComponent("RightSidebar"),
25
+ RegisterForm: createDynamicComponent("register/RegisterForm"),
26
+ RegisterDetails: createDynamicComponent("register/RegisterDetails"),
27
+ };
28
+ }, [props === null || props === void 0 ? void 0 : props.theme]);
29
+ const { LeftSidebar, RightSidebar, RegisterForm, RegisterDetails } = Components;
30
+ return (_jsx("div", { className: "flex flex-row h-screen w-full items-center justify-center", children: _jsxs("div", { className: "relative inline-flex flex-row z-120 max-w-[60dvw] h-[77dvh]", children: [_jsx(LeftSidebar, { title: t("register_title"), description: t("register_description"), children: _jsx(RegisterForm, Object.assign({}, props)) }), _jsx(RightSidebar, { children: _jsx(RegisterDetails, {}) })] }) }));
31
+ }
@@ -0,0 +1,2 @@
1
+ import type { LoginComponentProps } from "@/types";
2
+ export default function LoginIpad(props: LoginComponentProps): import("react").JSX.Element;