Skip to content

Commit 6f46062

Browse files
committed
Updated the activate license screen
1 parent 72ed72a commit 6f46062

10 files changed

Lines changed: 1488 additions & 467 deletions

File tree

src-tauri/capabilities/default.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
},
7676
{
7777
"url": "https://api.blinkeye.app/user-info"
78+
},
79+
{
80+
"url": "https://api.blinkeye.app/discount"
7881
}
7982
],
8083
"deny": []
@@ -150,4 +153,4 @@
150153
"dialog:default",
151154
"os:default"
152155
]
153-
}
156+
}

src/blink-eye-onboarding.tsx

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import GradientBackground from "./components/GradientBackground";
1818
// import Database from "@tauri-apps/plugin-sql";
1919
import { ModeToggle } from "./components/ThemeToggle";
2020
import { Toaster } from "react-hot-toast";
21+
import toast from "react-hot-toast";
2122
import ToDoOnboarding from "./components/screens/todo-screen-copied";
2223

2324
export default function UserOnboarding() {
@@ -29,10 +30,11 @@ export default function UserOnboarding() {
2930
const [breakInterval, setBreakInterval] = useState(20);
3031
const [breakDuration, setBreakDuration] = useState(20);
3132
const [reminderText, setReminderText] = useState(
32-
"Pause! Look into the distance, and best if you walk a bit."
33+
"Pause! Look into the distance, and best if you walk a bit.",
3334
);
3435
const [licenseKey, setLicenseKey] = useState("");
3536
const [userName, setUserName] = useState("");
37+
const [email, setEmail] = useState("");
3638
const [todos, setTodos] = useState<TodoItem[]>([]);
3739

3840
// Screen Configuration - Easy to add new screens!
@@ -81,6 +83,7 @@ export default function UserOnboarding() {
8183
reminderText,
8284
licenseKey,
8385
todos,
86+
email: email || undefined,
8487
};
8588
await OnboardingService.completeOnboarding(onboardingData);
8689
},
@@ -92,33 +95,83 @@ export default function UserOnboarding() {
9295
const currentScreenConfig = screens.find((s) => s.id === currentScreen);
9396

9497
// Navigation Functions
98+
9599
const nextScreen = async () => {
100+
if (currentScreen === 1) {
101+
const trimmed = email.trim();
102+
103+
if (!trimmed) {
104+
toast(
105+
"📬 Drop your email real quick!\n\nWe only use it if there's something important about the app — zero spam, we're not that kind of app.",
106+
{
107+
duration: 4000,
108+
style: {
109+
borderRadius: "12px",
110+
background: "var(--background)",
111+
color: "var(--foreground)",
112+
border: "1px solid rgba(254, 76, 85, 0.3)",
113+
fontSize: "13px",
114+
textAlign: "center",
115+
},
116+
icon: "🙅",
117+
},
118+
);
119+
return;
120+
}
121+
122+
// RFC-compliant-ish email validation
123+
const emailRegex = /^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/;
124+
if (!emailRegex.test(trimmed)) {
125+
toast(
126+
"🤔 Hmm, that email looks a little off.\nDouble-check it? We need it to be real — just in case!",
127+
{
128+
duration: 4000,
129+
style: {
130+
borderRadius: "12px",
131+
background: "var(--background)",
132+
color: "var(--foreground)",
133+
border: "1px solid rgba(254, 76, 85, 0.3)",
134+
fontSize: "13px",
135+
textAlign: "center",
136+
},
137+
icon: "✉️",
138+
},
139+
);
140+
return;
141+
}
142+
143+
// Success feedback when valid
144+
toast.success("Got it! 🎉 No spam — pinky promise. Let's keep going!", {
145+
duration: 2000,
146+
style: {
147+
borderRadius: "12px",
148+
fontSize: "13px",
149+
},
150+
});
151+
}
152+
96153
if (currentScreen < totalScreens) {
97154
setIsLoading(true);
98-
99155
try {
100-
// Execute the onNext function for current screen
101156
if (currentScreenConfig?.onNext) {
102157
await currentScreenConfig.onNext();
103158
}
104-
105159
setCurrentScreen(currentScreen + 1);
106160
} catch (error) {
107161
console.error("Error saving data:", error);
108-
// TODO: Show error toast/notification
162+
toast.error("Oops! Something went wrong. Try again?");
109163
} finally {
110164
setIsLoading(false);
111165
}
112166
} else if (currentScreen === totalScreens) {
113-
// Handle the final "Complete" button click
114167
setIsLoading(true);
115168
try {
116-
// Execute the onNext function for the final screen
117169
if (currentScreenConfig?.onNext) {
118170
await currentScreenConfig.onNext();
119171
}
120172
} catch (error) {
121173
console.error("Error completing onboarding:", error);
174+
toast.error("Couldn't complete setup. Try again!");
122175
} finally {
123176
setIsLoading(false);
124177
}
@@ -153,7 +206,7 @@ export default function UserOnboarding() {
153206
const getScreenProps = () => {
154207
switch (currentScreen) {
155208
case 1:
156-
return {};
209+
return { email, setEmail };
157210
case 2:
158211
return {
159212
breakInterval,
@@ -234,8 +287,8 @@ export default function UserOnboarding() {
234287
currentScreen === screen.id
235288
? "bg-[#FE4C55]"
236289
: currentScreen > screen.id
237-
? "bg-green-500"
238-
: "bg-gray-300"
290+
? "bg-green-500"
291+
: "bg-gray-300"
239292
}`}
240293
/>
241294
</div>
@@ -252,8 +305,8 @@ export default function UserOnboarding() {
252305
{isLoading
253306
? "Saving..."
254307
: currentScreen === totalScreens
255-
? "Complete"
256-
: "Next"}
308+
? "Complete"
309+
: "Next"}
257310
</span>
258311
<ChevronRight className="w-4 h-4" />
259312
</Button>

0 commit comments

Comments
 (0)