Refactor: Add button feedback

This commit is contained in:
gpt-engineer-app[bot]
2025-11-04 18:48:39 +00:00
parent b07004ed03
commit ded4dfd59c
7 changed files with 90 additions and 52 deletions

View File

@@ -166,8 +166,15 @@ export default function AdminSettings() {
setLocalValue(updated);
};
const saveBanDurations = () => {
updateSetting(setting.setting_key, banDurations);
const [savingBanDurations, setSavingBanDurations] = useState(false);
const saveBanDurations = async () => {
setSavingBanDurations(true);
try {
await updateSetting(setting.setting_key, banDurations);
} finally {
setSavingBanDurations(false);
}
};
return (
@@ -239,7 +246,13 @@ export default function AdminSettings() {
</div>
</div>
<Button onClick={saveBanDurations} disabled={isUpdating} className="w-full">
<Button
onClick={saveBanDurations}
loading={savingBanDurations}
loadingText="Saving..."
className="w-full"
trackingLabel="save-ban-duration-settings"
>
<Save className="w-4 h-4 mr-2" />
Save Ban Duration Settings
</Button>
@@ -431,7 +444,13 @@ export default function AdminSettings() {
className="w-24"
min="0"
/>
<Button onClick={handleSubmit} disabled={isUpdating} size="sm">
<Button
onClick={handleSubmit}
loading={isUpdating}
loadingText=""
size="sm"
trackingLabel="save-threshold-setting"
>
<Save className="w-4 h-4" />
</Button>
</div>
@@ -458,7 +477,13 @@ export default function AdminSettings() {
}}
className="flex-1"
/>
<Button onClick={handleSubmit} disabled={isUpdating} size="sm">
<Button
onClick={handleSubmit}
loading={isUpdating}
loadingText=""
size="sm"
trackingLabel="save-setting"
>
<Save className="w-4 h-4" />
</Button>
</div>

View File

@@ -275,15 +275,14 @@ export default function AuthCallback() {
required
/>
</div>
<Button type="submit" className="w-full" disabled={settingPassword}>
{settingPassword ? (
<>
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
Setting Password...
</>
) : (
'Set Password'
)}
<Button
type="submit"
className="w-full"
loading={settingPassword}
loadingText="Setting Password..."
trackingLabel="set-password-recovery"
>
Set Password
</Button>
</form>
</CardContent>

View File

@@ -525,6 +525,8 @@ export default function Profile() {
setFormErrors({});
return true;
};
const [isSaving, setIsSaving] = useState(false);
const handleSaveProfile = async () => {
if (!profile || !currentUser) return;
if (!validateForm()) return;
@@ -533,6 +535,8 @@ export default function Profile() {
setShowUsernameDialog(true);
return;
}
setIsSaving(true);
try {
const updateData: any = {
display_name: editForm.display_name,
@@ -572,6 +576,8 @@ export default function Profile() {
title: "Error updating profile",
description: getErrorMessage(error)
});
} finally {
setIsSaving(false);
}
};
const confirmUsernameChange = () => {
@@ -730,7 +736,14 @@ export default function Profile() {
</div>
<div className="flex gap-2">
<Button onClick={handleSaveProfile} size="sm" disabled={usernameValidation.isChecking || editForm.username !== profile?.username && !usernameValidation.isValid}>
<Button
onClick={handleSaveProfile}
size="sm"
loading={isSaving}
loadingText="Saving..."
disabled={usernameValidation.isChecking || editForm.username !== profile?.username && !usernameValidation.isValid}
trackingLabel="save-profile-changes"
>
<Save className="w-4 h-4 mr-2" />
Save Changes
</Button>

View File

@@ -83,7 +83,12 @@ export default function ErrorLookup() {
onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
className="font-mono"
/>
<Button onClick={handleSearch} disabled={loading}>
<Button
onClick={handleSearch}
loading={loading}
loadingText="Searching..."
trackingLabel="error-lookup-search"
>
<Search className="w-4 h-4 mr-2" />
Search
</Button>

View File

@@ -5,9 +5,9 @@ import { AdminLayout } from '@/components/layout/AdminLayout';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { AlertCircle, RefreshCw } from 'lucide-react';
import { AlertCircle } from 'lucide-react';
import { RefreshButton } from '@/components/ui/refresh-button';
import { ErrorDetailsModal } from '@/components/admin/ErrorDetailsModal';
import { ErrorAnalytics } from '@/components/admin/ErrorAnalytics';
import { format } from 'date-fns';
@@ -33,7 +33,7 @@ export default function ErrorMonitoring() {
const [dateRange, setDateRange] = useState<'1h' | '24h' | '7d' | '30d'>('24h');
// Fetch recent errors
const { data: errors, isLoading, refetch } = useQuery({
const { data: errors, isLoading, refetch, isFetching } = useQuery({
queryKey: ['admin-errors', dateRange, errorTypeFilter, searchTerm],
queryFn: async () => {
let query = supabase
@@ -88,10 +88,12 @@ export default function ErrorMonitoring() {
<h1 className="text-3xl font-bold tracking-tight">Error Monitoring</h1>
<p className="text-muted-foreground">Track and analyze application errors</p>
</div>
<Button onClick={() => refetch()} variant="outline" size="sm">
<RefreshCw className="w-4 h-4 mr-2" />
Refresh
</Button>
<RefreshButton
onRefresh={async () => { await refetch(); }}
isLoading={isFetching}
variant="outline"
size="sm"
/>
</div>
{/* Analytics Section */}