-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
922 additions
and
8 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
src/app/[lang]/edit/(crag)/[cragSlug]/sectors/components/edit-sectors.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { Crag } from "@/graphql/generated"; | ||
import EditSectorsNone from "./edit-sectors/edit-sectors-none"; | ||
import EditSectorsMany from "./edit-sectors/edit-sectors-many"; | ||
|
||
type TEditCragSectorsProps = { | ||
crag: Crag; | ||
}; | ||
|
||
function EditSectors({ crag }: TEditCragSectorsProps) { | ||
// Dep: crag.label is deprecated. remove it's use after api is updated and labels migrated into name | ||
const cragHasSectors = | ||
crag.sectors.length > 1 || | ||
!!crag.sectors[0]?.name || | ||
!!crag.sectors[0]?.label; | ||
|
||
return ( | ||
<div className="px-4 xs:px-8 mt-5"> | ||
{cragHasSectors ? ( | ||
<EditSectorsMany sectors={crag.sectors} cragId={crag.id} /> | ||
) : ( | ||
<EditSectorsNone /> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
||
export default EditSectors; |
58 changes: 58 additions & 0 deletions
58
...pp/[lang]/edit/(crag)/[cragSlug]/sectors/components/edit-sectors/delete-sector-dialog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import Dialog from "@/components/ui/dialog"; | ||
import { Sector } from "@/graphql/generated"; | ||
import { Dispatch, SetStateAction, useState } from "react"; | ||
import deleteSectorAction from "../../server-actions/delete-sector-action"; | ||
import { useRouter } from "next/navigation"; | ||
|
||
type TDeleteSectorDialog = { | ||
isOpen: boolean; | ||
setIsOpen: Dispatch<SetStateAction<boolean>>; | ||
sector: Sector; | ||
}; | ||
|
||
function DeleteSectorDialog({ | ||
isOpen, | ||
setIsOpen, | ||
sector, | ||
}: TDeleteSectorDialog) { | ||
const router = useRouter(); | ||
|
||
const [loading, setLoading] = useState(false); | ||
|
||
// Dep.: sector.label is deprecated. remove after removed in BE | ||
const labelAndName = | ||
sector.label && sector.name | ||
? `${sector.label} - ${sector.name}` | ||
: sector.label || sector.name || ""; | ||
|
||
const handleConfirm = async () => { | ||
setLoading(true); | ||
await deleteSectorAction(sector.id); | ||
setIsOpen(false); | ||
setLoading(false); | ||
router.refresh(); | ||
}; | ||
|
||
return ( | ||
<Dialog | ||
title="Brisanje sektorja" | ||
isOpen={isOpen} | ||
setIsOpen={setIsOpen} | ||
cancel={{ label: "Prekliči", disabled: loading }} | ||
confirm={{ | ||
label: "Briši", | ||
callback: handleConfirm, | ||
dontCloseOnConfirm: true, | ||
loading: loading, | ||
disabled: loading, | ||
}} | ||
> | ||
<> | ||
Ali res želiš izbrisati sektor{" "} | ||
<span className="font-medium">{labelAndName}</span> in vse smeri v njem? | ||
</> | ||
</Dialog> | ||
); | ||
} | ||
|
||
export default DeleteSectorDialog; |
181 changes: 181 additions & 0 deletions
181
src/app/[lang]/edit/(crag)/[cragSlug]/sectors/components/edit-sectors/edit-sectors-many.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
"use client"; | ||
|
||
import Checkbox from "@/components/ui/checkbox"; | ||
import IconPlus from "@/components/ui/icons/plus"; | ||
import { Sector } from "@/graphql/generated"; | ||
import SectorCard from "./sector-card"; | ||
import { Fragment, useEffect, useState } from "react"; | ||
import SectorDialog from "./sector-dialog"; | ||
import DeleteSectorDialog from "./delete-sector-dialog"; | ||
import { | ||
DndContext, | ||
DragEndEvent, | ||
KeyboardSensor, | ||
PointerSensor, | ||
closestCenter, | ||
useSensor, | ||
useSensors, | ||
} from "@dnd-kit/core"; | ||
import { | ||
SortableContext, | ||
arrayMove, | ||
sortableKeyboardCoordinates, | ||
} from "@dnd-kit/sortable"; | ||
import { restrictToParentElement } from "@dnd-kit/modifiers"; | ||
import updateSectorAction from "../../server-actions/update-sector-action"; | ||
import { useRouter } from "next/navigation"; | ||
|
||
type TEditCragSectorsManyProps = { | ||
sectors: Sector[]; | ||
cragId: string; | ||
}; | ||
|
||
function EditSectorsMany({ sectors, cragId }: TEditCragSectorsManyProps) { | ||
const router = useRouter(); | ||
const [loading, setLoading] = useState(false); | ||
|
||
const [sectorDialogType, setSectorDialogType] = useState<"new" | "edit">(); | ||
const [sectorDialogIsOpen, setSectorDialogIsOpen] = useState(false); | ||
const [position, setPosition] = useState(0); | ||
const [sector, setSector] = useState<Sector>(sectors[0]); | ||
const [sortedSectors, setSortedSectors] = useState(sectors); | ||
useEffect(() => { | ||
setSortedSectors(sectors); | ||
}, [sectors]); | ||
|
||
const handleCragHasSectorsChange = () => {}; | ||
|
||
const handleAddSectorClick = (position: number) => { | ||
setSectorDialogType("new"); | ||
setPosition(position); | ||
setSectorDialogIsOpen(true); | ||
}; | ||
|
||
const handleEditSectorClick = (sector: Sector) => { | ||
setSectorDialogType("edit"); | ||
setSector(sector); | ||
setSectorDialogIsOpen(true); | ||
}; | ||
|
||
const [deleteSectorDialogIsOpen, setDeleteSectorDialogIsOpen] = | ||
useState(false); | ||
const handleDeleteSectorClick = (sector: Sector) => { | ||
setSector(sector); | ||
setDeleteSectorDialogIsOpen(true); | ||
}; | ||
|
||
const handleDragEnd = async (event: DragEndEvent) => { | ||
const { active, over } = event; | ||
|
||
if (over && active.id !== over.id) { | ||
setLoading(true); | ||
|
||
const droppedSectorIndex = sortedSectors.findIndex( | ||
(sector) => sector.id === active.id | ||
); | ||
const targetSectorIndex = sortedSectors.findIndex( | ||
(sector) => sector.id === over.id | ||
); | ||
|
||
const newSortedSectors = arrayMove( | ||
sortedSectors, | ||
droppedSectorIndex, | ||
targetSectorIndex | ||
); | ||
|
||
setSortedSectors(newSortedSectors); | ||
|
||
const updatedSectorData = { | ||
id: sortedSectors[droppedSectorIndex].id, | ||
position: | ||
droppedSectorIndex > targetSectorIndex | ||
? sortedSectors[targetSectorIndex].position | ||
: sortedSectors[targetSectorIndex].position + 1, | ||
}; | ||
|
||
await updateSectorAction(updatedSectorData); | ||
router.refresh(); | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
const sensors = useSensors( | ||
useSensor(PointerSensor), | ||
useSensor(KeyboardSensor, { | ||
coordinateGetter: sortableKeyboardCoordinates, | ||
}) | ||
); | ||
|
||
return ( | ||
<> | ||
<Checkbox | ||
label="Plezališče ima več sektorjev" | ||
checked={true} | ||
disabled={loading} | ||
onChange={handleCragHasSectorsChange} | ||
/> | ||
|
||
<div className="h-18 flex items-stretch mt-5"> | ||
<button | ||
disabled={loading} | ||
className={`w-full flex justify-end items-center border border-dashed rounded-lg px-4 outline-none focus-visible:ring focus-visible:ring-blue-100 ${loading ? "text-neutral-400 border-neutral-300" : "text-neutral-500 hover:border-neutral-500 hover:text-neutral-600 active:text-neutral-700 active:border-neutral-600 border-neutral-400"}`} | ||
onClick={() => handleAddSectorClick(0)} | ||
> | ||
<span className="mr-2">dodaj sektor na začetek</span> | ||
<IconPlus /> | ||
</button> | ||
</div> | ||
|
||
<DndContext | ||
onDragEnd={handleDragEnd} | ||
collisionDetection={closestCenter} | ||
modifiers={[restrictToParentElement]} | ||
sensors={sensors} | ||
id="sort-sectors-dnd-context-id" | ||
> | ||
<SortableContext items={sortedSectors}> | ||
<div> | ||
{/* Dep: sector.label is deprecated. remove after api migrates it to name */} | ||
{sortedSectors.map((sector) => ( | ||
<Fragment key={sector.id}> | ||
<SectorCard | ||
id={sector.id} | ||
name={`${sector.label} - ${sector.name}`} | ||
disabled={loading} | ||
onEditClick={() => handleEditSectorClick(sector)} | ||
onAddClick={() => handleAddSectorClick(sector.position + 1)} | ||
onDeleteClick={() => handleDeleteSectorClick(sector)} | ||
/> | ||
</Fragment> | ||
))} | ||
</div> | ||
</SortableContext> | ||
</DndContext> | ||
|
||
{sectorDialogType === "new" ? ( | ||
<SectorDialog | ||
formType="new" | ||
isOpen={sectorDialogIsOpen} | ||
setIsOpen={setSectorDialogIsOpen} | ||
position={position} | ||
cragId={cragId} | ||
/> | ||
) : ( | ||
<SectorDialog | ||
formType="edit" | ||
isOpen={sectorDialogIsOpen} | ||
setIsOpen={setSectorDialogIsOpen} | ||
sector={sector} | ||
/> | ||
)} | ||
|
||
<DeleteSectorDialog | ||
isOpen={deleteSectorDialogIsOpen} | ||
setIsOpen={setDeleteSectorDialogIsOpen} | ||
sector={sector} | ||
/> | ||
</> | ||
); | ||
} | ||
|
||
export default EditSectorsMany; |
29 changes: 29 additions & 0 deletions
29
src/app/[lang]/edit/(crag)/[cragSlug]/sectors/components/edit-sectors/edit-sectors-none.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
"use client"; | ||
|
||
import Button from "@/components/ui/button"; | ||
import Checkbox from "@/components/ui/checkbox"; | ||
import IconRoutes from "@/components/ui/icons/routes"; | ||
|
||
function EditSectorsNone() { | ||
const handleCragHasSectorsChange = () => {}; | ||
const handleEditRoutesButtonClick = () => {}; | ||
|
||
return ( | ||
<div className="w-full flex justify-between flex-wrap gap-4"> | ||
<Checkbox | ||
label="Plezališče ima več sektorjev" | ||
checked={false} | ||
onChange={handleCragHasSectorsChange} | ||
/> | ||
|
||
<Button variant="quaternary" onClick={handleEditRoutesButtonClick}> | ||
<span className="flex"> | ||
<IconRoutes /> | ||
<span className="ml-2">Uredi smeri</span> | ||
</span> | ||
</Button> | ||
</div> | ||
); | ||
} | ||
|
||
export default EditSectorsNone; |
Oops, something went wrong.