mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 23:51:13 -05:00
Refactor: Implement desktop layout modernization
This commit is contained in:
@@ -244,7 +244,7 @@ export function AccountProfileTab() {
|
||||
const isDeactivated = profile?.deactivated || false;
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-6">
|
||||
{/* Deletion Status Banner */}
|
||||
{deletionRequest && (
|
||||
<DeletionStatusBanner
|
||||
@@ -253,9 +253,15 @@ export function AccountProfileTab() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Profile Picture + Account Info Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Profile Picture */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium">Profile Picture</h3>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Profile Picture</CardTitle>
|
||||
<CardDescription>Upload your profile picture</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<PhotoUpload
|
||||
variant="avatar"
|
||||
maxFiles={1}
|
||||
@@ -267,11 +273,72 @@ export function AccountProfileTab() {
|
||||
handleError(new Error(error), { action: 'Upload avatar' });
|
||||
}}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Account Information */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Account Information</CardTitle>
|
||||
<CardDescription>View your account details</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{pendingEmail && (
|
||||
<EmailChangeStatus
|
||||
currentEmail={user?.email || ''}
|
||||
pendingEmail={pendingEmail}
|
||||
onCancel={() => setShowCancelEmailDialog(true)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="p-4 bg-muted/50 rounded-lg space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium">Email Address</p>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<p className="text-sm text-muted-foreground">{user?.email}</p>
|
||||
{pendingEmail ? (
|
||||
<Badge variant="secondary" className="bg-blue-500/10 text-blue-500 border-blue-500/20 text-xs">
|
||||
Change Pending
|
||||
</Badge>
|
||||
) : user?.email_confirmed_at ? (
|
||||
<Badge variant="secondary" className="text-xs">Verified</Badge>
|
||||
) : (
|
||||
<Badge variant="outline" className="text-xs">Pending Verification</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setShowEmailDialog(true)}
|
||||
disabled={!!pendingEmail}
|
||||
>
|
||||
<Mail className="w-4 h-4 mr-2" />
|
||||
Change
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium">Account Created</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{profile?.created_at ? new Date(profile.created_at).toLocaleDateString() : 'N/A'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Profile Information */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Profile Information</CardTitle>
|
||||
<CardDescription>Update your public profile details</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
<h3 className="text-lg font-medium">Profile Information</h3>
|
||||
|
||||
@@ -419,60 +486,31 @@ export function AccountProfileTab() {
|
||||
</p>
|
||||
)}
|
||||
</form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Account Information */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-medium">Account Information</h3>
|
||||
<div className="space-y-4">
|
||||
{pendingEmail && (
|
||||
<EmailChangeStatus
|
||||
currentEmail={user?.email || ''}
|
||||
pendingEmail={pendingEmail}
|
||||
onCancel={() => setShowCancelEmailDialog(true)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="p-4 bg-muted/50 rounded-lg space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium">Email Address</p>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<p className="text-sm text-muted-foreground">{user?.email}</p>
|
||||
{pendingEmail ? (
|
||||
<Badge variant="secondary" className="bg-blue-500/10 text-blue-500 border-blue-500/20 text-xs">
|
||||
Change Pending
|
||||
</Badge>
|
||||
) : user?.email_confirmed_at ? (
|
||||
<Badge variant="secondary" className="text-xs">Verified</Badge>
|
||||
) : (
|
||||
<Badge variant="outline" className="text-xs">Pending Verification</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* Danger Zone */}
|
||||
<Card className="border-destructive/50">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-destructive">Danger Zone</CardTitle>
|
||||
<CardDescription>Irreversible account actions</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => setShowEmailDialog(true)}
|
||||
disabled={!!pendingEmail}
|
||||
variant="destructive"
|
||||
onClick={() => setShowDeletionDialog(true)}
|
||||
disabled={!!deletionRequest}
|
||||
>
|
||||
<Mail className="w-4 h-4 mr-2" />
|
||||
Change Email
|
||||
<Trash2 className="w-4 h-4 mr-2" />
|
||||
Delete Account
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div>
|
||||
<p className="text-sm font-medium">Account Created</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{profile?.created_at ? new Date(profile.created_at).toLocaleDateString() : 'N/A'}
|
||||
{deletionRequest && (
|
||||
<p className="text-sm text-muted-foreground mt-2">
|
||||
Account deletion already in progress
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Email Change Dialog */}
|
||||
{user && (
|
||||
@@ -486,29 +524,6 @@ export function AccountProfileTab() {
|
||||
|
||||
{/* Cancel Email Change Dialog */}
|
||||
<AlertDialog open={showCancelEmailDialog} onOpenChange={setShowCancelEmailDialog}>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Cancel Email Change?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will cancel your pending email change to <strong>{pendingEmail}</strong>.
|
||||
Your email will remain as <strong>{user?.email}</strong>.
|
||||
You can start a new email change request at any time.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={cancellingEmail}>Keep Change</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={handleCancelEmailChange}
|
||||
disabled={cancellingEmail}
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
>
|
||||
{cancellingEmail ? 'Cancelling...' : 'Yes, Cancel Change'}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Danger Zone */}
|
||||
<Card className="border-destructive">
|
||||
@@ -538,6 +553,28 @@ export function AccountProfileTab() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Cancel Email Change?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This will cancel your pending email change to <strong>{pendingEmail}</strong>.
|
||||
Your email will remain as <strong>{user?.email}</strong>.
|
||||
You can start a new email change request at any time.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel disabled={cancellingEmail}>Keep Change</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={handleCancelEmailChange}
|
||||
disabled={cancellingEmail}
|
||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||
>
|
||||
{cancellingEmail ? 'Cancelling...' : 'Yes, Cancel Change'}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
{/* Account Deletion Dialog */}
|
||||
<AccountDeletionDialog
|
||||
open={showDeletionDialog}
|
||||
|
||||
@@ -281,16 +281,16 @@ export function DataExportTab() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-6">
|
||||
{/* Statistics + Recent Activity Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Personal Statistics */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<BarChart3 className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Personal Statistics</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<BarChart3 className="w-5 h-5" />
|
||||
<CardTitle>Personal Statistics</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Your activity and contribution statistics on ThrillWiki
|
||||
</CardDescription>
|
||||
@@ -334,20 +334,136 @@ export function DataExportTab() {
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Export Your Data */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Download className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Export Your Data</h3>
|
||||
</div>
|
||||
|
||||
{/* Account Activity */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Download Your Data</CardTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<Activity className="w-5 h-5" />
|
||||
<CardTitle>Account Activity</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Recent account activity and changes
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-6">
|
||||
{rateLimited && nextAvailableAt && (
|
||||
<div className="flex items-start gap-3 p-4 border border-yellow-500/20 bg-yellow-500/10 rounded-lg">
|
||||
<Clock className="w-5 h-5 text-yellow-500 mt-0.5" />
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">Rate Limited</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
You can export your data once per hour. Next export available at{' '}
|
||||
{formatDate(nextAvailableAt)}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Choose what to include in your export:
|
||||
</p>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="include_reviews">Include Reviews</Label>
|
||||
<Switch
|
||||
id="include_reviews"
|
||||
checked={exportOptions.include_reviews}
|
||||
onCheckedChange={(checked) =>
|
||||
setExportOptions({ ...exportOptions, include_reviews: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="include_lists">Include Lists</Label>
|
||||
<Switch
|
||||
id="include_lists"
|
||||
checked={exportOptions.include_lists}
|
||||
onCheckedChange={(checked) =>
|
||||
setExportOptions({ ...exportOptions, include_lists: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="include_activity_log">Include Activity Log</Label>
|
||||
<Switch
|
||||
id="include_activity_log"
|
||||
checked={exportOptions.include_activity_log}
|
||||
onCheckedChange={(checked) =>
|
||||
setExportOptions({ ...exportOptions, include_activity_log: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="include_preferences">Include Preferences</Label>
|
||||
<Switch
|
||||
id="include_preferences"
|
||||
checked={exportOptions.include_preferences}
|
||||
onCheckedChange={(checked) =>
|
||||
setExportOptions({ ...exportOptions, include_preferences: checked })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3 p-4 border rounded-lg">
|
||||
<AlertCircle className="w-5 h-5 text-blue-500 mt-0.5" />
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium">GDPR Compliance</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
This export includes all personal data we store about you. You can use this for backup purposes or to migrate to another service.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleDataExport}
|
||||
disabled={exporting || rateLimited}
|
||||
className="w-full"
|
||||
>
|
||||
<Download className="w-4 h-4 mr-2" />
|
||||
{exporting ? 'Exporting Data...' : 'Export My Data'}
|
||||
</Button>
|
||||
</CardContent>
|
||||
<CardContent>
|
||||
{recentActivity.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground text-center py-4">
|
||||
No recent activity to display
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{recentActivity.map((activity) => (
|
||||
<div key={activity.id} className="flex items-start gap-3 pb-4 border-b last:border-0 last:pb-0">
|
||||
<Activity className="w-4 h-4 text-muted-foreground mt-1" />
|
||||
<div className="flex-1 space-y-1">
|
||||
<p className="text-sm font-medium">
|
||||
{formatActionName(activity.action)}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatDate(activity.created_at)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Export Your Data - Full Width */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Download className="w-5 h-5" />
|
||||
<CardTitle>Export Your Data</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Export all your ThrillWiki data in JSON format. This includes your profile, reviews, lists, and activity history.
|
||||
</CardDescription>
|
||||
@@ -439,47 +555,5 @@ export function DataExportTab() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Account Activity */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Activity className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Account Activity</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardDescription>
|
||||
Recent account activity and changes
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{recentActivity.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground text-center py-4">
|
||||
No recent activity to display
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{recentActivity.map((activity) => (
|
||||
<div key={activity.id} className="flex items-start gap-3 pb-4 border-b last:border-0 last:pb-0">
|
||||
<Activity className="w-4 h-4 text-muted-foreground mt-1" />
|
||||
<div className="flex-1 space-y-1">
|
||||
<p className="text-sm font-medium">
|
||||
{formatActionName(activity.action)}
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatDate(activity.created_at)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Card, CardContent, CardDescription, CardHeader } from '@/components/ui/card';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
@@ -304,16 +304,17 @@ export function LocationTab() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Location Settings</h3>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
{/* Location Settings + Personal Information Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Location Settings */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin className="w-5 h-5" />
|
||||
<CardTitle>Location Settings</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Set your location for better personalized content and timezone display.
|
||||
</CardDescription>
|
||||
@@ -425,18 +426,14 @@ export function LocationTab() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Personal Information</h3>
|
||||
</div>
|
||||
|
||||
{/* Personal Information */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-5 h-5" />
|
||||
<CardTitle>Personal Information</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Optional personal information that can be displayed on your profile.
|
||||
</CardDescription>
|
||||
@@ -462,16 +459,15 @@ export function LocationTab() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Ruler className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Units & Measurements</h3>
|
||||
</div>
|
||||
|
||||
{/* Unit Preferences + Accessibility Options Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Unit Preferences */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Ruler className="w-5 h-5" />
|
||||
<CardTitle>Units & Measurements</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Choose your preferred measurement system for displaying distances, speeds, and other measurements.
|
||||
</CardDescription>
|
||||
@@ -499,18 +495,14 @@ export function LocationTab() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Accessibility className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Accessibility Options</h3>
|
||||
</div>
|
||||
|
||||
{/* Accessibility Options */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Accessibility className="w-5 h-5" />
|
||||
<CardTitle>Accessibility Options</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Customize the interface to meet your accessibility needs.
|
||||
</CardDescription>
|
||||
@@ -564,6 +556,7 @@ export function LocationTab() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Save Button */}
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit" disabled={saving}>
|
||||
{saving ? 'Saving...' : 'Save Settings'}
|
||||
|
||||
@@ -239,6 +239,9 @@ export function NotificationsTab() {
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* Notification Channels + Frequency Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Notification Channels */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Notification Channels</CardTitle>
|
||||
@@ -301,6 +304,7 @@ export function NotificationsTab() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Notification Frequency */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Notification Frequency</CardTitle>
|
||||
@@ -359,7 +363,9 @@ export function NotificationsTab() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Workflow Preferences - Full Width */}
|
||||
{Object.keys(groupedTemplates).map((category) => (
|
||||
<Card key={category}>
|
||||
<CardHeader>
|
||||
|
||||
@@ -234,17 +234,17 @@ export function PrivacyTab() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<div className="space-y-6">
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
||||
{/* Profile Visibility + Activity & Content Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Profile Visibility */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Profile Visibility</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye className="w-5 h-5" />
|
||||
<CardTitle>Profile Visibility</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Control who can see your profile and personal information.
|
||||
</CardDescription>
|
||||
@@ -363,19 +363,14 @@ export function PrivacyTab() {
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Activity & Content */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Shield className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Activity & Content</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Shield className="w-5 h-5" />
|
||||
<CardTitle>Activity & Content</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Control the visibility of your activities and content.
|
||||
</CardDescription>
|
||||
@@ -407,17 +402,13 @@ export function PrivacyTab() {
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Search & Discovery */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Search className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Search & Discovery</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<Search className="w-5 h-5" />
|
||||
<CardTitle>Search & Discovery</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Control how others can find and discover your profile.
|
||||
</CardDescription>
|
||||
@@ -437,19 +428,14 @@ export function PrivacyTab() {
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Blocked Users */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<UserX className="w-5 h-5" />
|
||||
<h3 className="text-lg font-medium">Blocked Users</h3>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center gap-2">
|
||||
<UserX className="w-5 h-5" />
|
||||
<CardTitle>Blocked Users</CardTitle>
|
||||
</div>
|
||||
<CardDescription>
|
||||
Manage users you have blocked from interacting with you.
|
||||
</CardDescription>
|
||||
@@ -458,7 +444,6 @@ export function PrivacyTab() {
|
||||
<BlockedUsers />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Save Button */}
|
||||
<div className="flex justify-end">
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function UserSettings() {
|
||||
<div className="min-h-screen bg-background">
|
||||
<Header />
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<Settings className="w-8 h-8 text-primary" />
|
||||
@@ -118,19 +118,9 @@ export default function UserSettings() {
|
||||
<TabsContent
|
||||
key={tab.id}
|
||||
value={tab.id}
|
||||
className="space-y-6 focus-visible:outline-none"
|
||||
className="focus-visible:outline-none"
|
||||
>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2">
|
||||
<tab.icon className="w-5 h-5" />
|
||||
{tab.label}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Component />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user