Skip to content

Commit fb2fab0

Browse files
author
Rajat
committed
Communities data is cleaned up on delete
1 parent 77896b6 commit fb2fab0

21 files changed

Lines changed: 690 additions & 187 deletions

File tree

apps/queue/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ app.use("/job", verifyJWTMiddleware, jobRoutes);
1717
app.use("/sse", sseRoutes);
1818

1919
app.get("/healthy", (req, res) => {
20-
res.status(200).json({ success: true });
20+
res.status(200).json({ status: "ok", uptime: process.uptime() });
2121
});
2222

2323
startEmailAutomation();

apps/web/__mocks__/medialit.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class MediaLit {
2+
endpoint: string;
3+
constructor(config: { endpoint?: string }) {
4+
this.endpoint = config.endpoint || "https://medialit.example.com";
5+
}
6+
7+
async get(mediaId: string) {
8+
return {
9+
mediaId,
10+
file: "mock-file",
11+
originalFileName: "mock-file",
12+
mimeType: "image/png",
13+
size: 0,
14+
access: "public",
15+
url: `https://medialit.example.com/${mediaId}/main.png`,
16+
};
17+
}
18+
19+
async getSignature(_: { group: string }) {
20+
return "mock-signature";
21+
}
22+
23+
async delete(_: string) {
24+
return true;
25+
}
26+
}
27+
28+
export { MediaLit };

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ import {
1717
} from "@courselit/components-library";
1818
import { MoreVert } from "@courselit/icons";
1919
import {
20+
APP_MESSAGE_COURSE_DELETED,
2021
DELETE_PRODUCT_POPUP_HEADER,
2122
DELETE_PRODUCT_POPUP_TEXT,
2223
EDIT_BLOG,
2324
MANAGE_BLOG_PAGE_HEADING,
2425
MENU_BLOG_VISIT,
2526
PAGE_TITLE_404,
2627
PRODUCT_TABLE_CONTEXT_MENU_DELETE_PRODUCT,
28+
TOAST_TITLE_SUCCESS,
2729
} from "@ui-config/strings";
2830
import { truncate } from "@ui-lib/utils";
2931
import { useRouter, useSearchParams } from "next/navigation";
@@ -40,7 +42,7 @@ export default function Page(props: { params: Promise<{ id: string }> }) {
4042
const searchParams = useSearchParams();
4143
const [tab, setTab] = useState(searchParams?.get("tab") || "Details");
4244
const address = useContext(AddressContext);
43-
const course = useCourse(id, address);
45+
const course = useCourse(id);
4446
const router = useRouter();
4547
const { toast } = useToast();
4648

@@ -90,6 +92,11 @@ export default function Page(props: { params: Promise<{ id: string }> }) {
9092
router.replace(
9193
`/dashboard/blogs`,
9294
);
95+
toast({
96+
title: TOAST_TITLE_SUCCESS,
97+
description:
98+
APP_MESSAGE_COURSE_DELETED,
99+
});
93100
},
94101
toast,
95102
})

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
PRODUCT_EMPTY_WARNING,
4242
PRODUCT_TABLE_CONTEXT_MENU_INVITE_A_CUSTOMER,
4343
PRODUCT_UNPUBLISHED_WARNING,
44+
MANAGE_LINK_TEXT,
4445
TOAST_TITLE_SUCCESS,
4546
VIEW_PAGE_MENU_ITEM,
4647
} from "@ui-config/strings";
@@ -112,7 +113,7 @@ export default function DashboardPage() {
112113
href={`/dashboard/product/${productId}/manage#publish`}
113114
className="underline"
114115
>
115-
Manage
116+
{MANAGE_LINK_TEXT}
116117
</Link>
117118
</div>
118119
)}

apps/web/components/admin/blogs/editor/details.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,31 @@ export default function Details({ id }: DetailsProps) {
5656
e.preventDefault();
5757

5858
const mutation = `
59-
mutation {
59+
mutation ($courseId: String!, $title: String!, $description: String) {
6060
updateCourse(courseData: {
61-
id: "${course!.courseId}"
62-
title: "${title}",
63-
description: ${JSON.stringify(JSON.stringify(description))}
61+
id: $courseId
62+
title: $title
63+
description: $description
6464
}) {
6565
courseId
6666
}
6767
}
6868
`;
6969
const fetch = new FetchBuilder()
7070
.setUrl(`${address.backend}/api/graph`)
71-
.setPayload(mutation)
71+
.setPayload({
72+
query: mutation,
73+
variables: {
74+
courseId: course!.courseId,
75+
title: title,
76+
description: JSON.stringify(description),
77+
},
78+
})
7279
.setIsGraphQLEndpoint(true)
7380
.build();
7481
try {
7582
setLoading(true);
76-
const response = await fetch.exec();
77-
if (response.updateCourse) {
78-
toast({
79-
title: TOAST_TITLE_SUCCESS,
80-
description: APP_MESSAGE_COURSE_SAVED,
81-
});
82-
}
83+
await fetch.exec();
8384
} catch (err: any) {
8485
toast({
8586
title: TOAST_TITLE_ERROR,
Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { FetchBuilder } from "@courselit/utils";
2-
import {
3-
APP_MESSAGE_COURSE_DELETED,
4-
TOAST_TITLE_ERROR,
5-
TOAST_TITLE_SUCCESS,
6-
} from "@/ui-config/strings";
2+
import { TOAST_TITLE_ERROR } from "@/ui-config/strings";
73
import { useToast } from "@courselit/components-library";
84

95
interface DeleteProductProps {
@@ -22,14 +18,19 @@ export const deleteProduct = async ({
2218
if (!id) return;
2319

2420
const query = `
25-
mutation {
26-
result: deleteCourse(id: "${id}")
27-
}
21+
mutation ($id: String!) {
22+
result: deleteCourse(id: $id)
23+
}
2824
`;
2925

3026
const fetch = new FetchBuilder()
3127
.setUrl(`${backend}/api/graph`)
32-
.setPayload(query)
28+
.setPayload({
29+
query,
30+
variables: {
31+
id,
32+
},
33+
})
3334
.setIsGraphQLEndpoint(true)
3435
.build();
3536

@@ -38,18 +39,12 @@ export const deleteProduct = async ({
3839

3940
if (response.result) {
4041
onDeleteComplete && onDeleteComplete();
41-
// onDelete(position);
4242
}
4343
} catch (err: any) {
4444
toast({
4545
title: TOAST_TITLE_ERROR,
4646
description: err.message,
4747
variant: "destructive",
4848
});
49-
} finally {
50-
toast({
51-
title: TOAST_TITLE_SUCCESS,
52-
description: APP_MESSAGE_COURSE_DELETED,
53-
});
5449
}
5550
};

apps/web/components/admin/mails/index.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
import RequestForm from "./request-form";
3030
import SequencesList from "./sequences-list";
3131
import { Button } from "@components/ui/button";
32+
import Link from "next/link";
3233

3334
interface MailsProps {
3435
address: Address;
@@ -157,12 +158,9 @@ export default function Mails({ address, selectedTab }: MailsProps) {
157158
</CardHeader>
158159
<CardFooter>
159160
<div className="w-[120px]">
160-
<Button
161-
component="link"
162-
href={`/dashboard/settings?tab=Mails`}
163-
>
164-
Go to settings
165-
</Button>
161+
<Link href={`/dashboard/settings?tab=Mails`}>
162+
<Button>Go to settings</Button>
163+
</Link>
166164
</div>
167165
</CardFooter>
168166
</Card>

apps/web/components/community/banner.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, useRef } from "react";
1+
import { useState, useEffect, useRef, useContext } from "react";
22
import { Button } from "@/components/ui/button";
33
import { Alert, AlertDescription } from "@/components/ui/alert";
44
import { AlertCircle, Pencil, Check, X, Loader2 } from "lucide-react";
@@ -10,6 +10,7 @@ import {
1010
} from "@courselit/components-library";
1111
import { isTextEditorNonEmpty } from "@ui-lib/utils";
1212
import { BUTTON_SAVING, TOAST_TITLE_SUCCESS } from "@ui-config/strings";
13+
import { AddressContext } from "@components/contexts";
1314

1415
interface BannerComponentProps {
1516
canEdit: boolean;
@@ -29,6 +30,7 @@ export default function Banner({
2930
const [editedBannerText, setEditedBannerText] = useState(bannerText);
3031
const [isSaving, setIsSaving] = useState(false);
3132
const textareaRef = useRef<HTMLTextAreaElement>(null);
33+
const address = useContext(AddressContext);
3234
const { toast } = useToast();
3335

3436
useEffect(() => {
@@ -102,6 +104,7 @@ export default function Banner({
102104
showToolbar={false}
103105
initialContent={editedBannerText}
104106
onChange={(value) => setEditedBannerText(value)}
107+
url={address.backend}
105108
/>
106109
<div className="flex justify-end space-x-2">
107110
<Button

apps/web/components/community/index.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ import { formattedLocaleDate, hasCommunityPermission } from "@ui-lib/utils";
4545
import { MediaItem } from "./media-item";
4646
import Image from "next/image";
4747
import MembershipStatus from "./membership-status";
48-
import { TOAST_TITLE_ERROR, TOAST_TITLE_SUCCESS } from "@ui-config/strings";
48+
import {
49+
MANAGE_LINK_TEXT,
50+
TOAST_TITLE_ERROR,
51+
TOAST_TITLE_SUCCESS,
52+
} from "@ui-config/strings";
4953
import {
5054
DropdownMenu,
5155
DropdownMenuContent,
@@ -60,6 +64,7 @@ import NotFound from "@components/admin/not-found";
6064
import { CommunityInfo } from "./info";
6165
import Banner from "./banner";
6266
import { Textarea } from "@/components/ui/textarea";
67+
import Link from "next/link";
6368
import dynamic from "next/dynamic";
6469

6570
const CreatePostDialog = dynamic(() => import("./create-post-dialog"));
@@ -919,7 +924,13 @@ export function CommunityForum({
919924
{!community?.enabled && (
920925
<div className="bg-red-400 p-2 mb-4 text-sm text-white rounded-md">
921926
This community is not enabled. It is not visible to your
922-
audience (including moderators).
927+
audience (including moderators). {""}
928+
<Link
929+
href={`/dashboard/community/${id}/manage`}
930+
className="underline"
931+
>
932+
{MANAGE_LINK_TEXT}
933+
</Link>
923934
</div>
924935
)}
925936
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">

apps/web/components/ui/sonner.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"use client";
2+
3+
import {
4+
CircleCheck,
5+
Info,
6+
LoaderCircle,
7+
OctagonX,
8+
TriangleAlert,
9+
} from "lucide-react";
10+
import { useTheme } from "next-themes";
11+
import { Toaster as Sonner } from "sonner";
12+
13+
type ToasterProps = React.ComponentProps<typeof Sonner>;
14+
15+
const Toaster = ({ ...props }: ToasterProps) => {
16+
const { theme = "system" } = useTheme();
17+
18+
return (
19+
<Sonner
20+
theme={theme as ToasterProps["theme"]}
21+
className="toaster group"
22+
icons={{
23+
success: <CircleCheck className="h-4 w-4" />,
24+
info: <Info className="h-4 w-4" />,
25+
warning: <TriangleAlert className="h-4 w-4" />,
26+
error: <OctagonX className="h-4 w-4" />,
27+
loading: <LoaderCircle className="h-4 w-4 animate-spin" />,
28+
}}
29+
toastOptions={{
30+
classNames: {
31+
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
32+
description: "group-[.toast]:text-muted-foreground",
33+
actionButton:
34+
"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
35+
cancelButton:
36+
"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
37+
},
38+
}}
39+
{...props}
40+
/>
41+
);
42+
};
43+
44+
export { Toaster };

0 commit comments

Comments
 (0)