Make Project Hub responsive for mobile devices
- Header: Smaller text on mobile, hide stats on small screens - Layout: Stack sidebar above content on mobile, side-by-side on desktop - Kanban: 1 column on mobile, 2 on tablet, 4 on desktop - Task dialog: Stack type/priority/status on mobile - Dialogs: Use 95vw width with max-width for better mobile fit
This commit is contained in:
parent
7badcb8bba
commit
dbf68e4640
@ -109,26 +109,26 @@ export default function Home() {
|
|||||||
<div className="max-w-[1800px] mx-auto px-4 py-4">
|
<div className="max-w-[1800px] mx-auto px-4 py-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
|
<h1 className="text-xl md:text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent">
|
||||||
OpenClaw Project Hub
|
OpenClaw Project Hub
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-sm text-slate-400 mt-1">
|
<p className="text-xs md:text-sm text-slate-400 mt-1">
|
||||||
Track ideas, tasks, bugs, and plans — with threaded notes
|
Track ideas, tasks, bugs, and plans — with threaded notes
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-sm text-slate-400">
|
<span className="hidden md:inline text-sm text-slate-400">
|
||||||
{tasks.length} tasks across {projects.length} projects
|
{tasks.length} tasks · {projects.length} projects
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="max-w-[1800px] mx-auto px-4 py-6">
|
<div className="max-w-[1800px] mx-auto px-4 py-4 md:py-6">
|
||||||
<div className="flex gap-6">
|
<div className="flex flex-col lg:flex-row gap-4 lg:gap-6">
|
||||||
{/* Sidebar - Projects */}
|
{/* Sidebar - Projects */}
|
||||||
<aside className="w-64 shrink-0">
|
<aside className="w-full lg:w-64 shrink-0">
|
||||||
<Card className="bg-slate-900 border-slate-800">
|
<Card className="bg-slate-900 border-slate-800">
|
||||||
<CardHeader className="pb-3">
|
<CardHeader className="pb-3">
|
||||||
<CardTitle className="text-sm font-semibold text-slate-400 uppercase tracking-wider">
|
<CardTitle className="text-sm font-semibold text-slate-400 uppercase tracking-wider">
|
||||||
@ -213,23 +213,23 @@ export default function Home() {
|
|||||||
<main className="flex-1 min-w-0">
|
<main className="flex-1 min-w-0">
|
||||||
{selectedProject ? (
|
{selectedProject ? (
|
||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-3 mb-4 md:mb-6">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-semibold text-white">
|
<h2 className="text-lg md:text-xl font-semibold text-white">
|
||||||
{selectedProject.name}
|
{selectedProject.name}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-sm text-slate-400">
|
<p className="text-sm text-slate-400">
|
||||||
{projectTasks.length} tasks · {projectTasks.filter((t) => t.status === "done").length} done
|
{projectTasks.length} tasks · {projectTasks.filter((t) => t.status === "done").length} done
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<Button onClick={() => setNewTaskOpen(true)}>
|
<Button onClick={() => setNewTaskOpen(true)} className="w-full sm:w-auto">
|
||||||
<Plus className="w-4 h-4 mr-2" />
|
<Plus className="w-4 h-4 mr-2" />
|
||||||
Add Task
|
Add Task
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Kanban Columns */}
|
{/* Kanban Columns */}
|
||||||
<div className="grid grid-cols-4 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
|
||||||
{statusColumns.map((status) => {
|
{statusColumns.map((status) => {
|
||||||
const columnTasks = projectTasks.filter((t) => t.status === status)
|
const columnTasks = projectTasks.filter((t) => t.status === status)
|
||||||
return (
|
return (
|
||||||
@ -339,7 +339,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* New Task Dialog */}
|
{/* New Task Dialog */}
|
||||||
<Dialog open={newTaskOpen} onOpenChange={setNewTaskOpen}>
|
<Dialog open={newTaskOpen} onOpenChange={setNewTaskOpen}>
|
||||||
<DialogContent className="bg-slate-900 border-slate-800 text-white max-w-lg">
|
<DialogContent className="bg-slate-900 border-slate-800 text-white w-[95vw] max-w-lg max-h-[90vh] overflow-y-auto">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>New Task</DialogTitle>
|
<DialogTitle>New Task</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
@ -364,7 +364,7 @@ export default function Home() {
|
|||||||
rows={3}
|
rows={3}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<Label>Type</Label>
|
<Label>Type</Label>
|
||||||
<select
|
<select
|
||||||
@ -424,7 +424,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Task Detail Dialog with Comments */}
|
{/* Task Detail Dialog with Comments */}
|
||||||
<Dialog open={!!selectedTaskId} onOpenChange={() => selectTask(null)}>
|
<Dialog open={!!selectedTaskId} onOpenChange={() => selectTask(null)}>
|
||||||
<DialogContent className="bg-slate-900 border-slate-800 text-white max-w-2xl max-h-[85vh] overflow-y-auto">
|
<DialogContent className="bg-slate-900 border-slate-800 text-white w-[95vw] max-w-2xl max-h-[90vh] overflow-y-auto p-4 md:p-6">
|
||||||
{selectedTask && (
|
{selectedTask && (
|
||||||
<>
|
<>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user