Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions apps/web/components/roadmap/RoadmapBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ export default function RoadmapBoard({

return (
<>
<div className="flex-1 overflow-x-auto overflow-y-hidden">
<div className="flex justify-center">
<div className="overflow-x-auto snap-x snap-mandatory md:overflow-x-auto h-full">
<div className="flex md:justify-center h-full">
<div
className="flex space-x-6 pb-6 h-full"
className="flex space-x-4 md:space-x-6 pb-6 px-4 md:px-0 h-full"
style={{ minHeight: "calc(100vh - 300px)" }}
>
{columns.map((column) => (
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/roadmap/RoadmapColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function RoadmapColumn({
}: RoadmapColumnProps) {
return (
<div
className={`flex-shrink-0 w-80 flex flex-col transition-colors ${
className={`flex-shrink-0 snap-center w-[calc(100vw-3rem)] md:w-80 flex flex-col transition-colors ${
dragOverColumn === column.id
? "bg-indigo-50 dark:bg-indigo-900/20 rounded-lg"
: ""
Expand Down
2 changes: 1 addition & 1 deletion apps/web/components/roadmap/RoadmapItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function RoadmapItem({
)}
</h4>
</div>
<div className="flex space-x-1 opacity-0 group-hover:opacity-100 transition-opacity ml-2">
<div className="flex space-x-1 opacity-100 md:opacity-0 md:group-hover:opacity-100 transition-opacity ml-2">
<button
onClick={(e) => {
e.stopPropagation();
Expand Down
216 changes: 114 additions & 102 deletions apps/web/components/roadmap/RoadmapItemModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
IRoadmapCategory,
} from "@changes-page/supabase/types/page";
import { Dialog, Transition } from "@headlessui/react";
import { XIcon } from "@heroicons/react/outline";
import { Fragment, useCallback } from "react";
import MarkdownEditor from "../core/editor.component";
import { FormErrors, ItemForm, RoadmapItemWithRelations } from "./types";
Expand Down Expand Up @@ -45,7 +46,7 @@ export default function RoadmapItemModal({
return (
// @ts-ignore
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={onClose}>
<Dialog as="div" className="relative z-50" onClose={onClose}>
<Transition.Child
// @ts-ignore
as={Fragment}
Expand All @@ -71,127 +72,138 @@ export default function RoadmapItemModal({
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="relative">
<div className="relative w-full sm:w-auto">
{/* Desktop Close Button */}
<button
type="button"
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"
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"
onClick={onClose}
>
<svg
className="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M6 18L18 6M6 6l12 12"
/>
</svg>
<XIcon className="h-5 w-5" aria-hidden="true" />
</button>
<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">
<form onSubmit={onSubmit}>
{formErrors.general && (
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-4 mb-6">
<div className="text-sm text-red-700 dark:text-red-400">
{formErrors.general}
</div>
</div>
)}

{formErrors.title && (
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-3 mb-4">
<div className="text-sm text-red-700 dark:text-red-400">
{formErrors.title}
<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">
{/* Mobile Header with Close Button */}
<div className="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700 sm:hidden">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white truncate">
{editingItem ? "Edit Item" : "Create Item"}
</h3>
<button
type="button"
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"
onClick={onClose}
>
<XIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
<div className="p-4 sm:p-8 overflow-y-auto flex-1 sm:h-auto">
<form onSubmit={onSubmit} className="h-full">
{formErrors.general && (
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-4 mb-6">
<div className="text-sm text-red-700 dark:text-red-400">
{formErrors.general}
</div>
</div>
</div>
)}

<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 relative">
<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>
)}

<div className="lg:col-span-2 space-y-6">
<div>
<input
type="text"
value={itemForm.title}
onChange={(e) =>
setItemForm((prev) => ({
...prev,
title: e.target.value,
}))
}
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"
placeholder="Enter item title..."
/>
<MarkdownEditor
value={itemForm.description}
onChange={handleDescriptionChange}
imagesFolderPrefix={null}
/>
{formErrors.title && (
<div className="rounded-md bg-red-50 dark:bg-red-900/20 p-3 mb-4">
<div className="text-sm text-red-700 dark:text-red-400">
{formErrors.title}
</div>
</div>
</div>
)}

<div className="lg:col-span-1 space-y-6">
{categories.length > 0 && (
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
Category
</span>
<select
value={itemForm.category_id}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 relative h-full">
{/* Column Divider */}
<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>

{/* Left side - Content */}
<div className="lg:col-span-2 space-y-6">
<h3 className="hidden sm:block text-xl font-semibold leading-6 text-gray-900 dark:text-white">
{editingItem ? "Edit Item" : "Create Item"}
</h3>
<div>
<input
type="text"
value={itemForm.title}
onChange={(e) =>
setItemForm((prev) => ({
...prev,
category_id: e.target.value,
title: e.target.value,
}))
}
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"
>
<option value="">No category</option>
{categories.map((category) => (
<option key={category.id} value={category.id}>
{category.name}
</option>
))}
</select>
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"
placeholder="Enter item title..."
/>
<MarkdownEditor
value={itemForm.description}
onChange={handleDescriptionChange}
imagesFolderPrefix={null}
/>
</div>
)}

<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
Board
</span>
<span className="text-sm text-gray-900 dark:text-gray-100 font-medium">
{board.title}
</span>
</div>

<div className="space-y-3 pt-4">
<button
type="submit"
disabled={isSubmitting}
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"
>
{isSubmitting
? "Saving..."
: editingItem
? "Update Item"
: "Create Item"}
</button>
<button
type="button"
onClick={onClose}
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"
>
Cancel
</button>
{/* Right side - Metadata */}
<div className="lg:col-span-1 space-y-6">
{categories.length > 0 && (
<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
Category
</span>
<select
value={itemForm.category_id}
onChange={(e) =>
setItemForm((prev) => ({
...prev,
category_id: e.target.value,
}))
}
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"
>
<option value="">No category</option>
{categories.map((category) => (
<option key={category.id} value={category.id}>
{category.name}
</option>
))}
</select>
</div>
)}

<div className="flex items-center justify-between">
<span className="text-sm font-medium text-gray-500 dark:text-gray-400">
Board
</span>
<span className="text-sm text-gray-900 dark:text-gray-100 font-medium">
{board.title}
</span>
</div>

<div className="space-y-3 pt-4">
<button
type="submit"
disabled={isSubmitting}
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"
>
{isSubmitting
? "Saving..."
: editingItem
? "Update Item"
: "Create Item"}
</button>
<button
type="button"
onClick={onClose}
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"
>
Cancel
</button>
</div>
</div>
</div>
</div>
</form>
</form>
</div>
</Dialog.Panel>
</div>
</Transition.Child>
Expand Down
4 changes: 0 additions & 4 deletions apps/web/pages/pages/[page_id]/roadmap/[board_id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ export default function RoadmapBoardDetails({
Private
</div>
)}
<span className="text-gray-500 dark:text-gray-400">•</span>
<span className="text-gray-600 dark:text-gray-400">
{board.description || "No description"}
</span>
</div>
}
showBackButton={true}
Expand Down