Skip to content

Commit 2f0cf52

Browse files
authored
Merge pull request #91 from techulus/develop
Improve mobile UX for roadmaps
2 parents a9c52a3 + e53ac07 commit 2f0cf52

File tree

5 files changed

+119
-111
lines changed

5 files changed

+119
-111
lines changed

apps/web/components/roadmap/RoadmapBoard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ export default function RoadmapBoard({
4747

4848
return (
4949
<>
50-
<div className="flex-1 overflow-x-auto overflow-y-hidden">
51-
<div className="flex justify-center">
50+
<div className="overflow-x-auto snap-x snap-mandatory md:overflow-x-auto h-full">
51+
<div className="flex md:justify-center h-full">
5252
<div
53-
className="flex space-x-6 pb-6 h-full"
53+
className="flex space-x-4 md:space-x-6 pb-6 px-4 md:px-0 h-full"
5454
style={{ minHeight: "calc(100vh - 300px)" }}
5555
>
5656
{columns.map((column) => (

apps/web/components/roadmap/RoadmapColumn.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default function RoadmapColumn({
4545
}: RoadmapColumnProps) {
4646
return (
4747
<div
48-
className={`flex-shrink-0 w-80 flex flex-col transition-colors ${
48+
className={`flex-shrink-0 snap-center w-[calc(100vw-3rem)] md:w-80 flex flex-col transition-colors ${
4949
dragOverColumn === column.id
5050
? "bg-indigo-50 dark:bg-indigo-900/20 rounded-lg"
5151
: ""

apps/web/components/roadmap/RoadmapItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default function RoadmapItem({
5050
)}
5151
</h4>
5252
</div>
53-
<div className="flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity ml-2">
53+
<div className="flex space-x-1 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity ml-2">
5454
<button
5555
onClick={(e) => {
5656
e.stopPropagation();

apps/web/components/roadmap/RoadmapItemModal.tsx

Lines changed: 114 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
IRoadmapCategory,
44
} from "@changes-page/supabase/types/page";
55
import { Dialog, Transition } from "@headlessui/react";
6+
import { XIcon } from "@heroicons/react/outline";
67
import { Fragment, useCallback } from "react";
78
import MarkdownEditor from "../core/editor.component";
89
import { FormErrors, ItemForm, RoadmapItemWithRelations } from "./types";
@@ -45,7 +46,7 @@ export default function RoadmapItemModal({
4546
return (
4647
// @ts-ignore
4748
<Transition appear show={isOpen} as={Fragment}>
48-
<Dialog as="div" className="relative z-10" onClose={onClose}>
49+
<Dialog as="div" className="relative z-50" onClose={onClose}>
4950
<Transition.Child
5051
// @ts-ignore
5152
as={Fragment}
@@ -71,127 +72,138 @@ export default function RoadmapItemModal({
7172
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
7273
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
7374
>
74-
<div className="relative">
75+
<div className="relative w-full sm:w-auto">
76+
{/* Desktop Close Button */}
7577
<button
7678
type="button"
77-
className="absolute -top-4 -right-4 z-10 rounded-full bg-white dark:bg-gray-700 p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-lg border border-gray-200 dark:border-gray-600"
79+
className="hidden sm:block absolute -top-4 -right-4 z-30 rounded-full bg-white dark:bg-gray-700 p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 shadow-lg border border-gray-200 dark:border-gray-600"
7880
onClick={onClose}
7981
>
80-
<svg
81-
className="h-5 w-5"
82-
fill="none"
83-
viewBox="0 0 24 24"
84-
strokeWidth={2}
85-
stroke="currentColor"
86-
>
87-
<path
88-
strokeLinecap="round"
89-
strokeLinejoin="round"
90-
d="M6 18L18 6M6 6l12 12"
91-
/>
92-
</svg>
82+
<XIcon className="h-5 w-5" aria-hidden="true" />
9383
</button>
94-
<Dialog.Panel className="w-full max-w-5xl transform overflow-hidden rounded-t-2xl sm:rounded-2xl bg-white dark:bg-gray-800 p-8 text-left align-middle shadow-xl transition-all min-h-[50vh] sm:min-h-0">
95-
<form onSubmit={onSubmit}>
96-
{formErrors.general && (
97-
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-4 mb-6">
98-
<div className="text-sm text-red-700 dark:text-red-400">
99-
{formErrors.general}
100-
</div>
101-
</div>
102-
)}
10384

104-
{formErrors.title && (
105-
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-3 mb-4">
106-
<div className="text-sm text-red-700 dark:text-red-400">
107-
{formErrors.title}
85+
<Dialog.Panel className="w-full h-full sm:h-auto sm:max-w-5xl sm:min-w-[880px] transform overflow-hidden rounded-none sm:rounded-2xl bg-white dark:bg-gray-900 text-left align-middle shadow-xl transition-all flex flex-col sm:block">
86+
{/* Mobile Header with Close Button */}
87+
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 sm:hidden">
88+
<h3 className="text-lg font-semibold text-gray-900 dark:text-white truncate">
89+
{editingItem ? "Edit Item" : "Create Item"}
90+
</h3>
91+
<button
92+
type="button"
93+
className="rounded-full p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500"
94+
onClick={onClose}
95+
>
96+
<XIcon className="h-6 w-6" aria-hidden="true" />
97+
</button>
98+
</div>
99+
<div className="p-4 sm:p-8 overflow-y-auto flex-1 sm:h-auto">
100+
<form onSubmit={onSubmit} className="h-full">
101+
{formErrors.general && (
102+
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-4 mb-6">
103+
<div className="text-sm text-red-700 dark:text-red-400">
104+
{formErrors.general}
105+
</div>
108106
</div>
109-
</div>
110-
)}
111-
112-
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 relative">
113-
<div className="hidden lg:block absolute left-2/3 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-700 transform -translate-x-1/2 z-10"></div>
107+
)}
114108

115-
<div className="lg:col-span-2 space-y-6">
116-
<div>
117-
<input
118-
type="text"
119-
value={itemForm.title}
120-
onChange={(e) =>
121-
setItemForm((prev) => ({
122-
...prev,
123-
title: e.target.value,
124-
}))
125-
}
126-
className="w-full text-xl font-semibold leading-6 text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md px-3 py-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none mb-6"
127-
placeholder="Enter item title..."
128-
/>
129-
<MarkdownEditor
130-
value={itemForm.description}
131-
onChange={handleDescriptionChange}
132-
imagesFolderPrefix={null}
133-
/>
109+
{formErrors.title && (
110+
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-3 mb-4">
111+
<div className="text-sm text-red-700 dark:text-red-400">
112+
{formErrors.title}
113+
</div>
134114
</div>
135-
</div>
115+
)}
136116

137-
<div className="lg:col-span-1 space-y-6">
138-
{categories.length > 0 && (
139-
<div className="flex items-center justify-between">
140-
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
141-
Category
142-
</span>
143-
<select
144-
value={itemForm.category_id}
117+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 relative h-full">
118+
{/* Column Divider */}
119+
<div className="hidden lg:block absolute left-2/3 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-800 transform -translate-x-1/2 z-10"></div>
120+
121+
{/* Left side - Content */}
122+
<div className="lg:col-span-2 space-y-6">
123+
<h3 className="hidden sm:block text-xl font-semibold leading-6 text-gray-900 dark:text-white">
124+
{editingItem ? "Edit Item" : "Create Item"}
125+
</h3>
126+
<div>
127+
<input
128+
type="text"
129+
value={itemForm.title}
145130
onChange={(e) =>
146131
setItemForm((prev) => ({
147132
...prev,
148-
category_id: e.target.value,
133+
title: e.target.value,
149134
}))
150135
}
151-
className="text-sm rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-700 dark:text-gray-300"
152-
>
153-
<option value="">No category</option>
154-
{categories.map((category) => (
155-
<option key={category.id} value={category.id}>
156-
{category.name}
157-
</option>
158-
))}
159-
</select>
136+
className="w-full text-xl font-semibold leading-6 text-gray-900 dark:text-gray-100 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md px-3 py-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none mb-6"
137+
placeholder="Enter item title..."
138+
/>
139+
<MarkdownEditor
140+
value={itemForm.description}
141+
onChange={handleDescriptionChange}
142+
imagesFolderPrefix={null}
143+
/>
160144
</div>
161-
)}
162-
163-
<div className="flex items-center justify-between">
164-
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
165-
Board
166-
</span>
167-
<span className="text-sm text-gray-900 dark:text-gray-100 font-medium">
168-
{board.title}
169-
</span>
170145
</div>
171146

172-
<div className="space-y-3 pt-4">
173-
<button
174-
type="submit"
175-
disabled={isSubmitting}
176-
className="w-full inline-flex justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
177-
>
178-
{isSubmitting
179-
? "Saving..."
180-
: editingItem
181-
? "Update Item"
182-
: "Create Item"}
183-
</button>
184-
<button
185-
type="button"
186-
onClick={onClose}
187-
className="w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 shadow-sm hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
188-
>
189-
Cancel
190-
</button>
147+
{/* Right side - Metadata */}
148+
<div className="lg:col-span-1 space-y-6">
149+
{categories.length > 0 && (
150+
<div className="flex items-center justify-between">
151+
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
152+
Category
153+
</span>
154+
<select
155+
value={itemForm.category_id}
156+
onChange={(e) =>
157+
setItemForm((prev) => ({
158+
...prev,
159+
category_id: e.target.value,
160+
}))
161+
}
162+
className="text-sm rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:bg-gray-700 dark:text-gray-300"
163+
>
164+
<option value="">No category</option>
165+
{categories.map((category) => (
166+
<option key={category.id} value={category.id}>
167+
{category.name}
168+
</option>
169+
))}
170+
</select>
171+
</div>
172+
)}
173+
174+
<div className="flex items-center justify-between">
175+
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
176+
Board
177+
</span>
178+
<span className="text-sm text-gray-900 dark:text-gray-100 font-medium">
179+
{board.title}
180+
</span>
181+
</div>
182+
183+
<div className="space-y-3 pt-4">
184+
<button
185+
type="submit"
186+
disabled={isSubmitting}
187+
className="w-full inline-flex justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
188+
>
189+
{isSubmitting
190+
? "Saving..."
191+
: editingItem
192+
? "Update Item"
193+
: "Create Item"}
194+
</button>
195+
<button
196+
type="button"
197+
onClick={onClose}
198+
className="w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 shadow-sm hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
199+
>
200+
Cancel
201+
</button>
202+
</div>
191203
</div>
192204
</div>
193-
</div>
194-
</form>
205+
</form>
206+
</div>
195207
</Dialog.Panel>
196208
</div>
197209
</Transition.Child>

apps/web/pages/pages/[page_id]/roadmap/[board_id].tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ export default function RoadmapBoardDetails({
121121
Private
122122
</div>
123123
)}
124-
<span className="text-gray-500 dark:text-gray-400"></span>
125-
<span className="text-gray-600 dark:text-gray-400">
126-
{board.description || "No description"}
127-
</span>
128124
</div>
129125
}
130126
showBackButton={true}

0 commit comments

Comments
 (0)