Skip to content

Commit 4fd29ff

Browse files
author
SyedAthar25
committed
Changes for signup and port
1 parent 9bd5dd0 commit 4fd29ff

2 files changed

Lines changed: 239 additions & 28 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"version": "0.0.0",
55
"type": "module",
66
"scripts": {
7-
"dev": "vite --port 80 --host",
7+
8+
"dev": "vite",
89
"build": "tsc && vite build",
910
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
1011
"preview": "vite preview"

src/components/sections/GetStartedModal/components/SignUpForm.tsx

Lines changed: 237 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ENDPOINTS, fetcher } from "@api/useAxiosSWR";
22
import { EMAIL_PATTERN } from "@constants/index";
33
import { AxiosError } from "axios";
44
import { enqueueSnackbar } from "notistack";
5-
import { useState } from "react";
5+
import { useState, useEffect } from "react";
66
import { useForm } from "react-hook-form";
77
import PhoneInput from "react-phone-input-2";
88

@@ -34,53 +34,132 @@ const SignUpForm = ({ toggleSignUp }: Props) => {
3434
const [signing, setSigning] = useState(false);
3535
const [progress, setProgress] = useState(0);
3636
const [stepMessage, setStepMessage] = useState("Initializing...");
37-
38-
const updateProgress = (value: number, message: string) => {
37+
const [currentStep, setCurrentStep] = useState(0);
38+
39+
// Define signup process steps
40+
const signupSteps = [
41+
{ title: "Validating Information", description: "Checking your details..." },
42+
{ title: "Creating Account", description: "Setting up your profile..." },
43+
{ title: "Configuring Site", description: "Preparing your workspace..." },
44+
{ title: "Finalizing Setup", description: "Almost there..." },
45+
{ title: "Ready!", description: "Redirecting to your dashboard..." },
46+
];
47+
48+
const updateProgress = (value: number, message: string, step: number = -1) => {
49+
console.log(`Progress update: ${value}% - ${message}`);
3950
setProgress(value);
4051
setStepMessage(message);
52+
if (step >= 0) {
53+
setCurrentStep(step);
54+
} else {
55+
// Calculate step based on progress
56+
const newStep = Math.min(Math.floor(value / 20), 4);
57+
setCurrentStep(newStep);
58+
}
4159
};
4260

4361
const onSubmit = async (data: Record<string, string>) => {
62+
console.log("Form submission started with data:", data);
4463
setSigning(true);
45-
updateProgress(10, "Starting signup...");
64+
updateProgress(5, "Starting signup process...", 0);
4665

4766
try {
48-
updateProgress(20, "Sending signup request...");
49-
const response: any = await fetcher.post(ENDPOINTS.signup, { ...data });
50-
51-
updateProgress(40, "Received response from server...");
67+
// Step 1: Validate data
68+
await new Promise(resolve => setTimeout(resolve, 800)); // Simulate validation time
69+
updateProgress(20, "Validating your information...", 0);
70+
console.log("Sending signup request to:", ENDPOINTS.signup);
71+
72+
// Step 2: Create account
73+
updateProgress(40, "Creating your account...", 1);
74+
await new Promise(resolve => setTimeout(resolve, 800)); // Simulate account creation time
75+
76+
const response: any = await fetcher.post(ENDPOINTS.signup, { ...data })
77+
.catch(error => {
78+
console.error("API request failed:", error);
79+
console.log("Error response data:", error.response?.data);
80+
console.log("Error status:", error.response?.status);
81+
throw error;
82+
});
83+
84+
console.log("Signup API response received:", response);
85+
86+
// Step 3: Configure site
87+
updateProgress(60, "Setting up your site...", 2);
88+
await new Promise(resolve => setTimeout(resolve, 800)); // Simulate site setup time
5289

5390
const token = response?.token ?? response?.message?.token ?? null;
5491
const site_url = response?.site_url ?? response?.message?.site_url ?? null;
5592

56-
updateProgress(70, "Validating site creation...");
93+
console.log("Extracted token:", token ? "Token exists" : "Token missing");
94+
console.log("Extracted site_url:", site_url);
95+
96+
// Step 4: Finalize
97+
updateProgress(80, "Finalizing your workspace...", 3);
98+
await new Promise(resolve => setTimeout(resolve, 800)); // Simulate finalization time
5799

58100
if (token && site_url) {
101+
console.log("Signup successful, proceeding to redirect");
59102
enqueueSnackbar(`🎉 Site created! Welcome to AlphaX, ${data.email}`, { variant: "success" });
60103
localStorage.setItem("access_token", token);
61104
reset();
62105

63-
updateProgress(100, "Redirecting to your new site...");
106+
// Step 5: Ready
107+
updateProgress(100, "Redirecting to your new site...", 4);
108+
console.log("Will redirect to:", site_url);
64109
setTimeout(() => {
65110
window.location.href = site_url;
66-
}, 1000);
111+
}, 1500);
67112
} else {
113+
console.warn("Signup completed but token or site_url is missing", { token, site_url });
68114
updateProgress(100, "⚠️ Site was not created.");
69115
enqueueSnackbar("Site was not created. Please try again later.", { variant: "warning" });
70116
}
71117
} catch (error) {
118+
console.error("Signup process error:", error);
119+
120+
// Log detailed error information
121+
if ((error as AxiosError).isAxiosError) {
122+
const axiosError = error as AxiosError;
123+
console.error("Axios error details:", {
124+
status: axiosError.response?.status,
125+
statusText: axiosError.response?.statusText,
126+
data: axiosError.response?.data,
127+
headers: axiosError.response?.headers,
128+
});
129+
}
130+
72131
const errorMessage =
73132
((error as AxiosError)?.response?.data as { message: string })?.message ||
74133
(error as Error).message ||
75134
"Internal error. Please try again later";
76135

136+
console.error("Error message to display:", errorMessage);
77137
enqueueSnackbar(errorMessage, { variant: "error" });
78138
updateProgress(100, "Something went wrong.");
79139
} finally {
80-
setSigning(false);
140+
console.log("Signup process completed");
141+
// We don't set signing to false here to keep the modal visible if redirecting
81142
}
82143
};
83144

145+
// This effect will automatically animate progress bar smoothly
146+
useEffect(() => {
147+
if (signing && progress < 100) {
148+
const interval = setInterval(() => {
149+
setProgress(prev => {
150+
// Increment progress slightly for animation effect
151+
const target = Math.min((currentStep + 1) * 20, 100);
152+
if (prev < target - 2) {
153+
return prev + 0.5;
154+
}
155+
clearInterval(interval);
156+
return prev;
157+
});
158+
}, 50);
159+
return () => clearInterval(interval);
160+
}
161+
}, [signing, progress, currentStep]);
162+
84163
return (
85164
<div className="hide-scrollbar w-full h-screen overflow-auto bg-gray-50 dark:bg-gray-900 p-4 flex justify-center items-center">
86165
<div className="hide-scrollbar w-full max-w-[700px] bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-sm overflow-y-auto max-h-full">
@@ -180,6 +259,9 @@ const SignUpForm = ({ toggleSignUp }: Props) => {
180259
/>
181260
<span className="ml-2 mt-3 text-gray-500 text-sm">.alphaxerp.com</span>
182261
</div>
262+
{formErrors.siteName && (
263+
<p className="text-xs text-red-600 mt-2">{formErrors.siteName.message}</p>
264+
)}
183265
</div>
184266

185267
{/* Email */}
@@ -199,6 +281,9 @@ const SignUpForm = ({ toggleSignUp }: Props) => {
199281
className="py-3 px-4 block w-full border rounded-lg text-sm dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400"
200282
placeholder="your@email.com"
201283
/>
284+
{formErrors.email && (
285+
<p className="text-xs text-red-600 mt-2">{formErrors.email.message}</p>
286+
)}
202287
</div>
203288

204289
{/* Password */}
@@ -214,10 +299,26 @@ const SignUpForm = ({ toggleSignUp }: Props) => {
214299
value: 6,
215300
message: "Password must have at least 6 characters",
216301
},
302+
validate: (value) => {
303+
const hasUpperCase = /[A-Z]/.test(value);
304+
const hasLowerCase = /[a-z]/.test(value);
305+
const hasNumber = /[0-9]/.test(value);
306+
const hasSpecialChar = /[^A-Za-z0-9]/.test(value);
307+
308+
if (!hasUpperCase) return "Must include at least one uppercase letter";
309+
if (!hasLowerCase) return "Must include at least one lowercase letter";
310+
if (!hasNumber) return "Must include at least one number";
311+
if (!hasSpecialChar) return "Must include at least one special character";
312+
313+
return true;
314+
},
217315
})}
218316
className="py-3 px-4 block w-full border rounded-lg text-sm dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400"
219317
placeholder="Enter a secure password"
220318
/>
319+
{formErrors.password && (
320+
<p className="text-xs text-red-600 mt-2">{formErrors.password.message}</p>
321+
)}
221322
</div>
222323

223324
<div>
@@ -252,31 +353,138 @@ const SignUpForm = ({ toggleSignUp }: Props) => {
252353
</div>
253354

254355
{signing && (
255-
<div className="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm flex items-center justify-center">
256-
<div className="text-center">
257-
<div className="flex justify-center gap-6 mb-6">
258-
{["#38bdf8", "#7c3aed", "#60a5fa"].map((color, i) => (
356+
<div className="fixed inset-0 z-50 bg-black/70 backdrop-blur-sm flex items-center justify-center">
357+
<div className="bg-gray-800 rounded-xl p-8 max-w-md w-full shadow-2xl">
358+
{/* Step progress with animation */}
359+
<div className="flex justify-center mb-8">
360+
<div className="relative w-24 h-24">
361+
{/* Background circle */}
362+
<div className="absolute inset-0 rounded-full border-4 border-gray-700"></div>
363+
364+
{/* Progress circle with gradient */}
365+
<svg className="absolute inset-0 w-24 h-24 -rotate-90">
366+
<circle
367+
className="text-transparent"
368+
strokeWidth="4"
369+
stroke="currentColor"
370+
fill="transparent"
371+
r="38"
372+
cx="48"
373+
cy="48"
374+
/>
375+
<circle
376+
className="text-indigo-500 transition-all duration-300 ease-in-out"
377+
strokeWidth="4"
378+
strokeLinecap="round"
379+
stroke="url(#gradient)"
380+
fill="transparent"
381+
r="38"
382+
cx="48"
383+
cy="48"
384+
strokeDasharray={`${2 * Math.PI * 38}`}
385+
strokeDashoffset={`${2 * Math.PI * 38 * (1 - progress / 100)}`}
386+
/>
387+
388+
{/* Define gradient */}
389+
<defs>
390+
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
391+
<stop offset="0%" stopColor="#8B5CF6" />
392+
<stop offset="100%" stopColor="#3B82F6" />
393+
</linearGradient>
394+
</defs>
395+
</svg>
396+
397+
{/* Percentage text */}
398+
<div className="absolute inset-0 flex items-center justify-center">
399+
<span className="text-xl font-bold text-white">{Math.round(progress)}%</span>
400+
</div>
401+
</div>
402+
</div>
403+
404+
{/* Stepper title */}
405+
<h2 className="text-xl font-bold text-center text-white mb-2">
406+
{signupSteps[currentStep]?.title || "Processing..."}
407+
</h2>
408+
409+
{/* Description */}
410+
<p className="text-gray-300 text-center mb-6">
411+
{signupSteps[currentStep]?.description || "Please wait..."}
412+
</p>
413+
414+
{/* Stepper indicators */}
415+
<div className="flex justify-between items-center mb-4 px-2">
416+
{signupSteps.map((step, index) => (
417+
<div key={index} className="flex flex-col items-center">
418+
{/* Step connector line */}
419+
{index > 0 && (
420+
<div
421+
className={`h-0.5 w-full absolute -ml-full ${
422+
index <= currentStep ? "bg-gradient-to-r from-purple-500 to-blue-500" : "bg-gray-700"
423+
}`}
424+
style={{ width: "100%", marginLeft: "-50%", marginTop: "10px", zIndex: 0 }}
425+
></div>
426+
)}
427+
428+
{/* Step bubble */}
429+
<div
430+
className={`z-10 flex items-center justify-center w-7 h-7 rounded-full transition-all duration-500 ${
431+
index < currentStep
432+
? "bg-gradient-to-r from-purple-500 to-blue-500"
433+
: index === currentStep
434+
? "bg-gradient-to-r from-purple-400 to-blue-400 border-2 border-white animate-pulse"
435+
: "bg-gray-700"
436+
}`}
437+
>
438+
{index < currentStep ? (
439+
// Completed step check mark
440+
<svg className="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
441+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
442+
</svg>
443+
) : (
444+
// Step number
445+
<span className="text-xs text-white font-medium">{index + 1}</span>
446+
)}
447+
</div>
448+
449+
{/* Step label (visible on wider screens) */}
450+
<div className="hidden sm:block text-xs mt-2 text-center whitespace-nowrap">
451+
<span
452+
className={`${
453+
index <= currentStep ? "text-gray-200" : "text-gray-500"
454+
} font-medium`}
455+
>
456+
{step.title.split(' ')[0]}
457+
</span>
458+
</div>
459+
</div>
460+
))}
461+
</div>
462+
463+
{/* Detailed status message */}
464+
<div className="text-center text-gray-400 text-sm mt-6 italic">
465+
{stepMessage}
466+
</div>
467+
468+
{/* Animated gear icons */}
469+
<div className="flex justify-center gap-4 mt-8 opacity-70">
470+
{[24, 20, 16].map((size, i) => (
259471
<svg
260472
key={i}
261-
className={`w-16 h-16 ${
262-
i === 1 ? "animate-spin-slow-reverse" : "animate-spin-slow"
473+
className={`w-${size} h-${size} ${
474+
i % 2 === 0 ? "animate-spin-slow" : "animate-spin-slow-reverse"
263475
}`}
476+
style={{
477+
animationDuration: `${(i + 3) * 2}s`,
478+
opacity: 0.6 + (i * 0.1)
479+
}}
264480
xmlns="http://www.w3.org/2000/svg"
265-
fill={color}
481+
fill={i === 0 ? "#8B5CF6" : i === 1 ? "#3B82F6" : "#EC4899"}
266482
viewBox="0 0 24 24"
267483
>
268484
<path d="M19.14 12.936a7.996 7.996 0 0 0 .047-.936 7.996 7.996 0 0 0-.047-.936l2.036-1.593a.5.5 0 0 0 .121-.63l-1.926-3.33a.5.5 0 0 0-.607-.218l-2.396.96a7.98 7.98 0 0 0-1.617-.936l-.36-2.52A.5.5 0 0 0 13.405 2h-2.81a.5.5 0 0 0-.492.415l-.36 2.52a7.98 7.98 0 0 0-1.617.936l-2.396-.96a.5.5 0 0 0-.607.218L2.197 8.46a.5.5 0 0 0 .121.63l2.036 1.593a7.996 7.996 0 0 0 0 1.872L2.318 14.15a.5.5 0 0 0-.121.63l1.926 3.33a.5.5 0 0 0 .607.218l2.396-.96a7.98 7.98 0 0 0 1.617.936l.36 2.52a.5.5 0 0 0 .492.415h2.81a.5.5 0 0 0 .492-.415l.36-2.52a7.98 7.98 0 0 0 1.617-.936l2.396.96a.5.5 0 0 0 .607-.218l1.926-3.33a.5.5 0 0 0-.121-.63l-2.036-1.593zM12 15.5a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7z" />
269485
</svg>
270486
))}
271487
</div>
272-
<div className="text-lg text-slate-300 mb-2">{stepMessage}</div>
273-
<div className="w-60 h-2 bg-slate-700 rounded-full overflow-hidden mx-auto">
274-
<div
275-
className="h-full bg-gradient-to-r from-blue-400 to-purple-600 transition-all duration-500"
276-
style={{ width: `${progress}%` }}
277-
/>
278-
</div>
279-
<p className="mt-2 text-xs text-slate-400">{progress}% Complete</p>
280488
</div>
281489
</div>
282490
)}
@@ -289,6 +497,8 @@ export default SignUpForm;
289497

290498

291499

500+
501+
292502
// second code comment
293503

294504
// import { ENDPOINTS, fetcher } from "@api/useAxiosSWR";

0 commit comments

Comments
 (0)