From 83d0d0b9209e1d0fc88fd684a914e2ea666a9ef7 Mon Sep 17 00:00:00 2001
From: mARTin
Date: Mon, 23 Feb 2026 22:04:16 +0100
Subject: [PATCH] fix: implement custom CSS sync spinner and update all
components
- Replaced broken animate-spin Tailwind class with custom weekly-spinner CSS
- Standardized loading indicators across Auth, Tasks, and Calendar settings
- Fixed JSX syntax errors in several components
---
src/app/globals.css | 26 +++++++++++++
src/components/AuthForm.tsx | 9 ++---
src/components/CalendarSettings.tsx | 25 +++++--------
src/components/ImportListModal.tsx | 2 +-
src/components/TaskForm.tsx | 53 ++++++++++++---------------
src/components/TaskItem.tsx | 5 +--
src/components/WeeklyView.tsx | 26 +------------
src/components/auth/EmailAuthForm.tsx | 11 ++----
8 files changed, 69 insertions(+), 88 deletions(-)
diff --git a/src/app/globals.css b/src/app/globals.css
index 90ef1fb..ab5fe63 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -2939,4 +2939,30 @@ h3 {
+/* Weekly App Spinner */
+@keyframes weekly-spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+.weekly-spinner {
+ width: 16px;
+ height: 16px;
+ border: 2px solid rgba(0, 0, 0, 0.1);
+ border-top-color: #3b82f6;
+ border-radius: 50%;
+ animation: weekly-spin 0.8s linear infinite;
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.weekly-spinner-white {
+ border: 2px solid rgba(255, 255, 255, 0.3);
+ border-top-color: white;
+}
+
+
+.dark-mode .weekly-spinner {
+ border: 2px solid rgba(255, 255, 255, 0.1);
+ border-top-color: #60a5fa;
+}
diff --git a/src/components/AuthForm.tsx b/src/components/AuthForm.tsx
index 5b13b2e..406a2dc 100644
--- a/src/components/AuthForm.tsx
+++ b/src/components/AuthForm.tsx
@@ -141,10 +141,7 @@ const AuthForm: React.FC = ({ type, onSubmit, isLoading, error })
>
{isLoading ? (
-
+
Processing...
) : type === 'signup' ? (
@@ -179,8 +176,8 @@ const AuthForm: React.FC = ({ type, onSubmit, isLoading, error })
)}
-
-
+
+
);
};
diff --git a/src/components/CalendarSettings.tsx b/src/components/CalendarSettings.tsx
index 95306da..9965941 100644
--- a/src/components/CalendarSettings.tsx
+++ b/src/components/CalendarSettings.tsx
@@ -248,10 +248,7 @@ const CalendarSettings: React.FC = ({
>
{isSyncing[connection.id] ? (
<>
-
+
Syncing...
>
) : (
@@ -290,7 +287,8 @@ const CalendarSettings: React.FC = ({
))}
- )}
+ )
+ }
Add More Calendars
@@ -376,10 +374,7 @@ const CalendarSettings: React.FC
= ({
>
{isConnectingApple ? (
<>
-
+
Connecting...
>
) : 'Connect'}
@@ -429,19 +424,17 @@ const CalendarSettings: React.FC = ({
>
{isConnectingApple ? (
<>
-
+
Verifying...
>
) : 'Verify'}
>
- )}
-
-
+ )
+ }
+
+
)
}
diff --git a/src/components/ImportListModal.tsx b/src/components/ImportListModal.tsx
index 62bc6fc..ef62091 100644
--- a/src/components/ImportListModal.tsx
+++ b/src/components/ImportListModal.tsx
@@ -82,7 +82,7 @@ export const ImportListModal: React.FC = ({
{isLoading ? (
) : lists.length === 0 ? (
diff --git a/src/components/TaskForm.tsx b/src/components/TaskForm.tsx
index f4f9caf..e61b161 100644
--- a/src/components/TaskForm.tsx
+++ b/src/components/TaskForm.tsx
@@ -27,20 +27,20 @@ const TaskForm: React.FC
= ({ onSubmit, isLoading = false }) => {
const validateForm = (): boolean => {
const newErrors: Record = {};
-
+
if (!formData.title.trim()) {
newErrors.title = 'Title is required';
}
-
+
// Validate time format if provided
if (formData.startTime && !isValidTime(formData.startTime)) {
newErrors.startTime = 'Invalid time format';
}
-
+
if (formData.endTime && !isValidTime(formData.endTime)) {
newErrors.endTime = 'Invalid time format';
}
-
+
// Check if start time is before end time if both are provided
if (formData.startTime && formData.endTime) {
const start = parseTime(formData.startTime);
@@ -49,7 +49,7 @@ const TaskForm: React.FC = ({ onSubmit, isLoading = false }) => {
newErrors.endTime = 'End time must be after start time';
}
}
-
+
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
@@ -70,7 +70,7 @@ const TaskForm: React.FC = ({ onSubmit, isLoading = false }) => {
...formData,
[name]: value
});
-
+
// Clear error when user starts typing
if (errors[name]) {
setErrors(prev => {
@@ -83,7 +83,7 @@ const TaskForm: React.FC = ({ onSubmit, isLoading = false }) => {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
-
+
if (validateForm()) {
onSubmit(formData);
// Reset form
@@ -101,7 +101,7 @@ const TaskForm: React.FC = ({ onSubmit, isLoading = false }) => {
return (
-
-
+
);
};
diff --git a/src/components/TaskItem.tsx b/src/components/TaskItem.tsx
index a4e9ae9..e1bd53a 100644
--- a/src/components/TaskItem.tsx
+++ b/src/components/TaskItem.tsx
@@ -146,10 +146,7 @@ export default function TaskItem({ task, onToggleComplete, onDelete, onEdit, onT
aria-label="Delete task"
>
{isDeleting ? (
-
+
) : (