Skip to content

Commit 1ad288e

Browse files
author
Rajat
committed
Re-arrange FAQ items
1 parent d8414d2 commit 1ad288e

5 files changed

Lines changed: 70 additions & 21 deletions

File tree

apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function Page(props: { params: Promise<{ id: string }> }) {
4444
siteinfo: siteInfo,
4545
address: address,
4646
profile: profile as Profile,
47-
auth: profile.email
47+
auth: profile!.email
4848
? {
4949
guest: false,
5050
checked: true,

packages/page-blocks/src/blocks/faq/admin-widget/index.tsx

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import {
1414
CssIdField,
1515
MaxWidthSelector,
1616
VerticalPaddingSelector,
17+
DragAndDrop,
18+
IconButton,
1719
} from "@courselit/components-library";
20+
import { Edit } from "@courselit/icons";
21+
import { generateUniqueId } from "@courselit/utils";
1822

1923
export interface AdminWidgetProps {
2024
settings: Settings;
@@ -39,7 +43,7 @@ export default function AdminWidget({
3943
hideActionButtons,
4044
preservedStateAcrossRerender,
4145
theme,
42-
}: AdminWidgetProps): JSX.Element {
46+
}: AdminWidgetProps) {
4347
const dummyDescription: Record<string, unknown> = {
4448
type: "doc",
4549
content: [
@@ -82,7 +86,8 @@ export default function AdminWidget({
8286
const [headerAlignment, setHeaderAlignment] = useState<Alignment>(
8387
settings.headerAlignment || "center",
8488
);
85-
const [itemBeingEditedIndex, setItemBeingEditedIndex] = useState(-1);
89+
const [itemBeingEditedIndex, setItemBeingEditedIndex] =
90+
useState<number>(-1);
8691
const [maxWidth, setMaxWidth] = useState<
8792
ThemeStyle["structure"]["page"]["width"]
8893
>(settings.maxWidth);
@@ -100,6 +105,7 @@ export default function AdminWidget({
100105
maxWidth,
101106
verticalPadding,
102107
cssId,
108+
itemBeingEditedIndex,
103109
});
104110

105111
useEffect(() => {
@@ -112,6 +118,7 @@ export default function AdminWidget({
112118
maxWidth,
113119
verticalPadding,
114120
cssId,
121+
itemBeingEditedIndex,
115122
]);
116123

117124
const onItemChange = (newItemData: Item) => {
@@ -179,21 +186,36 @@ export default function AdminWidget({
179186
</Form>
180187
</AdminWidgetPanel>
181188
<AdminWidgetPanel title="Items" value="items">
182-
<ul className="flex flex-col gap-2">
183-
{items.map((item: Item, index: number) => (
184-
<li
185-
key={item.title}
186-
onClick={() => {
187-
hideActionButtons(true, {
188-
selectedItem: index,
189-
});
190-
}}
191-
className="p-1 border border-transparent hover:border-slate-300 rounded"
192-
>
193-
{item.title}
194-
</li>
195-
))}
196-
</ul>
189+
<DragAndDrop
190+
items={items.map((item: Item) => ({
191+
item,
192+
id: generateUniqueId(),
193+
}))}
194+
Renderer={({ item }) => (
195+
<div className="flex justify-between items-center w-full">
196+
<p>{item.title}</p>
197+
<IconButton
198+
variant="soft"
199+
onClick={() => {
200+
hideActionButtons(true, {
201+
selectedItem: items.findIndex(
202+
(i) => i.title === item.title,
203+
),
204+
});
205+
}}
206+
>
207+
<Edit />
208+
</IconButton>
209+
</div>
210+
)}
211+
onChange={(newItems: { item: Item }[]) => {
212+
const itemsInNewOrder: Item[] = [];
213+
for (const item of newItems) {
214+
itemsInNewOrder.push(Object.assign({}, item.item));
215+
}
216+
setItems(itemsInNewOrder);
217+
}}
218+
/>
197219
<div>
198220
<Button component="button" onClick={addNewItem}>
199221
Add new item

packages/page-blocks/src/blocks/faq/admin-widget/item-editor.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ import {
66
Form,
77
FormField,
88
Tooltip,
9+
AlertDescription,
10+
Alert,
911
} from "@courselit/components-library";
1012
import { Address, Auth, Profile } from "@courselit/common-models";
13+
import { AlertCircle } from "lucide-react";
1114

1215
interface ItemProps {
1316
item: Item;
@@ -27,6 +30,7 @@ export default function ItemEditor({
2730
}: ItemProps): JSX.Element {
2831
const [title, setTitle] = useState(item.title);
2932
const [description, setDescription] = useState(item.description);
33+
const [deleteConfirmation, setDeleteConfirmation] = useState(false);
3034

3135
const itemChanged = () =>
3236
onChange({
@@ -36,6 +40,12 @@ export default function ItemEditor({
3640

3741
return (
3842
<div className="flex flex-col">
43+
<Alert variant="destructive" className="mb-4">
44+
<AlertCircle className="w-4 h-4" />
45+
<AlertDescription>
46+
Changes will be visible upon clicking Done button
47+
</AlertDescription>
48+
</Alert>
3949
<Form onSubmit={(e) => e.preventDefault()}>
4050
<FormField
4151
label="Title"
@@ -55,10 +65,16 @@ export default function ItemEditor({
5565
<Tooltip title="Delete">
5666
<Button
5767
component="button"
58-
onClick={onDelete}
68+
onClick={() => {
69+
if (deleteConfirmation) {
70+
onDelete();
71+
} else {
72+
setDeleteConfirmation(true);
73+
}
74+
}}
5975
variant="soft"
6076
>
61-
Delete
77+
{deleteConfirmation ? "Sure?" : "Delete"}
6278
</Button>
6379
</Tooltip>
6480
<Tooltip title="Go back">

packages/page-blocks/src/blocks/faq/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ export default interface Settings extends WidgetDefaultSettings {
1212
itemsAlignment: Alignment;
1313
items?: Item[];
1414
cssId?: string;
15+
itemBeingEditedIndex?: number;
1516
}

packages/page-blocks/src/blocks/faq/widget.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,20 @@ export default function Widget({
2525
cssId,
2626
maxWidth,
2727
verticalPadding,
28+
itemBeingEditedIndex,
2829
},
2930
state,
31+
editing,
3032
}: WidgetProps<Settings>) {
3133
const { theme } = state;
3234
const overiddenTheme: ThemeStyle = JSON.parse(JSON.stringify(theme.theme));
3335
overiddenTheme.structure.page.width =
3436
maxWidth || theme.theme.structure.page.width;
3537
overiddenTheme.structure.section.padding.y =
3638
verticalPadding || theme.theme.structure.section.padding.y;
39+
const accordionValue = editing
40+
? `${items[itemBeingEditedIndex]?.title}-${itemBeingEditedIndex}`
41+
: undefined;
3742

3843
return (
3944
<Section theme={overiddenTheme} id={cssId}>
@@ -64,7 +69,12 @@ export default function Widget({
6469
</div>
6570
{items && items.length > 0 && (
6671
<div className="flex flex-wrap gap-[1%]">
67-
<Accordion type="single" collapsible className="w-full">
72+
<Accordion
73+
type="single"
74+
collapsible
75+
className="w-full"
76+
value={accordionValue}
77+
>
6878
{items.map((item: Item, index: number) => (
6979
<AccordionItem
7080
key={`${item.title}-${index}`}

0 commit comments

Comments
 (0)