From 5dc0dae924efa32cb54278d4432e465b46ae0d71 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 4 Mar 2024 15:37:50 +0700 Subject: [PATCH] feat: rearrange posts --- .../components/launches/add.edit.model.tsx | 173 ++++++++++++------ .../providers/high.order.provider.tsx | 148 +++++++++------ .../src/components/launches/up.down.arrow.tsx | 62 +++++++ 3 files changed, 269 insertions(+), 114 deletions(-) create mode 100644 apps/frontend/src/components/launches/up.down.arrow.tsx diff --git a/apps/frontend/src/components/launches/add.edit.model.tsx b/apps/frontend/src/components/launches/add.edit.model.tsx index 640b7115..b9c26eb6 100644 --- a/apps/frontend/src/components/launches/add.edit.model.tsx +++ b/apps/frontend/src/components/launches/add.edit.model.tsx @@ -1,6 +1,13 @@ 'use client'; -import React, {FC, MouseEventHandler, useCallback, useEffect, useState} from 'react'; +import React, { + FC, + Fragment, + MouseEventHandler, + useCallback, + useEffect, + useState, +} from 'react'; import dayjs from 'dayjs'; import { Integrations } from '@gitroom/frontend/components/launches/calendar.context'; import clsx from 'clsx'; @@ -29,6 +36,7 @@ import { v4 as uuidv4 } from 'uuid'; import { useSWRConfig } from 'swr'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { postSelector } from '@gitroom/frontend/components/post-url-selector/post.url.selector'; +import { UpDownArrow } from '@gitroom/frontend/components/launches/up.down.arrow'; export const AddEditModal: FC<{ date: dayjs.Dayjs; @@ -125,6 +133,31 @@ export const AddEditModal: FC<{ [value] ); + const changePosition = useCallback( + (index: number) => (type: 'up' | 'down') => { + if (type === 'up' && index !== 0) { + setValue((prev) => { + const temp = prev[index]; + prev[index] = prev[index - 1]; + prev[index - 1] = temp; + return [...prev]; + }); + } else if ( + type === 'down' && + value.length !== 0 && + value.length !== index + 1 + ) { + setValue((prev) => { + const temp = prev[index]; + prev[index] = prev[index + 1]; + prev[index + 1] = temp; + return [...prev]; + }); + } + }, + [value] + ); + // Delete post const deletePost = useCallback( (index: number) => async () => { @@ -159,12 +192,15 @@ export const AddEditModal: FC<{ // sometimes it's easier to click escape to close useKeypress('Escape', askClose); - const postNow = useCallback(((e) => { - e.stopPropagation(); - e.preventDefault(); + const postNow = useCallback( + ((e) => { + e.stopPropagation(); + e.preventDefault(); - return schedule('now')(); - }) as MouseEventHandler, []); + return schedule('now')(); + }) as MouseEventHandler, + [] + ); // function to send to the server and save const schedule = useCallback( @@ -281,63 +317,77 @@ export const AddEditModal: FC<{ <>
You are in global editing mode
{value.map((p, index) => ( - <> +
- 1 ? 150 : 250} - commands={[ - ...commands - .getCommands() - .filter((f) => f.name !== 'image'), - newImage, - postSelector(date), - ]} - value={p.content} - preview="edit" - // @ts-ignore - onChange={changeValue(index)} - /> - {showError && (!p.content || p.content.length < 6) && ( -
- The post should be at least 6 characters long -
- )} -
+
- 1 ? 150 : 250} + commands={[ + ...commands + .getCommands() + .filter((f) => f.name !== 'image'), + newImage, + postSelector(date), + ]} + value={p.content} + preview="edit" + // @ts-ignore + onChange={changeValue(index)} /> -
-
- {value.length > 1 && ( -
-
- - - -
-
- Delete Post + + {showError && + (!p.content || p.content.length < 6) && ( +
+ The post should be at least 6 characters long
+ )} +
+
+
- )} +
+ {value.length > 1 && ( +
+
+ + + +
+
+ Delete Post +
+
+ )} +
+
+
+
+
@@ -363,7 +413,7 @@ export const AddEditModal: FC<{
Add post
- + ))} ) : null} @@ -411,7 +461,10 @@ export const AddEditModal: FC<{ fill="white" /> -
+
Post now
diff --git a/apps/frontend/src/components/launches/providers/high.order.provider.tsx b/apps/frontend/src/components/launches/providers/high.order.provider.tsx index 83e5f3e4..75853682 100644 --- a/apps/frontend/src/components/launches/providers/high.order.provider.tsx +++ b/apps/frontend/src/components/launches/providers/high.order.provider.tsx @@ -1,7 +1,8 @@ 'use client'; -import { +import React, { FC, + Fragment, ReactNode, useCallback, useEffect, @@ -25,6 +26,7 @@ import { createPortal } from 'react-dom'; import clsx from 'clsx'; import { newImage } from '@gitroom/frontend/components/launches/helpers/new.image.component'; import { postSelector } from '@gitroom/frontend/components/post-url-selector/post.url.selector'; +import { UpDownArrow } from '@gitroom/frontend/components/launches/up.down.arrow'; // Simple component to change back to settings on after changing tab export const SetTab: FC<{ changeTab: () => void }> = (props) => { @@ -150,6 +152,31 @@ export const withProvider = ( [InPlaceValue] ); + const changePosition = useCallback( + (index: number) => (type: 'up' | 'down') => { + if (type === 'up' && index !== 0) { + setInPlaceValue((prev) => { + const temp = prev[index]; + prev[index] = prev[index - 1]; + prev[index - 1] = temp; + return [...prev]; + }); + } else if ( + type === 'down' && + InPlaceValue.length !== 0 && + InPlaceValue.length !== index + 1 + ) { + setInPlaceValue((prev) => { + const temp = prev[index]; + prev[index] = prev[index + 1]; + prev[index + 1] = temp; + return [...prev]; + }); + } + }, + [InPlaceValue] + ); + // Delete post const deletePost = useCallback( (index: number) => async () => { @@ -243,63 +270,76 @@ export const withProvider = (
)} {InPlaceValue.map((val, index) => ( - <> +
- 1 ? 200 : 250} - value={val.content} - commands={[ - ...commands - .getCommands() - .filter((f) => f.name !== 'image'), - newImage, - postSelector(date), - ]} - preview="edit" - // @ts-ignore - onChange={changeValue(index)} - /> - {(!val.content || val.content.length < 6) && ( -
- The post should be at least 6 characters long -
- )} -
+
- 1 ? 200 : 250} + value={val.content} + commands={[ + ...commands + .getCommands() + .filter((f) => f.name !== 'image'), + newImage, + postSelector(date), + ]} + preview="edit" + // @ts-ignore + onChange={changeValue(index)} /> -
-
- {InPlaceValue.length > 1 && ( -
-
- - - -
-
- Delete Post -
+ {(!val.content || val.content.length < 6) && ( +
+ The post should be at least 6 characters long
)} +
+
+ +
+
+ {InPlaceValue.length > 1 && ( +
+
+ + + +
+
+ Delete Post +
+
+ )} +
+
+
+
+
@@ -325,7 +365,7 @@ export const withProvider = (
Add post
- + ))}
, diff --git a/apps/frontend/src/components/launches/up.down.arrow.tsx b/apps/frontend/src/components/launches/up.down.arrow.tsx new file mode 100644 index 00000000..c88d5e5e --- /dev/null +++ b/apps/frontend/src/components/launches/up.down.arrow.tsx @@ -0,0 +1,62 @@ +import { FC, useCallback } from 'react'; +import clsx from 'clsx'; + +const Arrow: FC<{ flip: boolean }> = (props) => { + const { flip } = props; + return ( + + + + ); +}; +export const UpDownArrow: FC<{ + isUp: boolean; + isDown: boolean; + onChange: (type: 'up' | 'down') => void; +}> = (props) => { + const { isUp, isDown, onChange } = props; + + const changePosition = useCallback( + (type: 'up' | 'down') => () => { + onChange(type); + }, + [] + ); + + return ( +
+ + +
+ ); +};