Mobile optimization pass for responsive layouts
- TabsList: Add responsive grid columns (grid-cols-2/3 on mobile) - Headers: Stack vertically on mobile with responsive text sizes - Dialogs: Use viewport-relative heights (70-80vh on mobile) - Grids: Add sm: breakpoints for single-column mobile layouts - Tables: Add overflow-x-auto for horizontal scrolling - Buttons: Full-width on mobile with flex-1 sm:flex-none - Select triggers: Full-width on mobile Files updated: 21 component and page files across admin, staff, dashboards, and hub sections.
This commit is contained in:
parent
88e364f4c5
commit
b640b0d2ad
21 changed files with 44 additions and 44 deletions
|
|
@ -196,7 +196,7 @@ export function ProfileEditor({
|
|||
|
||||
return (
|
||||
<Tabs defaultValue="basic" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-5">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-3 md:grid-cols-5">
|
||||
<TabsTrigger value="basic">Basic</TabsTrigger>
|
||||
<TabsTrigger value="social">Social</TabsTrigger>
|
||||
<TabsTrigger value="skills">Skills</TabsTrigger>
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ export default function AdminStaffAdmin() {
|
|||
</div>
|
||||
|
||||
<Tabs value={adminTab} onValueChange={setAdminTab} className="space-y-4">
|
||||
<TabsList className="grid w-full grid-cols-3 lg:grid-cols-6">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-3 lg:grid-cols-6">
|
||||
<TabsTrigger value="users" className="flex items-center gap-2">
|
||||
<Users className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Users</span>
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ export const AIChat: React.FC<AIChatProps> = ({
|
|||
animate={{ opacity: 1, y: 0, scale: 1 }}
|
||||
exit={{ opacity: 0, y: 20, scale: 0.95 }}
|
||||
transition={{ type: 'spring', damping: 25, stiffness: 300 }}
|
||||
className="fixed bottom-4 right-4 md:bottom-6 md:right-6 w-[calc(100vw-2rem)] md:w-[450px] h-[600px] max-h-[80vh] bg-background border border-border rounded-2xl shadow-2xl z-50 flex flex-col overflow-hidden"
|
||||
className="fixed bottom-4 right-4 md:bottom-6 md:right-6 w-[calc(100vw-2rem)] md:w-[450px] h-[70vh] sm:h-[600px] max-h-[80vh] bg-background border border-border rounded-2xl shadow-2xl z-50 flex flex-col overflow-hidden"
|
||||
>
|
||||
<div className={`flex items-center justify-between p-4 border-b border-border bg-gradient-to-r ${currentPersona.theme.gradient} bg-opacity-10`}>
|
||||
<PersonaSelector
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ export default function CommentsModal({
|
|||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:max-w-[500px] flex flex-col h-[600px]">
|
||||
<DialogContent className="sm:max-w-[500px] flex flex-col h-[80vh] sm:h-[600px] max-h-[600px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<MessageCircle className="h-5 w-5" />
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ export default function BotPanel() {
|
|||
</div>
|
||||
)}
|
||||
<Separator className="bg-gray-700" />
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<p className="text-sm text-gray-400">Commands</p>
|
||||
<p className="text-lg font-semibold text-white">
|
||||
|
|
@ -379,7 +379,7 @@ export default function BotPanel() {
|
|||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||
<div className="text-center p-4 bg-gray-700/30 rounded-lg">
|
||||
<p className="text-2xl font-bold text-white">{feedStats?.totalPosts || 0}</p>
|
||||
<p className="text-sm text-gray-400">Total Posts</p>
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ export default function Dashboard() {
|
|||
onValueChange={setActiveTab}
|
||||
className="w-full"
|
||||
>
|
||||
<TabsList className="grid w-full grid-cols-4 lg:grid-cols-4 bg-purple-950/30 border border-purple-500/20 p-1">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-4 bg-purple-950/30 border border-purple-500/20 p-1">
|
||||
<TabsTrigger value="realms" className="text-sm md:text-base">
|
||||
<span className="hidden sm:inline">Realms</span>
|
||||
<span className="sm:hidden">Arms</span>
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ export default function MaintenancePage() {
|
|||
|
||||
<div className="h-px bg-border" />
|
||||
|
||||
<div className="grid grid-cols-3 gap-4 text-center text-xs">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 text-center text-xs">
|
||||
<div className="space-y-1">
|
||||
<div className="text-muted-foreground">STATUS</div>
|
||||
<div className="text-blue-400 font-semibold flex items-center justify-center gap-1">
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export default function ProjectsAdmin() {
|
|||
value={draft.title}
|
||||
onChange={(e) => setDraft({ ...draft, title: e.target.value })}
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<select
|
||||
className="rounded border border-border/40 bg-background/70 px-3 py-2"
|
||||
value={draft.org_unit}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export default function StaffAdmin() {
|
|||
<Card className="bg-slate-900/50 border-purple-500/20">
|
||||
<CardContent className="pt-6">
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
||||
<TabsList className="grid w-full grid-cols-5 bg-slate-800/50">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-3 md:grid-cols-5 bg-slate-800/50">
|
||||
<TabsTrigger value="users" className="gap-2">
|
||||
<Users className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Users</span>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ export default function StaffChat() {
|
|||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 h-[600px]">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 gap-6 h-[calc(100vh-200px)] sm:h-[600px] min-h-[400px]">
|
||||
{/* Channels Sidebar */}
|
||||
<Card className="bg-slate-900/50 border-purple-500/20 lg:col-span-1">
|
||||
<CardHeader>
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ export default function StaffDashboard() {
|
|||
</CardHeader>
|
||||
<CardContent>
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
||||
<TabsList className="grid w-full grid-cols-4 bg-slate-800/50">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-4 bg-slate-800/50">
|
||||
<TabsTrigger value="overview" className="gap-2">
|
||||
<BarChart3 className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">Overview</span>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default function WixCaseStudies() {
|
|||
<CardDescription>{c.summary}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-3 gap-3 text-sm">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 text-sm">
|
||||
{c.metrics.map((m, i) => (
|
||||
<div
|
||||
key={i}
|
||||
|
|
|
|||
|
|
@ -132,18 +132,18 @@ export default function AdminAnalytics() {
|
|||
<div className="relative z-10">
|
||||
<div className="container mx-auto max-w-7xl px-4 py-16">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-8">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 rounded-lg bg-cyan-500/20 border border-cyan-500/30">
|
||||
<BarChart3 className="h-6 w-6 text-cyan-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-cyan-100">Analytics</h1>
|
||||
<p className="text-cyan-200/70">Platform insights and metrics</p>
|
||||
<h1 className="text-2xl sm:text-4xl font-bold text-cyan-100">Analytics</h1>
|
||||
<p className="text-cyan-200/70 text-sm sm:text-base">Platform insights and metrics</p>
|
||||
</div>
|
||||
</div>
|
||||
<Select value={period} onValueChange={setPeriod}>
|
||||
<SelectTrigger className="w-40 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectTrigger className="w-full sm:w-40 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectValue placeholder="Period" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
|
|||
|
|
@ -264,18 +264,18 @@ export default function AdminModeration() {
|
|||
<div className="relative z-10">
|
||||
<div className="container mx-auto max-w-7xl px-4 py-16">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 rounded-lg bg-red-500/20 border border-red-500/30">
|
||||
<Shield className="h-6 w-6 text-red-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-red-100">Moderation</h1>
|
||||
<p className="text-red-200/70">Content moderation and user management</p>
|
||||
<h1 className="text-2xl sm:text-4xl font-bold text-red-100">Moderation</h1>
|
||||
<p className="text-red-200/70 text-sm sm:text-base">Content moderation and user management</p>
|
||||
</div>
|
||||
</div>
|
||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||
<SelectTrigger className="w-40 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectTrigger className="w-full sm:w-40 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectValue placeholder="Status" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ export default function GameForgeDashboard() {
|
|||
className="w-full"
|
||||
>
|
||||
<TabsList
|
||||
className="grid w-full grid-cols-5 bg-green-950/30 border border-green-500/20 p-1"
|
||||
className="grid w-full grid-cols-2 sm:grid-cols-3 md:grid-cols-5 bg-green-950/30 border border-green-500/20 p-1"
|
||||
style={{ fontFamily: theme.fontFamily }}
|
||||
>
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ export default function LabsDashboard() {
|
|||
className="w-full"
|
||||
>
|
||||
<TabsList
|
||||
className="grid w-full grid-cols-4 bg-amber-950/30 border border-amber-500/20 p-1"
|
||||
className="grid w-full grid-cols-2 sm:grid-cols-4 bg-amber-950/30 border border-amber-500/20 p-1"
|
||||
style={{ fontFamily: "Monaco, Courier New, monospace" }}
|
||||
>
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ export default function NexusDashboard() {
|
|||
onValueChange={setActiveTab}
|
||||
className="w-full"
|
||||
>
|
||||
<TabsList className="grid w-full grid-cols-4 bg-purple-950/30 border border-purple-500/20 p-1">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-4 bg-purple-950/30 border border-purple-500/20 p-1">
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
<TabsTrigger value="applications">Applications</TabsTrigger>
|
||||
<TabsTrigger value="contracts">Contracts</TabsTrigger>
|
||||
|
|
@ -876,7 +876,7 @@ export default function NexusDashboard() {
|
|||
onValueChange={setActiveTab}
|
||||
className="w-full"
|
||||
>
|
||||
<TabsList className="grid w-full grid-cols-4 bg-blue-950/30 border border-blue-500/20 p-1">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-4 bg-blue-950/30 border border-blue-500/20 p-1">
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
<TabsTrigger value="opportunities">Opportunities</TabsTrigger>
|
||||
<TabsTrigger value="applicants">Applicants</TabsTrigger>
|
||||
|
|
|
|||
|
|
@ -284,8 +284,8 @@ export default function ClientInvoices() {
|
|||
{selectedInvoice.line_items?.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-lg font-semibold text-white">Line Items</h3>
|
||||
<div className="bg-black/30 rounded-lg border border-cyan-500/20 overflow-hidden">
|
||||
<table className="w-full">
|
||||
<div className="bg-black/30 rounded-lg border border-cyan-500/20 overflow-x-auto">
|
||||
<table className="w-full min-w-[500px]">
|
||||
<thead className="bg-cyan-500/10">
|
||||
<tr className="text-left text-xs text-gray-400 uppercase">
|
||||
<th className="p-4">Description</th>
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export default function MyApplications() {
|
|||
}
|
||||
className="mb-8"
|
||||
>
|
||||
<TabsList className="grid w-full grid-cols-5 bg-slate-800/50 border-slate-700">
|
||||
<TabsList className="grid w-full grid-cols-2 sm:grid-cols-3 md:grid-cols-5 bg-slate-800/50 border-slate-700">
|
||||
<TabsTrigger value="all">
|
||||
All ({applications.length})
|
||||
</TabsTrigger>
|
||||
|
|
|
|||
|
|
@ -266,18 +266,18 @@ export default function StaffOKRs() {
|
|||
<div className="relative z-10">
|
||||
<div className="container mx-auto max-w-6xl px-4 py-16">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 rounded-lg bg-emerald-500/20 border border-emerald-500/30">
|
||||
<Target className="h-6 w-6 text-emerald-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-emerald-100">OKRs</h1>
|
||||
<p className="text-emerald-200/70">Objectives and Key Results</p>
|
||||
<h1 className="text-2xl sm:text-4xl font-bold text-emerald-100">OKRs</h1>
|
||||
<p className="text-emerald-200/70 text-sm sm:text-base">Objectives and Key Results</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
className="bg-emerald-600 hover:bg-emerald-700"
|
||||
className="bg-emerald-600 hover:bg-emerald-700 w-full sm:w-auto"
|
||||
onClick={() => setCreateOkrDialog(true)}
|
||||
>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
|
|
@ -334,9 +334,9 @@ export default function StaffOKRs() {
|
|||
</div>
|
||||
|
||||
{/* Filters */}
|
||||
<div className="flex gap-4 mb-8">
|
||||
<div className="flex flex-wrap gap-4 mb-8">
|
||||
<Select value={selectedQuarter} onValueChange={setSelectedQuarter}>
|
||||
<SelectTrigger className="w-32 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectTrigger className="w-full sm:w-32 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectValue placeholder="Quarter" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
@ -348,7 +348,7 @@ export default function StaffOKRs() {
|
|||
</SelectContent>
|
||||
</Select>
|
||||
<Select value={selectedYear} onValueChange={setSelectedYear}>
|
||||
<SelectTrigger className="w-32 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectTrigger className="w-full sm:w-32 bg-slate-800 border-slate-700 text-slate-100">
|
||||
<SelectValue placeholder="Year" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
@ -510,7 +510,7 @@ export default function StaffOKRs() {
|
|||
onChange={(e) => setNewOkr({ ...newOkr, description: e.target.value })}
|
||||
className="bg-slate-700 border-slate-600 text-slate-100"
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<Select
|
||||
value={newOkr.quarter.toString()}
|
||||
onValueChange={(v) => setNewOkr({ ...newOkr, quarter: parseInt(v) })}
|
||||
|
|
@ -570,7 +570,7 @@ export default function StaffOKRs() {
|
|||
onChange={(e) => setNewKr({ ...newKr, description: e.target.value })}
|
||||
className="bg-slate-700 border-slate-600 text-slate-100"
|
||||
/>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label className="text-sm text-slate-400 mb-1 block">Target Value</label>
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -276,20 +276,20 @@ export default function StaffTimeTracking() {
|
|||
<div className="relative z-10">
|
||||
<div className="container mx-auto max-w-6xl px-4 py-16">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="p-3 rounded-lg bg-blue-500/20 border border-blue-500/30">
|
||||
<Clock className="h-6 w-6 text-blue-400" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold text-blue-100">Time Tracking</h1>
|
||||
<p className="text-blue-200/70">Track your work hours and projects</p>
|
||||
<h1 className="text-2xl sm:text-4xl font-bold text-blue-100">Time Tracking</h1>
|
||||
<p className="text-blue-200/70 text-sm sm:text-base">Track your work hours and projects</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{activeTimer ? (
|
||||
<Button
|
||||
className="bg-red-600 hover:bg-red-700"
|
||||
className="bg-red-600 hover:bg-red-700 flex-1 sm:flex-none"
|
||||
onClick={stopTimer}
|
||||
>
|
||||
<Square className="h-4 w-4 mr-2" />
|
||||
|
|
@ -297,7 +297,7 @@ export default function StaffTimeTracking() {
|
|||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
className="bg-green-600 hover:bg-green-700"
|
||||
className="bg-green-600 hover:bg-green-700 flex-1 sm:flex-none"
|
||||
onClick={startTimer}
|
||||
>
|
||||
<Play className="h-4 w-4 mr-2" />
|
||||
|
|
@ -305,7 +305,7 @@ export default function StaffTimeTracking() {
|
|||
</Button>
|
||||
)}
|
||||
<Button
|
||||
className="bg-blue-600 hover:bg-blue-700"
|
||||
className="bg-blue-600 hover:bg-blue-700 flex-1 sm:flex-none"
|
||||
onClick={() => setCreateDialog(true)}
|
||||
>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue