Skip to content

Commit

Permalink
New dashboard (#523)
Browse files Browse the repository at this point in the history
* WIP: session, address and siteinfo fetched

* WIP: Sidebar without products and mails

* WIP: /blog ported

* WIP: porting products dashboard

* Most page ported

* Almost all parts ported

* Prettier fixes

* CodeQL fixes

* Ported invite customer screen

* Shadcn's New Sidebar for dashboard

* Lint fix

* break fixes

* Fixed the truncate function

* WIP: Page builder ported to Dashboard 4

* Check for undefined

* Merged Lesson loading

* lint changes

* New yarn.lock

* Missing string added

* Ported section editing screen

* Lesson loading state fix

* Lint fixes

* Injected config into Dashboard4

* Removed unused import

* Lint fixes

* multiple email forms can work on one page

* Button is enabled while editing

* Page editor sync icon fixed for new dashboard

* Fixed: Cloudflare turnstile loading in email form widget while editing

* Fixed: broadcasting filters

---------

Co-authored-by: Rajat Saxena <[email protected]>
  • Loading branch information
rajat1saxena and Rajat Saxena authored Nov 18, 2024
1 parent fbca787 commit 8da6503
Show file tree
Hide file tree
Showing 394 changed files with 7,165 additions and 1,790 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 3 additions & 1 deletion apps/web/app/dashboard2/blog/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ import { useContext } from "react";
export default function Page() {
const address = useContext(AddressContext);

return <NewBlog address={address} networkAction={false} />;
return (
<NewBlog address={address} networkAction={false} prefix="/dashboard2" />
);
}
5 changes: 3 additions & 2 deletions apps/web/app/dashboard2/blogs/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export async function generateMetadata(
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${MANAGE_BLOG_PAGE_HEADING} | ${(await parent)?.title
?.absolute}`,
title: `${MANAGE_BLOG_PAGE_HEADING} | ${
(await parent)?.title?.absolute
}`,
};
}

Expand Down
9 changes: 8 additions & 1 deletion apps/web/app/dashboard2/blogs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@ export default function Page() {
return <LoadingScreen />;
}

return <Blogs address={address} loading={false} siteinfo={siteinfo} />;
return (
<Blogs
address={address}
loading={false}
siteinfo={siteinfo}
prefix="/dashboard2"
/>
);
}
5 changes: 3 additions & 2 deletions apps/web/app/dashboard2/pages/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export async function generateMetadata(
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${MANAGE_PAGES_PAGE_HEADING} | ${(await parent)?.title
?.absolute}`,
title: `${MANAGE_PAGES_PAGE_HEADING} | ${
(await parent)?.title?.absolute
}`,
};
}

Expand Down
9 changes: 8 additions & 1 deletion apps/web/app/dashboard2/pages/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,12 @@ export default function Page() {
return <LoadingScreen />;
}

return <Pages address={address} loading={false} dispatch={() => {}} />;
return (
<Pages
address={address}
loading={false}
dispatch={() => {}}
prefix="/dashboard2"
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default function Page({
address={address}
profile={profile as Profile}
prefix="/dashboard2"
isNew={true}
/>
);
}
8 changes: 7 additions & 1 deletion apps/web/app/dashboard2/product/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ import { useContext } from "react";
export default function Page() {
const address = useContext(AddressContext);

return <NewProduct address={address} networkAction={false} />;
return (
<NewProduct
address={address}
networkAction={false}
prefix="/dashboard2"
/>
);
}
5 changes: 3 additions & 2 deletions apps/web/app/dashboard2/products/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export async function generateMetadata(
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${MANAGE_COURSES_PAGE_HEADING} | ${(await parent)?.title
?.absolute}`,
title: `${MANAGE_COURSES_PAGE_HEADING} | ${
(await parent)?.title?.absolute
}`,
};
}

Expand Down
9 changes: 8 additions & 1 deletion apps/web/app/dashboard2/products/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@ export default function Page() {
return <LoadingScreen />;
}

return <Products address={address} loading={false} siteinfo={siteinfo} />;
return (
<Products
address={address}
loading={false}
siteinfo={siteinfo}
prefix="/dashboard2"
/>
);
}
5 changes: 3 additions & 2 deletions apps/web/app/dashboard2/settings/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export async function generateMetadata(
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${SITE_SETTINGS_PAGE_HEADING} | ${(await parent)?.title
?.absolute}`,
title: `${SITE_SETTINGS_PAGE_HEADING} | ${
(await parent)?.title?.absolute
}`,
};
}

Expand Down
6 changes: 3 additions & 3 deletions apps/web/app/dashboard2/users/users-hub.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
TableBody,
TableHead,
TableRow,
Tabs,
Tabbs,
} from "@courselit/components-library";
import { checkPermission, FetchBuilder } from "@courselit/utils";
import {
Expand Down Expand Up @@ -172,7 +172,7 @@ export default function UsersHub() {
</div>
)}
</div>
<Tabs
<Tabbs
items={["All users", "Tags"]}
value={tab}
onChange={(tab: string) => {
Expand Down Expand Up @@ -258,7 +258,7 @@ export default function UsersHub() {
</Table>
</div>
<Tags address={address} prefix="/dashboard2" />
</Tabs>
</Tabbs>
</div>
);
}
16 changes: 16 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blog/[id]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Metadata, ResolvingMetadata } from "next";
import { ReactNode } from "react";
import { EDIT_BLOG } from "@ui-config/strings";

export async function generateMetadata(
{ params }: { params: any },
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${EDIT_BLOG} | ${(await parent)?.title?.absolute}`,
};
}

export default function Layout({ children }: { children: ReactNode }) {
return children;
}
116 changes: 116 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blog/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"use client";

import useCourse from "@components/admin/blogs/editor/course-hook";
import { Details } from "@components/admin/blogs/editor/details";
import { Publish } from "@components/admin/blogs/editor/publish";
import { deleteProduct } from "@components/admin/blogs/helpers";
import DashboardContent from "@components/admin/dashboard-content";
import { AddressContext, ProfileContext } from "@components/contexts";
import {
Link,
Menu2,
MenuItem,
Skeleton,
Tabbs,
} from "@courselit/components-library";
import { MoreVert } from "@courselit/icons";
import {
DELETE_PRODUCT_POPUP_HEADER,
DELETE_PRODUCT_POPUP_TEXT,
EDIT_BLOG,
MANAGE_BLOG_PAGE_HEADING,
MENU_BLOG_VISIT,
PAGE_TITLE_404,
PRODUCT_TABLE_CONTEXT_MENU_DELETE_PRODUCT,
} from "@ui-config/strings";
import { truncate } from "@ui-lib/utils";
import { Profile } from "next-auth";
import { useRouter, useSearchParams } from "next/navigation";
import { useContext, useState } from "react";

const breadcrumbs = [
{ label: MANAGE_BLOG_PAGE_HEADING, href: "/dashboard4/blogs" },
{ label: EDIT_BLOG, href: "#" },
];

export default function Page({ params }: { params: { id: string } }) {
const { id } = params;
const searchParams = useSearchParams();
const [tab, setTab] = useState(searchParams?.get("tab") || "Details");
const address = useContext(AddressContext);
const profile = useContext(ProfileContext);
const course = useCourse(id, address);
const router = useRouter();

return (
<DashboardContent breadcrumbs={breadcrumbs}>
{course === undefined && (
<div className="flex flex-col gap-4">
<Skeleton className="h-10 w-full" />
<Skeleton className="h-20 w-full" />
</div>
)}
{course === null && <p>{PAGE_TITLE_404}</p>}
{course && (
<>
<div className="flex justify-between items-center">
<h1 className="text-4xl font-semibold mb-4">
{truncate(course?.title || "", 50)}
</h1>
<div>
<Menu2 icon={<MoreVert />} variant="soft">
<MenuItem>
<Link
href={`/blog/${course?.slug}/${course?.courseId}`}
className="flex w-full"
>
{MENU_BLOG_VISIT}
</Link>
</MenuItem>
<MenuItem
component="dialog"
title={DELETE_PRODUCT_POPUP_HEADER}
triggerChildren={
PRODUCT_TABLE_CONTEXT_MENU_DELETE_PRODUCT
}
description={DELETE_PRODUCT_POPUP_TEXT}
onClick={() =>
deleteProduct({
id: course!.id as string,
backend: address.backend,
onDeleteComplete: () => {
router.replace(
`/dashboard4/blogs`,
);
},
})
}
></MenuItem>
</Menu2>
</div>
</div>
<Tabbs
items={["Details", "Publish"]}
value={tab}
onChange={setTab}
>
<div className="pt-4">
<Details
id={id as string}
address={address}
profile={profile as Profile}
/>
</div>
<div className="pt-4">
<Publish
id={id}
address={address}
loading={false}
/>
</div>
</Tabbs>
</>
)}
</DashboardContent>
);
}
23 changes: 23 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blog/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use client";

import LoadingScreen from "@components/admin/loading-screen";
import { ProfileContext } from "@components/contexts";
import { UIConstants } from "@courselit/common-models";
import { checkPermission } from "@courselit/utils";
import { ReactNode, useContext } from "react";
const { permissions } = UIConstants;

export default function Page({ children }: { children: ReactNode }) {
const profile = useContext(ProfileContext);

if (
!checkPermission(profile.permissions!, [
permissions.manageAnyCourse,
permissions.manageCourse,
])
) {
return <LoadingScreen />;
}

return children;
}
26 changes: 26 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blog/new/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use client";

import { NewBlog } from "@components/admin/blogs/new-blog";
import DashboardContent from "@components/admin/dashboard-content";
import { AddressContext } from "@components/contexts";
import { BTN_NEW_BLOG, MANAGE_BLOG_PAGE_HEADING } from "@ui-config/strings";
import { useContext } from "react";

const breadcrumbs = [
{ label: MANAGE_BLOG_PAGE_HEADING, href: "/dashboard4/blogs" },
{ label: BTN_NEW_BLOG, href: "#" },
];

export default function Page() {
const address = useContext(AddressContext);

return (
<DashboardContent breadcrumbs={breadcrumbs}>
<NewBlog
address={address}
networkAction={false}
prefix="/dashboard4"
/>
</DashboardContent>
);
}
18 changes: 18 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blogs/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { MANAGE_BLOG_PAGE_HEADING } from "@ui-config/strings";
import type { Metadata, ResolvingMetadata } from "next";
import { ReactNode } from "react";

export async function generateMetadata(
_: any,
parent: ResolvingMetadata,
): Promise<Metadata> {
return {
title: `${MANAGE_BLOG_PAGE_HEADING} | ${
(await parent)?.title?.absolute
}`,
};
}

export default function Layout({ children }: { children: ReactNode }) {
return children;
}
43 changes: 43 additions & 0 deletions apps/web/app/dashboard4/(sidebar)/blogs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

import { Index as Blogs } from "@components/admin/blogs";
import DashboardContent from "@components/admin/dashboard-content";
import LoadingScreen from "@components/admin/loading-screen";
import {
AddressContext,
ProfileContext,
SiteInfoContext,
} from "@components/contexts";
import { UIConstants } from "@courselit/common-models";
import { checkPermission } from "@courselit/utils";
import { MANAGE_BLOG_PAGE_HEADING } from "@ui-config/strings";
import { useContext } from "react";
const { permissions } = UIConstants;

const breadcrumbs = [{ label: MANAGE_BLOG_PAGE_HEADING, href: "#" }];

export default function Page() {
const address = useContext(AddressContext);
const profile = useContext(ProfileContext);
const siteinfo = useContext(SiteInfoContext);

if (
!checkPermission(profile.permissions!, [
permissions.manageAnyCourse,
permissions.manageCourse,
])
) {
return <LoadingScreen />;
}

return (
<DashboardContent breadcrumbs={breadcrumbs}>
<Blogs
address={address}
loading={false}
siteinfo={siteinfo}
prefix="/dashboard4"
/>
</DashboardContent>
);
}
Loading

0 comments on commit 8da6503

Please sign in to comment.