From 6d0babb0f835b1ae9334dc778982b95882d9c7f1 Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 01:45:01 +0600 Subject: [PATCH 1/8] Made initial section of workday --- src/App.tsx | 13 ++- src/components/app-sidebar.tsx | 2 +- src/components/window/Settings.tsx | 59 ++++++----- src/components/window/Workday.tsx | 156 +++++++++++++++++++++++++++++ 4 files changed, 200 insertions(+), 30 deletions(-) create mode 100644 src/components/window/Workday.tsx diff --git a/src/App.tsx b/src/App.tsx index ff04048..25d4966 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import "./App.css"; import { useAutoStart } from "./hooks/useAutoStart"; import { ErrorDisplay } from "./components/ErrorDisplay"; import { LoadingSpinner } from "./components/LoadingSpinner"; +import Workday from "./components/window/Workday"; // Lazy load route components const Dashboard = lazy(() => import("./components/window/Dashboard")); @@ -59,6 +60,14 @@ function App() { } /> + }> + + + } + /> }> - + } /> diff --git a/src/components/app-sidebar.tsx b/src/components/app-sidebar.tsx index 1b9feab..eb19f53 100644 --- a/src/components/app-sidebar.tsx +++ b/src/components/app-sidebar.tsx @@ -50,7 +50,7 @@ const items = [ }, { title: "Workday Setup", - url: "/soon", + url: "/workday", icon: Calendar, isPremiumFeature: true, }, diff --git a/src/components/window/Settings.tsx b/src/components/window/Settings.tsx index be6ff48..70417e0 100644 --- a/src/components/window/Settings.tsx +++ b/src/components/window/Settings.tsx @@ -9,6 +9,7 @@ const Settings = () => { const [interval, setInterval] = useState(20); const [duration, setDuration] = useState(20); const [reminderText, setReminderText] = useState(""); + const [workday, setWorkday] = useState(null); const openReminderWindow = () => { console.log("Clicked"); @@ -33,33 +34,18 @@ const Settings = () => { const storedInterval = await store.get( "blinkEyeReminderInterval" ); - // const isPomodoroTimerEnabled = await store.get( - // "PomodoroStyleBreak" - // ); - // console.log(isPomodoroTimerEnabled, "is pomodoro timer enabled"); const storedDuration = await store.get( "blinkEyeReminderDuration" ); const storedReminderText = await store.get( "blinkEyeReminderScreenText" ); - if (typeof storedReminderText === "string") { - setReminderText(storedReminderText); - } - if (typeof storedInterval === "number") { - setInterval(storedInterval); - // if (isPomodoroTimerEnabled) { - // setInterval(25); - // } else { - // } - } - if (typeof storedDuration === "number") { - setDuration(storedDuration); - // if (isPomodoroTimerEnabled) { - // setDuration(300); - // } else { - // } - } + const storedWorkday = await store.get("blinkEyeWorkday"); + + if (storedInterval) setInterval(storedInterval); + if (storedDuration) setDuration(storedDuration); + if (storedReminderText) setReminderText(storedReminderText); + if (storedWorkday) setWorkday(storedWorkday); }; console.log(interval, duration, reminderText, "settings 2"); fetchSettings(); @@ -69,18 +55,37 @@ const Settings = () => { useEffect(() => { let timer: number | null = null; - const startTimer = () => { - timer = window.setInterval(() => { - openReminderWindow(); - }, interval * 60 * 1000); + const checkWorkdayAndStartTimer = () => { + const now = new Date(); + const day = now.toLocaleString("en-US", { weekday: "long" }); + const todayWorkday = workday?.[day]; + + if (todayWorkday) { + const [startHour, startMinute] = todayWorkday.start + .split(":") + .map(Number); + const [endHour, endMinute] = todayWorkday.end.split(":").map(Number); + + const startTime = new Date(); + startTime.setHours(startHour, startMinute, 0, 0); + + const endTime = new Date(); + endTime.setHours(endHour, endMinute, 0, 0); + + if (now >= startTime && now <= endTime) { + timer = window.setInterval(() => { + openReminderWindow(); + }, interval * 60 * 1000); + } + } }; - startTimer(); + if (workday) checkWorkdayAndStartTimer(); return () => { if (timer !== null) window.clearInterval(timer); }; - }, [interval]); + }, [workday, interval]); const handleSave = async () => { const store = await load("store.json", { autoSave: false }); diff --git a/src/components/window/Workday.tsx b/src/components/window/Workday.tsx new file mode 100644 index 0000000..631411b --- /dev/null +++ b/src/components/window/Workday.tsx @@ -0,0 +1,156 @@ +import { useState, useEffect } from "react"; +import { load } from "@tauri-apps/plugin-store"; +import { Button } from "../ui/button"; +import { Input } from "../ui/input"; +import toast from "react-hot-toast"; +import { Label } from "../ui/label"; +import { Separator } from "../ui/separator"; +import { Clock } from "lucide-react"; +import { Switch } from "../ui/switch"; + +type Schedule = { start: string; end: string } | null; +// Define the type for a single day's schedule +type DaySchedule = { + start: string; + end: string; +} | null; + +// Define the type for the workday object +type Workday = { + [day: string]: DaySchedule; +}; +const defaultWorkday: Record = { + Monday: { start: "09:00", end: "17:00" }, + Tuesday: { start: "09:00", end: "17:00" }, + Wednesday: { start: "09:00", end: "17:00" }, + Thursday: { start: "09:00", end: "17:00" }, + Friday: { start: "09:00", end: "17:00" }, + Saturday: null, + Sunday: null, +}; + +export default function Workday() { + const [workday, setWorkday] = + useState>(defaultWorkday); + + useEffect(() => { + const fetchWorkday = async () => { + const store = await load("store.json", { autoSave: false }); + const savedWorkday = await store.get("blinkEyeWorkday"); + + // Ensure the saved workday matches the expected type + if (savedWorkday && typeof savedWorkday === "object") { + setWorkday(savedWorkday); + } + }; + + fetchWorkday(); + }, []); + + const handleTimeChange = ( + day: string, + type: "start" | "end", + value: string + ) => { + setWorkday((prev) => ({ + ...prev, + [day]: { + ...prev[day], + [type]: value, + } as DaySchedule, // Ensure proper typing here + })); + }; + + const toggleWorkingDay = (day: string) => { + setWorkday((prev) => ({ + ...prev, + [day]: prev[day] ? null : { start: "09:00", end: "17:00" }, + })); + }; + + const handleSave = async () => { + const store = await load("store.json", { autoSave: false }); + await store.set("blinkEyeWorkday", workday); + await store.save(); + toast.success("Workday settings saved!"); + }; + + return ( +
+
+

Workday Setup

+

+ Configure your work hours for each day of the week. Toggle to set + working or non-working days. +

+
+ +
+ {Object.entries(workday).map(([day, schedule]) => ( +
+
+

{day}

+
+ + toggleWorkingDay(day)} + /> +
+
+ {schedule ? ( +
+
+ +
+ + + handleTimeChange(day, "start", e.target.value) + } + /> +
+
+
+ +
+ + + handleTimeChange(day, "end", e.target.value) + } + /> +
+
+
+ ) : ( +

Non-working day

+ )} + +
+ ))} +
+ +
+ ); +} From b4ade30541c908cffb5c680f94d4372086107ce8 Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 12:52:38 +0600 Subject: [PATCH 2/8] Added workday setup data --- package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/components/ConfigDataLoader.tsx | 60 +++++++ src/components/window/Workday.tsx | 263 +++++++++++++++++----------- src/main.tsx | 2 + 7 files changed, 227 insertions(+), 106 deletions(-) create mode 100644 src/components/ConfigDataLoader.tsx diff --git a/package.json b/package.json index b46c215..870509b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "blink-eye", "private": true, - "version": "1.8.1", + "version": "1.9.0", "type": "module", "displayName": "Blink Eye", "categories": ["Other"], diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index df460a3..0778e1b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "Blink-Eye" -version = "1.8.1" +version = "1.9.0" dependencies = [ "serde", "serde_json", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9cfcf3a..8cd0f55 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "Blink-Eye" -version = "1.8.1" +version = "1.9.0" description = "A minimalist eye care reminder app for Windows, macOS, and Linux." authors = ["Noman Dhoni"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index fdc3320..5a776d1 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2.0.6", "productName": "Blink Eye", - "version": "1.8.1", + "version": "1.9.0", "identifier": "com.blinkeye.app", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/ConfigDataLoader.tsx b/src/components/ConfigDataLoader.tsx new file mode 100644 index 0000000..31022b9 --- /dev/null +++ b/src/components/ConfigDataLoader.tsx @@ -0,0 +1,60 @@ +import { useEffect } from "react"; +import { BaseDirectory } from "@tauri-apps/api/path"; +import { exists } from "@tauri-apps/plugin-fs"; +import Database from "@tauri-apps/plugin-sql"; + +const ConfigDataLoader: React.FC = () => { + const defaultWorkday = { + Monday: { start: "09:00", end: "17:00" }, + Tuesday: { start: "09:00", end: "17:00" }, + Wednesday: { start: "09:00", end: "17:00" }, + Thursday: { start: "09:00", end: "17:00" }, + Friday: { start: "09:00", end: "17:00" }, + Saturday: null, + Sunday: null, + }; + + useEffect(() => { + const setupDatabase = async () => { + // Check if the database file exists + const dbExists = await exists("appconfig.db", { + baseDir: BaseDirectory.AppData, + }); + + // Initialize the database + const db = await Database.load("sqlite:appconfig.db"); + + if (!dbExists) { + console.log("Database does not exist. Initializing..."); + + // Create the tables + await db.execute(` + CREATE TABLE IF NOT EXISTS config ( + key TEXT PRIMARY KEY, + value TEXT + ); + `); + + // Insert default values + await db.execute(`INSERT INTO config (key, value) VALUES (?, ?);`, [ + "blinkEyeWorkday", + JSON.stringify(defaultWorkday), + ]); + await db.execute(`INSERT INTO config (key, value) VALUES (?, ?);`, [ + "isWorkdayEnabled", + "false", + ]); + + console.log("Database initialized with default configuration."); + } else { + console.log("Database already exists. No action needed."); + } + }; + + setupDatabase(); + }, []); + + return null; // This component does not render anything +}; + +export default ConfigDataLoader; diff --git a/src/components/window/Workday.tsx b/src/components/window/Workday.tsx index 631411b..74a03c5 100644 --- a/src/components/window/Workday.tsx +++ b/src/components/window/Workday.tsx @@ -1,5 +1,4 @@ import { useState, useEffect } from "react"; -import { load } from "@tauri-apps/plugin-store"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; import toast from "react-hot-toast"; @@ -7,44 +6,49 @@ import { Label } from "../ui/label"; import { Separator } from "../ui/separator"; import { Clock } from "lucide-react"; import { Switch } from "../ui/switch"; +import Database from "@tauri-apps/plugin-sql"; type Schedule = { start: string; end: string } | null; -// Define the type for a single day's schedule -type DaySchedule = { - start: string; - end: string; -} | null; - -// Define the type for the workday object -type Workday = { - [day: string]: DaySchedule; -}; -const defaultWorkday: Record = { - Monday: { start: "09:00", end: "17:00" }, - Tuesday: { start: "09:00", end: "17:00" }, - Wednesday: { start: "09:00", end: "17:00" }, - Thursday: { start: "09:00", end: "17:00" }, - Friday: { start: "09:00", end: "17:00" }, - Saturday: null, - Sunday: null, -}; +type Workday = { [day: string]: Schedule }; -export default function Workday() { - const [workday, setWorkday] = - useState>(defaultWorkday); +const Workday = () => { + const [workday, setWorkday] = useState(null); + const [isWorkdayEnabled, setIsWorkdayEnabled] = useState(false); useEffect(() => { - const fetchWorkday = async () => { - const store = await load("store.json", { autoSave: false }); - const savedWorkday = await store.get("blinkEyeWorkday"); + const fetchConfig = async () => { + const db = await Database.load("sqlite:appconfig.db"); + + // Define a type for the query result + type ConfigResult = { value: string }; + + // Fetch the `workday` setup + const workdayData = (await db.select( + "SELECT value FROM config WHERE key = ?", + ["blinkEyeWorkday"] + )) as ConfigResult[]; // Specify the expected structure - // Ensure the saved workday matches the expected type - if (savedWorkday && typeof savedWorkday === "object") { - setWorkday(savedWorkday); + if (workdayData.length > 0 && workdayData[0].value) { + try { + const parsedWorkday = JSON.parse(workdayData[0].value) as Workday; + setWorkday(parsedWorkday); + } catch (error) { + console.error("Failed to parse workday data:", error); + } + } + + // Fetch the `isWorkdayEnabled` status + const isEnabledData = (await db.select( + "SELECT value FROM config WHERE key = ?", + ["isWorkdayEnabled"] + )) as ConfigResult[]; // Specify the expected structure + + if (isEnabledData.length > 0 && isEnabledData[0].value) { + setIsWorkdayEnabled(isEnabledData[0].value === "true"); } }; - fetchWorkday(); + fetchConfig(); }, []); const handleTimeChange = ( @@ -52,105 +56,160 @@ export default function Workday() { type: "start" | "end", value: string ) => { + if (!workday) return; setWorkday((prev) => ({ ...prev, [day]: { - ...prev[day], + ...prev![day], [type]: value, - } as DaySchedule, // Ensure proper typing here + } as Schedule, })); }; const toggleWorkingDay = (day: string) => { + if (!workday) return; setWorkday((prev) => ({ ...prev, - [day]: prev[day] ? null : { start: "09:00", end: "17:00" }, + [day]: prev![day] ? null : { start: "09:00", end: "17:00" }, })); }; const handleSave = async () => { - const store = await load("store.json", { autoSave: false }); - await store.set("blinkEyeWorkday", workday); - await store.save(); - toast.success("Workday settings saved!"); + const db = await Database.load("sqlite:appconfig.db"); + + if (workday) { + await db.execute( + "INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)", + ["blinkEyeWorkday", JSON.stringify(workday)] + ); + } + + toast.success("Workday settings saved!", { + duration: 2000, + position: "bottom-right", + }); }; + const handleWorkdayToggle = async () => { + const newValue = !isWorkdayEnabled; + setIsWorkdayEnabled(newValue); + + const db = await Database.load("sqlite:appconfig.db"); + await db.execute( + "INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)", + ["isWorkdayEnabled", newValue.toString()] + ); + + toast.success( + `Workday ${newValue ? "enabled" : "disabled"} successfully!`, + { + duration: 2000, + position: "bottom-right", + } + ); + }; + + if (!workday) { + return
Loading...
; + } + return (
-

Workday Setup

-

- Configure your work hours for each day of the week. Toggle to set - working or non-working days. -

+
+
+

Workday Setup

+

+ Configure your work hours for each day of the week. Toggle to set + working or non-working days. +

+
+
+ + +
+
-
- {Object.entries(workday).map(([day, schedule]) => ( -
-
-

{day}

-
- - toggleWorkingDay(day)} - /> -
-
- {schedule ? ( -
-
-
+ )}
); -} +}; + +export default Workday; diff --git a/src/main.tsx b/src/main.tsx index 921a357..b9e3832 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,7 @@ import DefaultStartMinimize from "./components/DefaultStartMinimize"; import EncryptionComponent from "./components/EncryptionComponent"; import LicenseValidationComponent from "./components/LicenseValidationComponent"; import { PremiumFeaturesProvider } from "./contexts/PremiumFeaturesContext"; +import ConfigDataLoader from "./components/ConfigDataLoader"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( @@ -14,6 +15,7 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( + From 247e224534c6f61e5bfe73252082d213c44af2ac Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 19:40:59 +0600 Subject: [PATCH 3/8] Fixedd the workday logic --- src/components/ReminderHandler.tsx | 145 +++++++++++++++++++++++++++ src/components/window/Settings.tsx | 153 +++++++++++++---------------- src/components/window/Workday.tsx | 41 +++++--- src/contexts/TriggerReRender.tsx | 35 +++++++ src/main.tsx | 7 +- 5 files changed, 283 insertions(+), 98 deletions(-) create mode 100644 src/components/ReminderHandler.tsx create mode 100644 src/contexts/TriggerReRender.tsx diff --git a/src/components/ReminderHandler.tsx b/src/components/ReminderHandler.tsx new file mode 100644 index 0000000..4bc1afd --- /dev/null +++ b/src/components/ReminderHandler.tsx @@ -0,0 +1,145 @@ +import { useEffect, useState } from "react"; +import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; +import Database from "@tauri-apps/plugin-sql"; +import { usePremiumFeatures } from "../contexts/PremiumFeaturesContext"; +import { load } from "@tauri-apps/plugin-store"; +import { useTrigger } from "../contexts/TriggerReRender"; + +// Define the type for workday configuration +type Workday = { [day: string]: { start: string; end: string } } | null; + +const ReminderHandler = () => { + const { trigger } = useTrigger(); // Use the trigger value from the context + const [interval, setInterval] = useState(20); + const [workday, setWorkday] = useState(null); + const [isWorkdayEnabled, setIsWorkdayEnabled] = useState(false); + const { canAccessPremiumFeatures } = usePremiumFeatures(); + + // Function to open the reminder window + const openReminderWindow = () => { + console.log("Opening reminder window..."); + const webview = new WebviewWindow("ReminderWindow", { + url: "/reminder", + fullscreen: true, + alwaysOnTop: true, + title: "Take A Break Reminder - Blink Eye", + skipTaskbar: true, + }); + + webview.once("tauri://created", () => { + console.log("Reminder window created"); + }); + + webview.once("tauri://error", (e) => { + console.error("Error creating reminder window:", e); + }); + }; + + // Fetch settings when `trigger` changes + useEffect(() => { + const fetchSettings = async () => { + console.log("Fetching settings due to trigger:", trigger); + const db = await Database.load("sqlite:appconfig.db"); + const store = await load("store.json", { autoSave: false }); + + // Load the reminder interval from storage + const storedInterval = await store.get( + "blinkEyeReminderInterval" + ); + if (storedInterval) setInterval(storedInterval); + + // Fetch workday setup from the database + type ConfigResult = { value: string }; + const workdayData = (await db.select( + "SELECT value FROM config WHERE key = ?", + ["blinkEyeWorkday"] + )) as ConfigResult[]; + if (workdayData.length > 0 && workdayData[0].value) { + try { + const parsedWorkday = JSON.parse(workdayData[0].value) as Workday; + setWorkday(parsedWorkday); + } catch (error) { + console.error("Failed to parse workday data:", error); + } + } + + // Fetch whether workday is enabled + const isEnabledData = (await db.select( + "SELECT value FROM config WHERE key = ?", + ["isWorkdayEnabled"] + )) as ConfigResult[]; + + if (isEnabledData.length > 0 && isEnabledData[0].value) { + setIsWorkdayEnabled(isEnabledData[0].value === "true"); + } + console.log(workdayData, "workdayData"); + console.log(storedInterval, "storedInterval"); + console.log(isWorkdayEnabled, "isWorkdayEnabled"); + }; + + fetchSettings(); + }, [trigger]); // Refetch settings when the trigger updates + + // Handle interval-based reminder logic + useEffect(() => { + console.log("Initializing reminder logic"); + let timer: number | null = null; + + const startReminder = () => { + console.log("Starting reminder timer with interval:", interval); + timer = window.setInterval(() => { + openReminderWindow(); + }, interval * 60 * 1000); // The interval value will be non-null + }; + + const checkWorkdayAndStartTimer = () => { + const now = new Date(); + const day = now.toLocaleString("en-US", { weekday: "long" }); + const todayWorkday = workday?.[day]; + + if (canAccessPremiumFeatures && isWorkdayEnabled) { + if (todayWorkday) { + const [startHour, startMinute] = todayWorkday.start + .split(":") + .map(Number); + const [endHour, endMinute] = todayWorkday.end.split(":").map(Number); + + const startTime = new Date(); + startTime.setHours(startHour, startMinute, 0, 0); + + const endTime = new Date(); + endTime.setHours(endHour, endMinute, 0, 0); + + console.log("Start time:", startTime); + console.log("End time:", endTime); + console.log("Now:", now); + + if (now >= startTime && now <= endTime) { + console.log("Within workday window. Starting reminder."); + startReminder(); + } else { + console.log("Outside workday window. Reminder not started."); + } + } else { + console.log("No workday setup for today. Reminder skipped."); + } + } else { + console.log("Non-premium user or workday disabled. Starting reminder."); + startReminder(); + } + }; + + // Start reminder logic if necessary + if (workday || !canAccessPremiumFeatures) { + checkWorkdayAndStartTimer(); + } + + return () => { + if (timer !== null) window.clearInterval(timer); // Cleanup previous timers + }; + }, [workday, isWorkdayEnabled, canAccessPremiumFeatures, interval]); + + return null; +}; + +export default ReminderHandler; diff --git a/src/components/window/Settings.tsx b/src/components/window/Settings.tsx index 70417e0..46a2c73 100644 --- a/src/components/window/Settings.tsx +++ b/src/components/window/Settings.tsx @@ -5,14 +5,17 @@ import { load } from "@tauri-apps/plugin-store"; import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; import { useState, useEffect } from "react"; import toast from "react-hot-toast"; +import { useTrigger } from "../../contexts/TriggerReRender"; + const Settings = () => { + const { triggerUpdate } = useTrigger(); // Access triggerUpdate from the context const [interval, setInterval] = useState(20); const [duration, setDuration] = useState(20); const [reminderText, setReminderText] = useState(""); - const [workday, setWorkday] = useState(null); + // Function to open the reminder window const openReminderWindow = () => { - console.log("Clicked"); + console.log("Opening reminder window..."); const webview = new WebviewWindow("ReminderWindow", { url: "/reminder", fullscreen: true, @@ -20,14 +23,16 @@ const Settings = () => { title: "Take A Break Reminder - Blink Eye", skipTaskbar: true, }); + webview.once("tauri://created", () => { - console.log("Webview created"); + console.log("Reminder window created"); }); webview.once("tauri://error", (e) => { - console.error("Error creating webview:", e); + console.error("Error creating reminder window:", e); }); }; - console.log(interval, duration, reminderText, "settings"); + + // Load settings from the store when the component mounts useEffect(() => { const fetchSettings = async () => { const store = await load("store.json", { autoSave: false }); @@ -40,110 +45,86 @@ const Settings = () => { const storedReminderText = await store.get( "blinkEyeReminderScreenText" ); - const storedWorkday = await store.get("blinkEyeWorkday"); if (storedInterval) setInterval(storedInterval); if (storedDuration) setDuration(storedDuration); if (storedReminderText) setReminderText(storedReminderText); - if (storedWorkday) setWorkday(storedWorkday); }; - console.log(interval, duration, reminderText, "settings 2"); + fetchSettings(); - console.log(interval, duration, reminderText, "settings3"); }, []); - useEffect(() => { - let timer: number | null = null; - - const checkWorkdayAndStartTimer = () => { - const now = new Date(); - const day = now.toLocaleString("en-US", { weekday: "long" }); - const todayWorkday = workday?.[day]; - - if (todayWorkday) { - const [startHour, startMinute] = todayWorkday.start - .split(":") - .map(Number); - const [endHour, endMinute] = todayWorkday.end.split(":").map(Number); - - const startTime = new Date(); - startTime.setHours(startHour, startMinute, 0, 0); - - const endTime = new Date(); - endTime.setHours(endHour, endMinute, 0, 0); - - if (now >= startTime && now <= endTime) { - timer = window.setInterval(() => { - openReminderWindow(); - }, interval * 60 * 1000); - } - } - }; - - if (workday) checkWorkdayAndStartTimer(); - - return () => { - if (timer !== null) window.clearInterval(timer); - }; - }, [workday, interval]); - + // Save settings to the store when the save button is clicked const handleSave = async () => { + // Input validation + if (interval <= 0) { + toast.error("Interval must be greater than 0 minutes."); + return; + } + if (duration <= 0) { + toast.error("Duration must be greater than 0 seconds."); + return; + } + const store = await load("store.json", { autoSave: false }); - const storee = await load("userScreenOnTime.json", { autoSave: false }); - await store.set("blinkEyeReminderInterval", interval); await store.set("blinkEyeReminderDuration", duration); await store.set("blinkEyeReminderScreenText", reminderText); - + await store.set("blinkEyeReminderInterval", interval); await store.save(); - toast.success("Successfully Saved the settings!", { + + triggerUpdate(); // Notify other components to refresh data + + toast.success("Successfully saved the settings!", { duration: 2000, position: "bottom-right", }); - const timeData = await storee.get("timeData"); - console.log("Saved settings:", { interval, duration }, timeData); + + console.log("Saved settings:", { interval, duration, reminderText }); }; return ( - <> -
-
- - setInterval(parseInt(e.target.value, 10) || 1)} - /> -
-
- - setDuration(parseInt(e.target.value, 10) || 1)} - /> -
-
- - setReminderText(e.target.value)} - /> -
+
+
+ + setInterval(Math.max(1, parseInt(e.target.value, 10) || 1)) // Enforce minimum value + } + /> +
+
+ + setDuration(Math.max(1, parseInt(e.target.value, 10) || 1)) // Enforce minimum value + } + /> +
+
+ + setReminderText(e.target.value.trim())} // Trim extra spaces + /> +
+
-
- +
); }; diff --git a/src/components/window/Workday.tsx b/src/components/window/Workday.tsx index 74a03c5..5d04a4e 100644 --- a/src/components/window/Workday.tsx +++ b/src/components/window/Workday.tsx @@ -7,11 +7,16 @@ import { Separator } from "../ui/separator"; import { Clock } from "lucide-react"; import { Switch } from "../ui/switch"; import Database from "@tauri-apps/plugin-sql"; +import { useTrigger } from "../../contexts/TriggerReRender"; +import { usePremiumFeatures } from "../../contexts/PremiumFeaturesContext"; type Schedule = { start: string; end: string } | null; type Workday = { [day: string]: Schedule }; const Workday = () => { + const { triggerUpdate } = useTrigger(); + const { canAccessPremiumFeatures } = usePremiumFeatures(); + const [workday, setWorkday] = useState(null); const [isWorkdayEnabled, setIsWorkdayEnabled] = useState(false); @@ -22,7 +27,7 @@ const Workday = () => { // Define a type for the query result type ConfigResult = { value: string }; - // Fetch the `workday` setup + // Fetch the workday setup const workdayData = (await db.select( "SELECT value FROM config WHERE key = ?", ["blinkEyeWorkday"] @@ -37,7 +42,7 @@ const Workday = () => { } } - // Fetch the `isWorkdayEnabled` status + // Fetch the isWorkdayEnabled status const isEnabledData = (await db.select( "SELECT value FROM config WHERE key = ?", ["isWorkdayEnabled"] @@ -75,15 +80,22 @@ const Workday = () => { }; const handleSave = async () => { - const db = await Database.load("sqlite:appconfig.db"); + if (!canAccessPremiumFeatures) { + toast.error("You need a valid license to save Workday settings.", { + duration: 2000, + position: "bottom-right", + }); + return; + } + const db = await Database.load("sqlite:appconfig.db"); if (workday) { await db.execute( "INSERT OR REPLACE INTO config (key, value) VALUES (?, ?)", ["blinkEyeWorkday", JSON.stringify(workday)] ); } - + triggerUpdate(); toast.success("Workday settings saved!", { duration: 2000, position: "bottom-right", @@ -91,6 +103,15 @@ const Workday = () => { }; const handleWorkdayToggle = async () => { + if (!canAccessPremiumFeatures) { + setIsWorkdayEnabled(false); // Ensure toggle is turned off + toast.error("You need a valid license to enable this feature.", { + duration: 2000, + position: "bottom-right", + }); + return; + } + const newValue = !isWorkdayEnabled; setIsWorkdayEnabled(newValue); @@ -100,12 +121,10 @@ const Workday = () => { ["isWorkdayEnabled", newValue.toString()] ); + triggerUpdate(); toast.success( `Workday ${newValue ? "enabled" : "disabled"} successfully!`, - { - duration: 2000, - position: "bottom-right", - } + { duration: 2000, position: "bottom-right" } ); }; @@ -120,8 +139,8 @@ const Workday = () => {

Workday Setup

- Configure your work hours for each day of the week. Toggle to set - working or non-working days. + Configure your work hours for each day of the week.
Toggle + to set working or non-working days.

@@ -130,7 +149,7 @@ const Workday = () => {
diff --git a/src/contexts/TriggerReRender.tsx b/src/contexts/TriggerReRender.tsx new file mode 100644 index 0000000..c3e66d2 --- /dev/null +++ b/src/contexts/TriggerReRender.tsx @@ -0,0 +1,35 @@ +import React, { createContext, useContext, useState, ReactNode } from "react"; + +// Define the context type +interface TriggerContextType { + trigger: number; // Use a number for incremental changes + triggerUpdate: () => void; // Function to trigger updates +} + +// Create the context +const TriggerContext = createContext(undefined); + +// Provider component +export const TriggerProvider = ({ children }: { children: ReactNode }) => { + const [trigger, setTrigger] = useState(0); + + // Function to update the trigger + const triggerUpdate = () => { + setTrigger((prev) => prev + 1); // Increment to ensure a change + }; + + return ( + + {children} + + ); +}; + +// Custom hook for consuming the context +export const useTrigger = () => { + const context = useContext(TriggerContext); + if (!context) { + throw new Error("useTrigger must be used within a TriggerProvider"); + } + return context; +}; diff --git a/src/main.tsx b/src/main.tsx index b9e3832..1f2b4f3 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,6 +7,8 @@ import EncryptionComponent from "./components/EncryptionComponent"; import LicenseValidationComponent from "./components/LicenseValidationComponent"; import { PremiumFeaturesProvider } from "./contexts/PremiumFeaturesContext"; import ConfigDataLoader from "./components/ConfigDataLoader"; +import ReminderHandler from "./components/ReminderHandler"; +import { TriggerProvider } from "./contexts/TriggerReRender"; ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( @@ -16,7 +18,10 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - + + + + From 89cb620aba166d48131b0bbd648bed2444c4cb4b Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 20:47:07 +0600 Subject: [PATCH 4/8] Added update available toast --- src/components/ConfigDataLoader.tsx | 24 ++++++++- src/components/window/Reminder.tsx | 26 ++++++++++ src/contexts/TriggerReRender.tsx | 2 +- src/hooks/useAutoUpdater.ts | 76 +++++++++++++++++++---------- 4 files changed, 99 insertions(+), 29 deletions(-) diff --git a/src/components/ConfigDataLoader.tsx b/src/components/ConfigDataLoader.tsx index 31022b9..376c7df 100644 --- a/src/components/ConfigDataLoader.tsx +++ b/src/components/ConfigDataLoader.tsx @@ -2,6 +2,7 @@ import { useEffect } from "react"; import { BaseDirectory } from "@tauri-apps/api/path"; import { exists } from "@tauri-apps/plugin-fs"; import Database from "@tauri-apps/plugin-sql"; +import { load } from "@tauri-apps/plugin-store"; const ConfigDataLoader: React.FC = () => { const defaultWorkday = { @@ -22,9 +23,9 @@ const ConfigDataLoader: React.FC = () => { }); // Initialize the database - const db = await Database.load("sqlite:appconfig.db"); if (!dbExists) { + const db = await Database.load("sqlite:appconfig.db"); console.log("Database does not exist. Initializing..."); // Create the tables @@ -44,11 +45,30 @@ const ConfigDataLoader: React.FC = () => { "isWorkdayEnabled", "false", ]); - + await db.execute(`INSERT INTO config (key, value) VALUES (?, ?);`, [ + "isUpdateAvailable", + "false", + ]); console.log("Database initialized with default configuration."); } else { console.log("Database already exists. No action needed."); } + + const storeExists = await exists("store.json", { + baseDir: BaseDirectory.AppData, + }); + if (!storeExists) { + const store = await load("store.json", { autoSave: false }); + await store.set("blinkEyeReminderDuration", 20); + await store.set("blinkEyeReminderInterval", 20); + await store.set( + "blinkEyeReminderScreenText", + "Look 20 feet away to protect your eyes." + ); + await store.save(); + } else { + console.log("Store already exists. No action needed."); + } }; setupDatabase(); diff --git a/src/components/window/Reminder.tsx b/src/components/window/Reminder.tsx index 71d4ecb..272de06 100644 --- a/src/components/window/Reminder.tsx +++ b/src/components/window/Reminder.tsx @@ -15,8 +15,15 @@ import PlainGradientAnimation from "../backgrounds/PlainGradientAnimation"; import StarryBackground from "../backgrounds/StarryBackground"; import { useTimeCountContext } from "../../contexts/TimeCountContext"; import { usePremiumFeatures } from "../../contexts/PremiumFeaturesContext"; +import Database from "@tauri-apps/plugin-sql"; +import toast, { Toaster } from "react-hot-toast"; +import { CloudDownload } from "lucide-react"; const appWindow = getCurrentWebviewWindow(); +// Define the expected result type for the select query +interface ConfigRow { + value: string; // The 'value' column in the config table is expected to be a string +} const Reminder: React.FC = () => { const { canAccessPremiumFeatures } = usePremiumFeatures(); @@ -25,6 +32,7 @@ const Reminder: React.FC = () => { const [timeLeft, setTimeLeft] = useState(20); const [reminderDuration, setReminderDuration] = useState(20); const [reminderText, setStoredReminderText] = useState(""); + useEffect(() => { const fetchReminderScreenInfo = async () => { const reminderStyleData = await load("ReminderThemeStyle.json"); @@ -48,7 +56,24 @@ const Reminder: React.FC = () => { setReminderDuration(storedDuration); setTimeLeft(storedDuration); } + // Load the database + const db = await Database.load("sqlite:appconfig.db"); + + // Retrieve the 'isUpdateAvailable' value from the config table + const result: ConfigRow[] = await db.select( + "SELECT value FROM config WHERE key = 'isUpdateAvailable';" + ); + + // Show toast if the update is available + if (result.length > 0 && result[0].value === "true") { + toast.success("Update available!", { + duration: 2000, + position: "bottom-right", + icon: , + }); + } }; + fetchReminderScreenInfo(); }, []); @@ -133,6 +158,7 @@ const Reminder: React.FC = () => {
+
); }; diff --git a/src/contexts/TriggerReRender.tsx b/src/contexts/TriggerReRender.tsx index c3e66d2..5c87100 100644 --- a/src/contexts/TriggerReRender.tsx +++ b/src/contexts/TriggerReRender.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useContext, useState, ReactNode } from "react"; +import { createContext, useContext, useState, ReactNode } from "react"; // Define the context type interface TriggerContextType { diff --git a/src/hooks/useAutoUpdater.ts b/src/hooks/useAutoUpdater.ts index a8f6415..4965ebb 100644 --- a/src/hooks/useAutoUpdater.ts +++ b/src/hooks/useAutoUpdater.ts @@ -1,16 +1,29 @@ import { useState, useEffect } from "react"; import { check } from "@tauri-apps/plugin-updater"; import { relaunch } from "@tauri-apps/plugin-process"; +import Database from "@tauri-apps/plugin-sql"; export const useUpdater = () => { const [isUpdateAvailable, setIsUpdateAvailable] = useState(false); useEffect(() => { const updateApp = async () => { - const update = await check(); - if (update) { - console.log(`Update available: ${update.version}`); - setIsUpdateAvailable(true); // Trigger alert dialog + try { + // Check for updates + const update = await check(); + if (update) { + console.log(`Update available: ${update.version}`); + setIsUpdateAvailable(true); + + const db = await Database.load("sqlite:appconfig.db"); + // Update the value in the database + await db.execute( + `UPDATE config SET value = ? WHERE key = 'isUpdateAvailable';`, + ["true"] + ); + } + } catch (error) { + console.error("Error during update check:", error); } }; @@ -18,29 +31,40 @@ export const useUpdater = () => { }, []); const handleUpdate = async () => { - const update = await check(); - if (update) { - let downloaded = 0; - let contentLength = 0; - - await update.downloadAndInstall((event) => { - switch (event.event) { - case "Started": - contentLength = event.data.contentLength ?? 0; - console.log(`Started downloading ${contentLength} bytes`); - break; - case "Progress": - downloaded += event.data.chunkLength ?? 0; - console.log(`Downloaded ${downloaded} of ${contentLength}`); - break; - case "Finished": - console.log("Download finished"); - break; - } - }); + try { + const update = await check(); + if (update) { + let downloaded = 0; + let contentLength = 0; + + await update.downloadAndInstall((event) => { + switch (event.event) { + case "Started": + contentLength = event.data.contentLength ?? 0; + console.log(`Started downloading ${contentLength} bytes`); + break; + case "Progress": + downloaded += event.data.chunkLength ?? 0; + console.log(`Downloaded ${downloaded} of ${contentLength}`); + break; + case "Finished": + console.log("Download finished"); + break; + } + }); - console.log("Update installed"); - await relaunch(); + // Update the database value after installation + const db = await Database.load("sqlite:appconfig.db"); + await db.execute( + `UPDATE config SET value = ? WHERE key = 'isUpdateAvailable';`, + ["false"] + ); + + console.log("Update installed"); + await relaunch(); + } + } catch (error) { + console.error("Error during update installation:", error); } }; From 1bf71ea6109e5ec9824e93fce63e6f37ac40ac8e Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 22:07:42 +0600 Subject: [PATCH 5/8] Added using strict mode functionality --- src/components/ConfigDataLoader.tsx | 4 ++ src/components/StrictModeToggle.tsx | 75 +++++++++++++++++++++++++++ src/components/window/AllSettings.tsx | 2 + src/components/window/Reminder.tsx | 44 ++++++++++------ 4 files changed, 110 insertions(+), 15 deletions(-) create mode 100644 src/components/StrictModeToggle.tsx diff --git a/src/components/ConfigDataLoader.tsx b/src/components/ConfigDataLoader.tsx index 376c7df..c781000 100644 --- a/src/components/ConfigDataLoader.tsx +++ b/src/components/ConfigDataLoader.tsx @@ -49,6 +49,10 @@ const ConfigDataLoader: React.FC = () => { "isUpdateAvailable", "false", ]); + await db.execute(`INSERT INTO config (key, value) VALUES (?, ?);`, [ + "usingStrictMode", + "false", + ]); console.log("Database initialized with default configuration."); } else { console.log("Database already exists. No action needed."); diff --git a/src/components/StrictModeToggle.tsx b/src/components/StrictModeToggle.tsx new file mode 100644 index 0000000..443220e --- /dev/null +++ b/src/components/StrictModeToggle.tsx @@ -0,0 +1,75 @@ +import { useState, useEffect } from "react"; +import { Label } from "./ui/label"; +import { Switch } from "./ui/switch"; +import Database from "@tauri-apps/plugin-sql"; + +interface ConfigRow { + value: string; +} + +const StrictModeToggle = () => { + const [isStrictModeEnabled, setIsStrictModeEnabled] = useState(false); + + useEffect(() => { + const initializeStrictMode = async () => { + try { + // Load initial configuration store + const db = await Database.load("sqlite:appconfig.db"); + + // Retrieve the 'usingStrictMode' value from the config table + const result: ConfigRow[] = await db.select( + "SELECT value FROM config WHERE key = 'usingStrictMode';" + ); + + if (result.length > 0) { + setIsStrictModeEnabled(result[0].value === "true"); + } + } catch (error) { + console.error("Failed to initialize strict mode:", error); + } + }; + initializeStrictMode(); + }, []); + + const handleCheckboxChange = async (checked: boolean) => { + try { + const db = await Database.load("sqlite:appconfig.db"); + + // Use an `INSERT OR REPLACE` or `UPDATE` query + await db.execute( + ` + INSERT INTO config (key, value) VALUES ('usingStrictMode', ?) + ON CONFLICT(key) DO UPDATE SET value = excluded.value; + `, + [checked ? "true" : "false"] + ); + + setIsStrictModeEnabled(checked); + } catch (error) { + console.error("Failed to update strict mode status:", error); + } + }; + + return ( +
+
+ +

+ This will hide the 'Skip this time' button to force follow the break. +

+
+ +
+ ); +}; + +export default StrictModeToggle; diff --git a/src/components/window/AllSettings.tsx b/src/components/window/AllSettings.tsx index 0bf1106..a96df7d 100644 --- a/src/components/window/AllSettings.tsx +++ b/src/components/window/AllSettings.tsx @@ -1,4 +1,5 @@ import AutoStartToggle from "../AutoStartToggle"; +import StrictModeToggle from "../StrictModeToggle"; // import PomodoroTimerToggle from "../PomodoroTimerToggle"; const AllSettings = () => { @@ -7,6 +8,7 @@ const AllSettings = () => {
{/* */} +
); diff --git a/src/components/window/Reminder.tsx b/src/components/window/Reminder.tsx index 272de06..db4d142 100644 --- a/src/components/window/Reminder.tsx +++ b/src/components/window/Reminder.tsx @@ -32,6 +32,7 @@ const Reminder: React.FC = () => { const [timeLeft, setTimeLeft] = useState(20); const [reminderDuration, setReminderDuration] = useState(20); const [reminderText, setStoredReminderText] = useState(""); + const [isUsingStictMode, setIsUsingStrictMode] = useState(false); useEffect(() => { const fetchReminderScreenInfo = async () => { @@ -60,18 +61,29 @@ const Reminder: React.FC = () => { const db = await Database.load("sqlite:appconfig.db"); // Retrieve the 'isUpdateAvailable' value from the config table - const result: ConfigRow[] = await db.select( + const updateAvailableResult: ConfigRow[] = await db.select( "SELECT value FROM config WHERE key = 'isUpdateAvailable';" ); // Show toast if the update is available - if (result.length > 0 && result[0].value === "true") { + if ( + updateAvailableResult.length > 0 && + updateAvailableResult[0].value === "true" + ) { toast.success("Update available!", { duration: 2000, position: "bottom-right", icon: , }); } + + const strictModeResult: ConfigRow[] = await db.select( + "SELECT value FROM config WHERE key = 'usingStrictMode';" + ); + + if (strictModeResult.length > 0) { + setIsUsingStrictMode(strictModeResult[0].value === "true"); + } }; fetchReminderScreenInfo(); @@ -143,20 +155,22 @@ const Reminder: React.FC = () => {
{reminderText || "Look 20 feet far away to protect your eyes."}
- + Skip this Time + + + + + )}
From 92d25bbbec5381d654d9f8fd2f6011b31d799b95 Mon Sep 17 00:00:00 2001 From: Noman Dhoni Date: Mon, 18 Nov 2024 22:16:34 +0600 Subject: [PATCH 6/8] Fixed basic seo --- website/configs/seo.ts | 37 ++++++------------------------------- 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/website/configs/seo.ts b/website/configs/seo.ts index 228f86b..841d14d 100644 --- a/website/configs/seo.ts +++ b/website/configs/seo.ts @@ -1,8 +1,12 @@ export const SEO = { - title: "Blink Eye - Best Free Eye Care & Break Timer for Mac, Windows, Linux", + title: "Blink Eye | Best Eye Care & Break Timer for Mac, Windows, Linux", description: "A minimalist eye care reminder app to reduce eye strain, featuring customizable timers, full-screen popups, audio mute.", keywords: [ + "prevent rsi app", + "prevent cvs app", + "rsi app", + "cvs app", "best eye care app 2024", "screen break reminder app", "free eye health app download", @@ -37,9 +41,7 @@ export const SEO = { "eye care reminder app for Linux", "blink eye", "blink eye for windows", - "Noman Dhoni", "Noman Dhoni Made App", - "nomandhoni", "eye care app for windows", "20 20 20 rule app for windows", "eye care", @@ -53,44 +55,17 @@ export const SEO = { "eye care tips", "eye exercises app", "eye protection app", - "blink eye alternative", - "eye care app for android", - "eye care app for ios", "eye care app for pc", "eye care app for laptop", "eye care app for desktop", - "eye care app for chrome", - "eye care app for firefox", - "eye care app for safari", - "eye care app for edge", "eye care app for windows 10", "eye care app for windows 11", - "eye care app for windows 8", - "eye care app for windows 7", - "eye care app for windows xp", - "eye care app for windows vista", - "eye care app for windows 2000", - "eye care app for windows 98", - "eye care app for windows 95", - "eye care app for windows 3.1", - "eye care app for windows nt", - "eye care app for windows me", - "eye care app for windows ce", "blink eye download", "blink eye review", "eye care app for windows", "20 20 20 rule app for windows", - "eye care reminder app", - "eye care software", - "eye care tips", - "eye exercises app", - "eye protection app", - "eye care", - "eye health app", - "20 20 20 rule app", ], - thumb: - "https://repository-images.githubusercontent.com/749625079/db502010-82d3-4004-8e01-283d20915ee0", + thumb: "https://utfs.io/f/93hqarYp4cDdRfdEFOs3IvZkCG1g7rYl8WhFVBbNozK265eA", url: "https://blinkeye.vercel.app", twitter: "@blinkeyeapp", }; From 0825e916b18628b308890e91014253bf9c2f671c Mon Sep 17 00:00:00 2001 From: Noman Dhoni <92979541+nomandhoni-cs@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:17:21 +0000 Subject: [PATCH 7/8] Fixed the website seo and added one more section --- website/app/(home)/page.tsx | 20 +- website/app/howblinkeyehelps/page.tsx | 14 + website/app/sitemap.ts | 1 + website/bun.lockb | Bin 459132 -> 460644 bytes website/components/download-app.tsx | 4 +- website/components/features.tsx | 4 +- .../components/how-blink-eye-will-help.tsx | 239 ++++++++++++++++++ website/components/layout/footer.tsx | 1 + website/components/pricing-section.tsx | 4 +- website/components/ui/accordion.tsx | 58 +++++ website/components/ui/card.tsx | 79 ++++++ website/configs/seo.ts | 2 +- website/package.json | 1 + website/tailwind.config.ts | 136 +++++----- 14 files changed, 485 insertions(+), 78 deletions(-) create mode 100644 website/app/howblinkeyehelps/page.tsx create mode 100644 website/components/how-blink-eye-will-help.tsx create mode 100644 website/components/ui/accordion.tsx create mode 100644 website/components/ui/card.tsx diff --git a/website/app/(home)/page.tsx b/website/app/(home)/page.tsx index e3452fb..ce8a5ff 100644 --- a/website/app/(home)/page.tsx +++ b/website/app/(home)/page.tsx @@ -1,8 +1,12 @@ -import DownloadApp from '@/components/download-app'; -import { FeatureGrid } from '@/components/features'; -import OpenSource from '@/components/open-source'; -import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'; -import Link from 'next/link'; +import DownloadApp from "@/components/download-app"; +import { FeatureGrid } from "@/components/features"; +import OpenSource from "@/components/open-source"; +import { + HoverCard, + HoverCardContent, + HoverCardTrigger, +} from "@/components/ui/hover-card"; +import Link from "next/link"; import { AudioLinesIcon, Calendar, @@ -14,9 +18,10 @@ import { Timer, ToggleRight, } from "lucide-react"; -import PricingSection from '@/components/pricing-section'; +import PricingSection from "@/components/pricing-section"; +import HowBlinkEyeWillHelp from "@/components/how-blink-eye-will-help"; const RootPage = () => { - return ( + return (

Blink Eye
A @@ -106,6 +111,7 @@ const RootPage = () => { ]} /> +

diff --git a/website/app/howblinkeyehelps/page.tsx b/website/app/howblinkeyehelps/page.tsx new file mode 100644 index 0000000..b73428a --- /dev/null +++ b/website/app/howblinkeyehelps/page.tsx @@ -0,0 +1,14 @@ +import HowBlinkEyeWillHelp from "@/components/how-blink-eye-will-help"; +import { Metadata } from "next"; +export const metadata: Metadata = { + title: "How Blink Eye Helps", +}; +const HowBlinkEyeHelpsPage = () => { + return ( + <> + + + ); +}; + +export default HowBlinkEyeHelpsPage; diff --git a/website/app/sitemap.ts b/website/app/sitemap.ts index 3e2ddfc..4cfb10a 100644 --- a/website/app/sitemap.ts +++ b/website/app/sitemap.ts @@ -34,6 +34,7 @@ const sitemap = async (): Promise => { "/privacy", "/pricing", "/changelog", + "/howblinkeyehelps", ]; // Fetch release data from GitHub API diff --git a/website/bun.lockb b/website/bun.lockb index 70b03ca46a8a9ec1afe82e1fb8499be57d558bcd..b2def9c6cfaa76d5cca30666ebcfbc35d249a2ca 100755 GIT binary patch delta 81831 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�N{@Oe32Zx$Q$mzqUhS4}9glDFQ2Nuv_f zTJnQVfd>}i(f2QP3X1S~P~?DO+|iVqesNsosj5}E!=y0HMX$WJS>vmAyp~|4JX2Av zS!0K$cT}>Ey`=`Hr=-9;hWftLosFJ)CcPtH_!nL#VgLn&`=w=J7RoC!(sDx1wAx&!EStPGiSt({y!S6p?e8O zb?-7Jhv{v`dq3-uTHOs}VR@xLXTlzso~EnFW22*1NV59DkX;MEau-wov6|S3hVBgo znu=~5Hf;3z=^th4Vl;>#vmUGJU%~hglYJ#@t(;q9x70m*sXn<0vq~ z`X#rm{d0uns-8=hG)$Y~ReipDM2c?nJf5rj)WG!xdnLma_aXUn6_~~0ALakt=x?dF z1+7@wV%BxI%LK%-#yp;g(jqkk=sA@^^7tzo}Kiu)gmS-wTK?bg%q^7-}}j@@<%@O zv2`RyjNEiWAHsu0ZL>r7cW&=v8&8b*3M-zg$B3UMu2uE2?SaBm)u`o2o!rZIT5cfE z@_EnR{~LooQH1d!-j@EP3rMU#LY{nR(51g>#^pW6`@` z4*uGG{2)DtzSNwgQZUY);~|j3OU&zZIN)`s7dnAHS=3b}vpK??vmp?j6o1_<*Oo*N zc#cW?>93d=mLhyP1Y%PQkNNRRXvR0P(&LFVzVQ9E<>Q!WRqpGmJ&w{n=7OR7d$j+s(J{e>z&wK9hz zoxRm-bu0&7rn&jWJ3L`Iu}#KmMx5?tZ`9D7%d(|yB!*b?(!?}8%bL-}|Nj7EFA77$aKK%1uJrv3V@70PRbkyX7(cgO| z&pmMBs?A^9<&lN%sNGbBbF)Cmeq;+NA>qa~JEs4ITfRt`%C|5@SjslaZQ zX+NGo1?8nXW>zio>aLj{1ginu@!bWRZk_tRJF&aX+iI)yE)*u_*6g$U^E%SGayX1% z+x#_4#jmfco89%UsQdi%<`2T$c<)aI2jj7u*R8p>`<7GD!L-W)hnf-WXzNOv$l!E! zS;XZ!o11V-&0142iMT?bwB|xVfaY{pwhei_J@0c}nuN zCM#^*3R1+#K5zGEdWuKW+n6cgyoqS6I@I?Oj&|l5

WPd|5rLdz1ds#OOJjpk^Pu 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 diff --git a/website/components/download-app.tsx b/website/components/download-app.tsx index 45bc73c..c08be69 100644 --- a/website/components/download-app.tsx +++ b/website/components/download-app.tsx @@ -33,8 +33,8 @@ const DownloadApp = async () => { return (

-

- Download Now +

+ Download Free & Start Now

{/* Platform Row */} diff --git a/website/components/features.tsx b/website/components/features.tsx index a652de0..98fce7d 100644 --- a/website/components/features.tsx +++ b/website/components/features.tsx @@ -31,10 +31,10 @@ export function FeatureGrid(props: { className="container space-y-6 py-8 md:py-12 lg:py-24" >
-

+

{props.title}

-

+

{props.subtitle}

diff --git a/website/components/how-blink-eye-will-help.tsx b/website/components/how-blink-eye-will-help.tsx new file mode 100644 index 0000000..794ef70 --- /dev/null +++ b/website/components/how-blink-eye-will-help.tsx @@ -0,0 +1,239 @@ +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; +import { + EyeIcon, + ActivityIcon, + BrainIcon, + ZapIcon, + HeartIcon, + ClockIcon, + SettingsIcon, + BookOpenIcon, + SunIcon, +} from "lucide-react"; + +export default function HowBlinkEyeWillHelp() { + // const [openAccordion, setOpenAccordion] = useState(null); + + const benefits = [ + { + title: "Eye Care and Protection", + description: + "Protect your eyes from digital strain, reduce blue light exposure, and prevent Computer Vision Syndrome (CVS).", + icon: EyeIcon, + details: [ + { + subtitle: "Prevent Digital Eye Strain", + content: + "Scheduled breaks reduce symptoms like dry eyes, blurry vision, and headaches, ensuring long-term eye health.", + }, + { + subtitle: "Blue Light Protection", + content: + "Rest your eyes regularly with prompts designed to combat the harmful effects of blue light exposure.", + }, + ], + }, + { + title: "Physical Health", + description: + "Improve posture, prevent Repetitive Strain Injuries (RSI), and reduce physical discomfort.", + icon: ActivityIcon, + details: [ + { + subtitle: "Prevent Repetitive Strain Injuries (RSI)", + content: + "Regular breaks minimize strain on your hands and wrists, preventing long-term damage from repetitive tasks.", + }, + { + subtitle: "Support Better Posture", + content: + "Encourages stretching and posture checks to avoid issues like tech neck and back pain.", + }, + ], + }, + { + title: "Mental Wellness", + description: + "Boost your focus, mindfulness, and reduce stress effortlessly.", + icon: BrainIcon, + details: [ + { + subtitle: "Enhance Focus and Mindfulness", + content: + "Regular breaks help you stay sharp and focused while reducing mental fatigue and burnout.", + }, + { + subtitle: "Stress Management", + content: + "Use break intervals to practice relaxation techniques, reducing work-induced stress and tension.", + }, + ], + }, + { + title: "Boosted Productivity", + description: + "Work smarter, not harder, with productivity-focused methods.", + icon: ZapIcon, + details: [ + { + subtitle: "Pomodoro Technique Integration", + content: + "Break tasks into manageable intervals for efficient work sessions, improving task completion rates.", + }, + { + subtitle: "Cognitive Efficiency", + content: + "Strategic breaks enhance your mental performance, helping you achieve more with less effort.", + }, + ], + }, + { + title: "Healthy Screen-Time Habits", + description: + "Develop disciplined screen-time practices and minimize unnecessary distractions.", + icon: HeartIcon, + details: [ + { + subtitle: "Structured Screen-Time", + content: + "Build healthy digital habits with well-timed reminders for work and relaxation balance.", + }, + { + subtitle: "Reduce Multitasking", + content: + "Focus fully on tasks by minimizing distractions during your work and relaxation cycles.", + }, + ], + }, + { + title: "Sustainable Long-Term Benefits", + description: + "Avoid chronic issues and maintain balance for years to come.", + icon: ClockIcon, + details: [ + { + subtitle: "Prevent Chronic Vision Problems", + content: + "Take proactive measures to reduce risks of long-term digital vision problems caused by screen overuse.", + }, + { + subtitle: "Achieve Work-Life Balance", + content: + "Create sustainable habits for work and personal life with a balanced approach to productivity.", + }, + ], + }, + { + title: "Flexible and Customizable", + description: + "Tailor your experience to fit your lifestyle, profession, and individual needs.", + icon: SettingsIcon, + details: [ + { + subtitle: "Customizable Break Timers", + content: + "Set intervals that match your workflow, ensuring the app complements your unique schedule.", + }, + { + subtitle: "Built for Everyone", + content: + "Whether you’re a student, developer, designer, or remote worker, the app adapts to your needs.", + }, + ], + }, + { + title: "Research-Backed Benefits", + description: + "Enjoy features grounded in productivity and wellness studies.", + icon: BookOpenIcon, + details: [ + { + subtitle: "Evidence-Based Features", + content: + "The app’s design is inspired by research in productivity, focus, and digital well-being.", + }, + { + subtitle: "Trusted by Users", + content: + "Real user testimonials and success stories validate its effectiveness and value.", + }, + ], + }, + { + title: "Enhanced Energy and Mood", + description: + "Feel energized and stay positive throughout the day with balanced work breaks.", + icon: SunIcon, + details: [ + { + subtitle: "Boost Daily Energy", + content: + "Short, regular breaks help recharge your mind and body, keeping you energized for the day ahead.", + }, + { + subtitle: "Maintain a Positive Mood", + content: + "Break the monotony of continuous screen time to reduce frustration and enhance your overall mood.", + }, + ], + }, + ]; + + return ( +
+
+

+ How Blink Eye Will Help You +

+
+

+ Take control of your well-being with Blink Eye. Discover how + scheduled breaks can improve eye health, enhance focus, boost + productivity, and promote long-term wellness for a balanced digital + lifestyle. +

+
+ {benefits.map((benefit, index) => ( + + +
+ +
+ {benefit.title} + {benefit.description} +
+ + + + Learn More + + {benefit.details.map((detail, detailIndex) => ( +
+

+ {detail.subtitle} +

+

{detail.content}

+
+ ))} +
+
+
+
+
+ ))} +
+
+ ); +} diff --git a/website/components/layout/footer.tsx b/website/components/layout/footer.tsx index f5b8209..bd846fa 100644 --- a/website/components/layout/footer.tsx +++ b/website/components/layout/footer.tsx @@ -12,6 +12,7 @@ const routes = [ "/goodbye", "/pricing", "/changelog", + "/howblinkeyehelps", ]; export const Footer = () => { const currentYear = getCurrentYear(); diff --git a/website/components/pricing-section.tsx b/website/components/pricing-section.tsx index 0719672..6cc0ac1 100644 --- a/website/components/pricing-section.tsx +++ b/website/components/pricing-section.tsx @@ -154,9 +154,9 @@ export default function PricingSection({ return (
-

+

Choose the right plan for you -

+

Choose an affordable plan that's packed with the best features for diff --git a/website/components/ui/accordion.tsx b/website/components/ui/accordion.tsx new file mode 100644 index 0000000..6d6ec0e --- /dev/null +++ b/website/components/ui/accordion.tsx @@ -0,0 +1,58 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/utils/cn" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +

{children}
+ +)) + +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/website/components/ui/card.tsx b/website/components/ui/card.tsx new file mode 100644 index 0000000..b874cd7 --- /dev/null +++ b/website/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/utils/cn" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/website/configs/seo.ts b/website/configs/seo.ts index 841d14d..dc3edaf 100644 --- a/website/configs/seo.ts +++ b/website/configs/seo.ts @@ -1,5 +1,5 @@ export const SEO = { - title: "Blink Eye | Best Eye Care & Break Timer for Mac, Windows, Linux", + title: "Blink Eye - Best Eye Care & Break Timer for Mac, Windows, Linux", description: "A minimalist eye care reminder app to reduce eye strain, featuring customizable timers, full-screen popups, audio mute.", keywords: [ diff --git a/website/package.json b/website/package.json index 8c6151c..71d59fd 100644 --- a/website/package.json +++ b/website/package.json @@ -24,6 +24,7 @@ }, "dependencies": { "@next/third-parties": "^15.0.3", + "@radix-ui/react-accordion": "^1.2.1", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-hover-card": "^1.1.2", "@radix-ui/react-select": "^2.1.2", diff --git a/website/tailwind.config.ts b/website/tailwind.config.ts index f407f23..811ec4c 100644 --- a/website/tailwind.config.ts +++ b/website/tailwind.config.ts @@ -5,70 +5,78 @@ const config = { content: ['./pages/**/*.{ts,tsx}', './components/**/*.{ts,tsx}', './app/**/*.{ts,tsx}', './src/**/*.{ts,tsx}'], prefix: '', theme: { - container: { - center: true, - padding: '2rem', - screens: { - '2xl': '1400px', - }, - }, - extend: { - colors: { - border: 'hsl(var(--border))', - input: 'hsl(var(--input))', - ring: 'hsl(var(--ring))', - background: 'hsl(var(--background))', - foreground: 'hsl(var(--foreground))', - primary: { - DEFAULT: 'hsl(var(--primary))', - foreground: 'hsl(var(--primary-foreground))', - }, - secondary: { - DEFAULT: 'hsl(var(--secondary))', - foreground: 'hsl(var(--secondary-foreground))', - }, - destructive: { - DEFAULT: 'hsl(var(--destructive))', - foreground: 'hsl(var(--destructive-foreground))', - }, - muted: { - DEFAULT: 'hsl(var(--muted))', - foreground: 'hsl(var(--muted-foreground))', - }, - accent: { - DEFAULT: 'hsl(var(--accent))', - foreground: 'hsl(var(--accent-foreground))', - }, - popover: { - DEFAULT: 'hsl(var(--popover))', - foreground: 'hsl(var(--popover-foreground))', - }, - card: { - DEFAULT: 'hsl(var(--card))', - foreground: 'hsl(var(--card-foreground))', - }, - }, - borderRadius: { - lg: 'var(--radius)', - md: 'calc(var(--radius) - 2px)', - sm: 'calc(var(--radius) - 4px)', - }, - keyframes: { - 'accordion-down': { - from: { height: '0' }, - to: { height: 'var(--radix-accordion-content-height)' }, - }, - 'accordion-up': { - from: { height: 'var(--radix-accordion-content-height)' }, - to: { height: '0' }, - }, - }, - animation: { - 'accordion-down': 'accordion-down 0.2s ease-out', - 'accordion-up': 'accordion-up 0.2s ease-out', - }, - }, - }, + container: { + center: 'true', + padding: '2rem', + screens: { + '2xl': '1400px' + } + }, + extend: { + colors: { + border: 'hsl(var(--border))', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', + primary: { + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))' + }, + secondary: { + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))' + }, + destructive: { + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))' + }, + muted: { + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))' + }, + accent: { + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))' + }, + popover: { + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))' + }, + card: { + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))' + } + }, + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)' + }, + keyframes: { + 'accordion-down': { + from: { + height: '0' + }, + to: { + height: 'var(--radix-accordion-content-height)' + } + }, + 'accordion-up': { + from: { + height: 'var(--radix-accordion-content-height)' + }, + to: { + height: '0' + } + } + }, + animation: { + 'accordion-down': 'accordion-down 0.2s ease-out', + 'accordion-up': 'accordion-up 0.2s ease-out' + } + } + }, plugins: [require('tailwindcss-animate')], } satisfies Config; From f44bf3e8669ca5b7d3cadf23f051fcc5f5c83c2c Mon Sep 17 00:00:00 2001 From: Noman Dhoni <92979541+nomandhoni-cs@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:21:27 +0600 Subject: [PATCH 8/8] Update tailwind.config.ts --- website/tailwind.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/tailwind.config.ts b/website/tailwind.config.ts index 811ec4c..fd80e11 100644 --- a/website/tailwind.config.ts +++ b/website/tailwind.config.ts @@ -6,7 +6,7 @@ const config = { prefix: '', theme: { container: { - center: 'true', + center: true, padding: '2rem', screens: { '2xl': '1400px'