From 3f8d8cba19dd12838fbdfb1e4d0ade061d4eeda1 Mon Sep 17 00:00:00 2001 From: Emil Date: Thu, 12 Jan 2023 19:14:55 -0500 Subject: [PATCH] chore(profile): sortable links --- .../app/components/nft-collection/Check.tsx | 80 ++++++++ apps/profile/app/routes/account/gallery.tsx | 1 - .../app/routes/account/settings/links.tsx | 191 +++++++++++------- .../account/src/jsonrpc/validators/profile.ts | 2 +- 4 files changed, 200 insertions(+), 74 deletions(-) create mode 100644 apps/profile/app/components/nft-collection/Check.tsx diff --git a/apps/profile/app/components/nft-collection/Check.tsx b/apps/profile/app/components/nft-collection/Check.tsx new file mode 100644 index 0000000000..f2d9d2dcde --- /dev/null +++ b/apps/profile/app/components/nft-collection/Check.tsx @@ -0,0 +1,80 @@ +import React, { useState } from 'react' +import { useSortable } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' + +import { + DndContext, + closestCenter, + KeyboardSensor, + PointerSensor, + useSensor, + useSensors, +} from '@dnd-kit/core' +import { + arrayMove, + SortableContext, + sortableKeyboardCoordinates, + verticalListSortingStrategy, +} from '@dnd-kit/sortable' + +import styles from '~/components/nft-collection/styles.css' + +export const links = () => [{ rel: 'stylesheet', href: styles }] + +export function SortableItem(props: any) { + const { attributes, listeners, setNodeRef, transform, transition } = + useSortable({ id: props.id }) + + const style = { + transform: CSS.Transform.toString(transform), + transition, + } + + return ( +
+ {props.id} + + {props.id} +
+ ) +} + +export default function App() { + const [items, setItems] = useState(['1', '2', '3']) + const sensors = useSensors( + useSensor(PointerSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates, + }) + ) + + console.log(items) + return ( + + + {items.map((id) => ( + + ))} + + + ) + + function handleDragEnd(event: any) { + const { active, over } = event + + if (active.id !== over.id) { + setItems((items) => { + const oldIndex = items.indexOf(active.id) + const newIndex = items.indexOf(over.id) + + return arrayMove(items, oldIndex, newIndex) + }) + } + } +} diff --git a/apps/profile/app/routes/account/gallery.tsx b/apps/profile/app/routes/account/gallery.tsx index e5987c16ad..628068c0e2 100644 --- a/apps/profile/app/routes/account/gallery.tsx +++ b/apps/profile/app/routes/account/gallery.tsx @@ -129,7 +129,6 @@ const Nft = forwardRef( * Don't know how to write it better so keep it for now */ height: '100%', - ...style, } return ( diff --git a/apps/profile/app/routes/account/settings/links.tsx b/apps/profile/app/routes/account/settings/links.tsx index f40f3dbad7..3d84d5f921 100644 --- a/apps/profile/app/routes/account/settings/links.tsx +++ b/apps/profile/app/routes/account/settings/links.tsx @@ -1,4 +1,10 @@ -import { React, useState, useEffect } from 'react' +import React, { + useState, + useEffect, + forwardRef, + useRef, + useLayoutEffect, +} from 'react' import type { ActionFunction } from 'react-router-dom' import { @@ -8,13 +14,23 @@ import { useActionData, } from '@remix-run/react' -import { useSensor, useSensors, DndContext, closestCenter } from '@dnd-kit/core' +import { + useSensor, + useSensors, + DndContext, + closestCenter, + KeyboardSensor, + MouseSensor, + TouchSensor, +} from '@dnd-kit/core' import { useSortable, arrayMove, SortableContext, verticalListSortingStrategy, + sortableKeyboardCoordinates, } from '@dnd-kit/sortable' +import { CSS } from '@dnd-kit/utilities' import { requireJWT } from '~/utils/session.server' import { PlatformJWTAssertionHeader } from '@kubelt/platform-middleware/jwt' @@ -29,6 +45,7 @@ import { Button } from '@kubelt/design-system/src/atoms/buttons/Button' import { Text } from '@kubelt/design-system/src/atoms/text/Text' import { Tooltip } from 'flowbite-react' +import SortApp from '~/components/nft-collection/Check' import InputText from '~/components/inputs/InputText' import SaveButton from '~/components/accounts/SaveButton' @@ -119,9 +136,15 @@ export const action: ActionFunction = async ({ request }) => { return { updatedLinks } } -export const SortableItem = (props) => { - const { attributes, listeners, setNodeRef, transform, transition } = - useSortable({ id: props.id }) +const SortableLink = (props: any) => { + const { + attributes, + listeners, + setNodeRef, + transform, + transition, + isDragging, + } = useSortable({ id: props.id }) const style = { transform: CSS.Transform.toString(transform), @@ -129,39 +152,113 @@ export const SortableItem = (props) => { } return ( -
- {/* ... */} +
+
+ + + + +
+ + {props.link.name} + + {props.link.url} +
+
+ {/* // Puts current link in "modification" regyme */} +
) } export default function AccountSettingsLinks() { + const [items, setItems] = useState(['1', '2', '3']) + const { notificationHandler } = useOutletContext() const transition = useTransition() const actionData = useActionData() const [activeId, setActiveId] = useState(null) - const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor)) + const [activeLink, setActiveLink] = useState(null) + const sensors = useSensors( + useSensor(MouseSensor), + useSensor(TouchSensor), + useSensor(KeyboardSensor, { + coordinateGetter: sortableKeyboardCoordinates, + }) + ) const [links, setLinks] = useState( useRouteData('routes/account')?.links || [] ) - const handleDragStart = ({ active }) => { - setActiveId(active) + const handleDragCancel = () => { + setActiveLink(null) + setActiveId(null) + } + + const handleDragStart = ({ active }: { active: any }) => { + const id = parseInt(active.id) + setActiveLink(active.data.current.sortable.items[id]) + setActiveId(id as any) } - const handleDragEnd = (event) => { + const handleDragEnd = (event: any) => { const { active, over } = event + const active_id = parseInt(active.id) + const over_id = parseInt(over.id) - if (active.id !== over.id) { + if (active_id !== over_id) { setLinks((links) => { - const oldIndex = links.indexOf(active.id) - const newIndex = links.indexOf(over.id) + const oldIndex = parseInt(active.id) + const newIndex = parseInt(over.id) return arrayMove(links, oldIndex, newIndex) }) } + setActiveId(null) + setActiveLink(null) } const [isFormChanged, setFormChanged] = useState(false) @@ -188,7 +285,6 @@ export default function AccountSettingsLinks() { > Connected Account Links -
`${id}`)} strategy={verticalListSortingStrategy} > {(links || []).map((link: any, i: number) => ( -
-
- - - - -
- - {link.name} - - - {link.url} - -
-
- {/* Puts current link in "modification" regyme */} - -
+ id={`${i}`} + link={link} + /> ))}
- - {activeId ? : null} -
diff --git a/platform/account/src/jsonrpc/validators/profile.ts b/platform/account/src/jsonrpc/validators/profile.ts index 6d04332c67..5f729c30bf 100644 --- a/platform/account/src/jsonrpc/validators/profile.ts +++ b/platform/account/src/jsonrpc/validators/profile.ts @@ -22,7 +22,7 @@ export const ProfileSchema = z.object({ name: z.string(), url: z.string().url().or(z.literal('')), verified: z.boolean(), - links_order: z.number(), + links_order: z.number().optional().nullable(), }) ) .optional()