Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/components/admin/page-editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,7 @@ export default function PageEditor({
leftPaneContent === "widgets"
? EDIT_PAGE_ADD_WIDGET_TITLE
: leftPaneContent === "editor"
? "Edit Widget"
? "Edit Block"
: leftPaneContent === "fonts"
? "Fonts"
: leftPaneContent === "theme"
Expand Down
148 changes: 74 additions & 74 deletions apps/web/graphql/pages/logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,91 +265,91 @@ export const getPages = async (
};

export const initMandatoryPages = async (domain: Domain, user: User) => {
await PageModel.insertMany<Page>([
await PageModel.bulkWrite([
{
domain: domain._id,
pageId: defaultPages[0],
type: site,
creatorId: user.userId,
name: pageNames.home,
entityId: domain.name,
layout: [
{
name: "header",
deleteable: false,
shared: true,
},
...homePageTemplate,
{
name: "footer",
deleteable: false,
shared: true,
updateOne: {
filter: { domain: domain._id, pageId: defaultPages[0] },
update: {
$setOnInsert: {
domain: domain._id,
pageId: defaultPages[0],
type: site,
creatorId: user.userId,
name: pageNames.home,
entityId: domain.name,
layout: [
{ name: "header", deleteable: false, shared: true },
...homePageTemplate,
{ name: "footer", deleteable: false, shared: true },
],
draftLayout: [],
},
},
],
draftLayout: [],
upsert: true,
},
},
{
domain: domain._id,
pageId: defaultPages[2],
type: site,
creatorId: user.userId,
name: pageNames.privacy,
entityId: domain.name,
layout: [
{
name: "header",
deleteable: false,
shared: true,
},
{
name: "footer",
deleteable: false,
shared: true,
updateOne: {
filter: { domain: domain._id, pageId: defaultPages[2] },
update: {
$setOnInsert: {
domain: domain._id,
pageId: defaultPages[2],
type: site,
creatorId: user.userId,
name: pageNames.privacy,
entityId: domain.name,
layout: [
{ name: "header", deleteable: false, shared: true },
{ name: "footer", deleteable: false, shared: true },
],
draftLayout: [],
},
},
],
draftLayout: [],
upsert: true,
},
},
{
domain: domain._id,
pageId: defaultPages[1],
type: site,
creatorId: user.userId,
name: pageNames.terms,
entityId: domain.name,
layout: [
{
name: "header",
deleteable: false,
shared: true,
},
{
name: "footer",
deleteable: false,
shared: true,
updateOne: {
filter: { domain: domain._id, pageId: defaultPages[1] },
update: {
$setOnInsert: {
domain: domain._id,
pageId: defaultPages[1],
type: site,
creatorId: user.userId,
name: pageNames.terms,
entityId: domain.name,
layout: [
{ name: "header", deleteable: false, shared: true },
{ name: "footer", deleteable: false, shared: true },
],
draftLayout: [],
},
},
],
draftLayout: [],
upsert: true,
},
},
{
domain: domain._id,
pageId: defaultPages[3],
type: blogPage,
creatorId: user.userId,
name: pageNames.blog,
entityId: domain.name,
layout: [
{
name: "header",
deleteable: false,
shared: true,
},
{
name: "footer",
deleteable: false,
shared: true,
updateOne: {
filter: { domain: domain._id, pageId: defaultPages[3] },
update: {
$setOnInsert: {
domain: domain._id,
pageId: defaultPages[3],
type: blogPage,
creatorId: user.userId,
name: pageNames.blog,
entityId: domain.name,
layout: [
{ name: "header", deleteable: false, shared: true },
{ name: "footer", deleteable: false, shared: true },
],
draftLayout: [],
},
},
],
draftLayout: [],
upsert: true,
},
},
]);
};
Expand Down
13 changes: 6 additions & 7 deletions apps/web/ui-config/widgets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ import {
FAQ,
Pricing,
Media,
Marquee,
Embed,
} from "@courselit/page-blocks";

function loadWidgets(): Record<string, any> {
const widgets: Record<string, Widget> = {};

// Add common widgets to CourseLit
// Adding page blocks to CourseLit
widgets[RichText.metadata.name] = RichText;
widgets[Featured.metadata.name] = Featured;
widgets[Banner.metadata.name] = Banner;
Expand All @@ -27,14 +29,11 @@ function loadWidgets(): Record<string, any> {
widgets[FAQ.metadata.name] = FAQ;
widgets[Pricing.metadata.name] = Pricing;
widgets[Media.metadata.name] = Media;
widgets[Marquee.metadata.name] = Marquee;
widgets[Embed.metadata.name] = Embed;
widgets[EmailForm.metadata.name] = EmailForm;
widgets[Footer.metadata.name] = Object.assign({}, Footer, { shared: true });
widgets[Header.metadata.name] = Object.assign({}, Header, { shared: true });
widgets[EmailForm.metadata.name] = Object.assign({}, EmailForm, {
shared: true,
});

// Additional widgets are added here
// widgets[buttondown.metadata.name] = buttondown;

return widgets;
}
Expand Down
63 changes: 58 additions & 5 deletions packages/components-library/src/admin-widget-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,74 @@
import * as React from "react";
import Section from "./section";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "./components/ui/accordion";

interface AdminWidgetPanelContainerProps {
children: React.ReactNode;
className?: string;
type?: "single" | "multiple";
defaultValue?: string | string[];
}

export function AdminWidgetPanelContainer({
children,
className = "",
type = "multiple",
defaultValue,
}: AdminWidgetPanelContainerProps) {
return (
<div className={`flex flex-col gap-4 mb-4 ${className}`}>
{type === "single" ? (
<Accordion
type="single"
collapsible
defaultValue={defaultValue as string}
>
{children}
</Accordion>
) : (
<Accordion
type="multiple"
defaultValue={defaultValue as string[]}
>
{children}
</Accordion>
)}
</div>
);
}

interface AdminWidgetPanelProps {
title?: string;
children: React.ReactNode;
className?: string;
value: string;
defaultExpanded?: boolean;
}

export default function AdminWidgetPanel({
export function AdminWidgetPanel({
title,
children,
className = "",
value,
}: AdminWidgetPanelProps) {
if (!title) {
// If no title, render as non-collapsible section
return <Section className={className}>{children}</Section>;
}

return (
<Section className={className}>
{title && <h2 className="text-lg font-semibold">{title}</h2>}
{children}
</Section>
<AccordionItem value={value} className={className}>
<AccordionTrigger className="text-base hover:no-underline">
{title}
</AccordionTrigger>
<AccordionContent className="flex flex-col gap-4">
{children}
</AccordionContent>
</AccordionItem>
);
}
62 changes: 62 additions & 0 deletions packages/components-library/src/components/ui/alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "@/lib/utils";

const alertVariants = cva(
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
{
variants: {
variant: {
default: "bg-background text-foreground",
destructive:
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
},
},
defaultVariants: {
variant: "default",
},
},
);

const Alert = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
>(({ className, variant, ...props }, ref) => (
<div
ref={ref}
role="alert"
className={cn(alertVariants({ variant }), className)}
{...props}
/>
));
Alert.displayName = "Alert";

const AlertTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h5
ref={ref}
className={cn(
"mb-1 font-medium leading-none tracking-tight",
className,
)}
{...props}
/>
));
AlertTitle.displayName = "AlertTitle";

const AlertDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("text-sm [&_p]:leading-relaxed", className)}
{...props}
/>
));
AlertDescription.displayName = "AlertDescription";

export { Alert, AlertTitle, AlertDescription };
8 changes: 5 additions & 3 deletions packages/components-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import TextEditor, { emptyDoc as TextEditorEmptyDoc } from "./text-editor";
import TextRenderer from "./text-renderer";
import LessonIcon from "./lesson-icon";
import ColorSelector from "./color-selector";
import AdminWidgetPanel from "./admin-widget-panel";
import Button from "./button";
import IconButton from "./icon-button";
import Form from "./form";
Expand Down Expand Up @@ -41,14 +40,17 @@ import Tooltip from "./tooltip";
import DragAndDrop from "./drag-and-drop";

export { Button as Button2 } from "./components/ui/button";
export * from "./menu";
export * from "./components/ui/avatar";
export * from "./components/ui/accordion";
export * from "./components/ui/slider";
export * from "./components/ui/card";
export * from "./components/ui/badge";
export * from "./components/ui/skeleton";
export * from "./components/ui/textarea";
export * from "./components/ui/alert";

export * from "./admin-widget-panel";
export * from "./menu";
export * from "./toast2";
export * from "./paginated-table";
import getSymbolFromCurrency from "currency-symbol-map";
Expand All @@ -58,6 +60,7 @@ export * from "./video-with-preview";
export * from "./image";
export * from "./vertical-padding-selector";
export * from "./max-width-selector";
export * from "./lib/utils";

export {
PriceTag,
Expand All @@ -72,7 +75,6 @@ export {
TextRenderer,
LessonIcon,
ColorSelector,
AdminWidgetPanel,
Button,
IconButton,
Form,
Expand Down
Loading
Loading