Improve app responsiveness and visual consistency across devices
Adjusted layout, spacing, and element sizing in CalendarView, KanbanBoard, and ProjectTemplate components to enhance responsiveness and user experience on various screen sizes. Replit-Commit-Author: Agent Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518 Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/gFHkSPu
This commit is contained in:
+1
-1
@@ -316,7 +316,7 @@ function App() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<main className="pb-20 px-4 py-6">
|
<main className="pb-20 px-3 py-4 sm:px-4 sm:py-6 max-w-screen-2xl mx-auto">
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSel
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="sticky top-16 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b pb-3 mb-4">
|
<div className="sticky top-16 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b pb-2 sm:pb-3 mb-3 sm:mb-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Calendar className="w-5 h-5 text-primary" />
|
<Calendar className="w-4 h-4 sm:w-5 sm:h-5 text-primary" />
|
||||||
<h2 className="text-lg font-semibold" data-testid="text-calendar-title">
|
<h2 className="text-base sm:text-lg font-semibold" data-testid="text-calendar-title">
|
||||||
5-Week Calendar View
|
Calendar
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSel
|
|||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => navigateWeek('prev')}
|
onClick={() => navigateWeek('prev')}
|
||||||
data-testid="button-prev-week"
|
data-testid="button-prev-week"
|
||||||
className="w-8 h-8"
|
className="h-11 w-11"
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4" />
|
<ChevronLeft className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -91,7 +91,7 @@ export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSel
|
|||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => navigateWeek('next')}
|
onClick={() => navigateWeek('next')}
|
||||||
data-testid="button-next-week"
|
data-testid="button-next-week"
|
||||||
className="w-8 h-8"
|
className="h-11 w-11"
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-4 h-4" />
|
<ChevronRight className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -100,7 +100,7 @@ export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSel
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Calendar Grid */}
|
{/* Calendar Grid */}
|
||||||
<div className="grid grid-cols-7 gap-2">
|
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-5 lg:grid-cols-7 gap-2 sm:gap-3">
|
||||||
{dates.map((date, index) => {
|
{dates.map((date, index) => {
|
||||||
const dayTasks = getTasksForDate(date);
|
const dayTasks = getTasksForDate(date);
|
||||||
const isToday = isSameDay(date, new Date());
|
const isToday = isSameDay(date, new Date());
|
||||||
@@ -110,7 +110,7 @@ export default function CalendarView({ tasks, onTaskDrop, onTaskClick, onDateSel
|
|||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={index}
|
key={index}
|
||||||
className={`p-3 min-h-[120px] hover-elevate active-elevate-2 transition-all ${
|
className={`p-2 sm:p-3 min-h-[100px] sm:min-h-[120px] hover-elevate active-elevate-2 transition-all ${
|
||||||
isToday ? 'ring-2 ring-primary' : ''
|
isToday ? 'ring-2 ring-primary' : ''
|
||||||
} ${
|
} ${
|
||||||
isWeekend ? 'bg-muted/30' : ''
|
isWeekend ? 'bg-muted/30' : ''
|
||||||
|
|||||||
@@ -169,12 +169,12 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="sticky top-16 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b pb-3 mb-4">
|
<div className="sticky top-16 z-40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b pb-2 sm:pb-3 mb-3 sm:mb-4">
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-3 sm:mb-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<LayoutGrid className="w-5 h-5 text-primary" />
|
<LayoutGrid className="w-4 h-4 sm:w-5 sm:h-5 text-primary" />
|
||||||
<h2 className="text-lg font-semibold" data-testid="text-kanban-title">
|
<h2 className="text-base sm:text-lg font-semibold" data-testid="text-kanban-title">
|
||||||
Task Board
|
Board
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => navigatePeriod('prev')}
|
onClick={() => navigatePeriod('prev')}
|
||||||
data-testid="button-prev-period"
|
data-testid="button-prev-period"
|
||||||
className="w-8 h-8"
|
className="h-11 w-11"
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4" />
|
<ChevronLeft className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -199,7 +199,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
size="icon"
|
size="icon"
|
||||||
onClick={() => navigatePeriod('next')}
|
onClick={() => navigatePeriod('next')}
|
||||||
data-testid="button-next-period"
|
data-testid="button-next-period"
|
||||||
className="w-8 h-8"
|
className="h-11 w-11"
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-4 h-4" />
|
<ChevronRight className="w-4 h-4" />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -208,8 +208,8 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Filter Bar */}
|
{/* Filter Bar */}
|
||||||
<Card className="p-4">
|
<Card className="p-3 sm:p-4">
|
||||||
<div className="flex items-center justify-between flex-wrap gap-4">
|
<div className="flex items-center justify-between flex-wrap gap-3 sm:gap-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Filter className="w-4 h-4 text-muted-foreground" />
|
<Filter className="w-4 h-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">Filters</span>
|
<span className="text-sm font-medium">Filters</span>
|
||||||
@@ -416,14 +416,14 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
|
|
||||||
{/* All view modes use the same kanban layout, just with different filtering */}
|
{/* All view modes use the same kanban layout, just with different filtering */}
|
||||||
<TabsContent value="traditional" className="mt-4">
|
<TabsContent value="traditional" className="mt-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 sm:gap-4">
|
||||||
{columns.map((column) => {
|
{columns.map((column) => {
|
||||||
const columnTasks = getTasksForColumn(column.status);
|
const columnTasks = getTasksForColumn(column.status);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={column.id}
|
key={column.id}
|
||||||
className="p-4"
|
className="p-3 sm:p-4"
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDrop={() => handleDrop(column.status)}
|
onDrop={() => handleDrop(column.status)}
|
||||||
data-testid={`column-${column.id}`}
|
data-testid={`column-${column.id}`}
|
||||||
@@ -437,7 +437,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3 min-h-[200px]">
|
<div className="space-y-2 sm:space-y-3 min-h-[150px] sm:min-h-[200px]">
|
||||||
{columnTasks.map((task) => (
|
{columnTasks.map((task) => (
|
||||||
<div
|
<div
|
||||||
key={task.id}
|
key={task.id}
|
||||||
@@ -480,14 +480,14 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="weekly" className="mt-4">
|
<TabsContent value="weekly" className="mt-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 sm:gap-4">
|
||||||
{columns.map((column) => {
|
{columns.map((column) => {
|
||||||
const columnTasks = getTasksForColumn(column.status);
|
const columnTasks = getTasksForColumn(column.status);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={column.id}
|
key={column.id}
|
||||||
className="p-4"
|
className="p-3 sm:p-4"
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDrop={() => handleDrop(column.status)}
|
onDrop={() => handleDrop(column.status)}
|
||||||
data-testid={`column-${column.id}`}
|
data-testid={`column-${column.id}`}
|
||||||
@@ -501,7 +501,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3 min-h-[200px]">
|
<div className="space-y-2 sm:space-y-3 min-h-[150px] sm:min-h-[200px]">
|
||||||
{columnTasks.map((task) => (
|
{columnTasks.map((task) => (
|
||||||
<div
|
<div
|
||||||
key={task.id}
|
key={task.id}
|
||||||
@@ -544,14 +544,14 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="monthly" className="mt-4">
|
<TabsContent value="monthly" className="mt-4">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-3 sm:gap-4">
|
||||||
{columns.map((column) => {
|
{columns.map((column) => {
|
||||||
const columnTasks = getTasksForColumn(column.status);
|
const columnTasks = getTasksForColumn(column.status);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={column.id}
|
key={column.id}
|
||||||
className="p-4"
|
className="p-3 sm:p-4"
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDrop={() => handleDrop(column.status)}
|
onDrop={() => handleDrop(column.status)}
|
||||||
data-testid={`column-${column.id}`}
|
data-testid={`column-${column.id}`}
|
||||||
@@ -565,7 +565,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3 min-h-[200px]">
|
<div className="space-y-2 sm:space-y-3 min-h-[150px] sm:min-h-[200px]">
|
||||||
{columnTasks.map((task) => (
|
{columnTasks.map((task) => (
|
||||||
<div
|
<div
|
||||||
key={task.id}
|
key={task.id}
|
||||||
|
|||||||
@@ -522,40 +522,42 @@ export default function ProjectTemplate({
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<h2 className="text-lg font-semibold" data-testid="text-settings-title">
|
<h2 className="text-base sm:text-lg font-semibold" data-testid="text-settings-title">
|
||||||
Settings & Project Management
|
Settings
|
||||||
</h2>
|
</h2>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setIsCreateProjectOpen(true)}
|
onClick={() => setIsCreateProjectOpen(true)}
|
||||||
data-testid="button-create-project"
|
data-testid="button-create-project"
|
||||||
|
size="lg"
|
||||||
|
className="h-11"
|
||||||
>
|
>
|
||||||
<Plus className="w-4 h-4 mr-2" />
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
New Project
|
New Project
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Tabs defaultValue="projects" className="space-y-4">
|
<Tabs defaultValue="projects" className="space-y-3 sm:space-y-4">
|
||||||
<TabsList>
|
<TabsList className="w-full">
|
||||||
<TabsTrigger value="projects" data-testid="tab-projects">Projects</TabsTrigger>
|
<TabsTrigger value="projects" data-testid="tab-projects" className="flex-1">Projects</TabsTrigger>
|
||||||
<TabsTrigger value="labels" data-testid="tab-labels">Labels</TabsTrigger>
|
<TabsTrigger value="labels" data-testid="tab-labels" className="flex-1">Labels</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
|
|
||||||
<TabsContent value="projects" className="space-y-6">
|
<TabsContent value="projects" className="space-y-4 sm:space-y-6">
|
||||||
{/* Project Kanban Board */}
|
{/* Project Kanban Board */}
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-3 sm:gap-4 lg:gap-6">
|
||||||
{projectColumns.map((column) => {
|
{projectColumns.map((column) => {
|
||||||
const columnProjects = getProjectsByStatus(column.status);
|
const columnProjects = getProjectsByStatus(column.status);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
key={column.id}
|
key={column.id}
|
||||||
className="p-4"
|
className="p-3 sm:p-4"
|
||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDrop={() => handleDrop(column.status)}
|
onDrop={() => handleDrop(column.status)}
|
||||||
data-testid={`column-${column.id}`}
|
data-testid={`column-${column.id}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-3 sm:mb-4">
|
||||||
<h3 className="font-semibold text-sm" data-testid={`text-column-title-${column.id}`}>
|
<h3 className="font-semibold text-sm" data-testid={`text-column-title-${column.id}`}>
|
||||||
{column.title}
|
{column.title}
|
||||||
</h3>
|
</h3>
|
||||||
@@ -564,14 +566,14 @@ export default function ProjectTemplate({
|
|||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3 min-h-[400px]">
|
<div className="space-y-2 sm:space-y-3 min-h-[200px] sm:min-h-[300px]">
|
||||||
{columnProjects.map((project) => (
|
{columnProjects.map((project) => (
|
||||||
<Card
|
<Card
|
||||||
key={project.id}
|
key={project.id}
|
||||||
draggable
|
draggable
|
||||||
onDragStart={() => handleDragStart(project.id)}
|
onDragStart={() => handleDragStart(project.id)}
|
||||||
onDragEnd={handleDragEnd}
|
onDragEnd={handleDragEnd}
|
||||||
className={`p-4 cursor-move hover-elevate transition-all ${
|
className={`p-3 sm:p-4 cursor-move hover-elevate transition-all ${
|
||||||
draggedProject === project.id ? 'opacity-50 scale-95' : ''
|
draggedProject === project.id ? 'opacity-50 scale-95' : ''
|
||||||
}`}
|
}`}
|
||||||
data-testid={`project-card-${project.id}`}
|
data-testid={`project-card-${project.id}`}
|
||||||
|
|||||||
Reference in New Issue
Block a user