From d8414d2d93d57704f7cd373296e5d35b902eac08 Mon Sep 17 00:00:00 2001 From: Rajat Date: Sun, 12 Oct 2025 02:34:39 +0000 Subject: [PATCH 1/8] Removed commented code and deprecated docs --- .../dashboard/(sidebar)/settings/page.tsx | 10 +- .../dashboard/page/[id]/page.tsx | 1 - .../components/admin/page-editor/index.tsx | 46 ------ apps/web/components/admin/settings/index.tsx | 29 ---- docs/widgets.md | 152 ------------------ 5 files changed, 1 insertion(+), 237 deletions(-) delete mode 100644 docs/widgets.md diff --git a/apps/web/app/(with-contexts)/dashboard/(sidebar)/settings/page.tsx b/apps/web/app/(with-contexts)/dashboard/(sidebar)/settings/page.tsx index 7fe42acb4..4111f5776 100644 --- a/apps/web/app/(with-contexts)/dashboard/(sidebar)/settings/page.tsx +++ b/apps/web/app/(with-contexts)/dashboard/(sidebar)/settings/page.tsx @@ -3,11 +3,7 @@ import DashboardContent from "@components/admin/dashboard-content"; import LoadingScreen from "@components/admin/loading-screen"; import Settings from "@components/admin/settings"; -import { - AddressContext, - ProfileContext, - SiteInfoContext, -} from "@components/contexts"; +import { ProfileContext, SiteInfoContext } from "@components/contexts"; import { Profile, UIConstants } from "@courselit/common-models"; import { checkPermission } from "@courselit/utils"; import { SITE_SETTINGS_PAGE_HEADING } from "@ui-config/strings"; @@ -19,7 +15,6 @@ const breadcrumbs = [{ label: SITE_SETTINGS_PAGE_HEADING, href: "#" }]; export default function Page() { const siteinfo = useContext(SiteInfoContext); - const address = useContext(AddressContext); const { profile } = useContext(ProfileContext); const searchParams = useSearchParams(); @@ -37,12 +32,9 @@ export default function Page() { {}} loading={false} - networkAction={false} /> ); diff --git a/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx b/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx index 74ae230eb..09e20e979 100644 --- a/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx +++ b/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx @@ -72,7 +72,6 @@ export default function Page(props: { params: Promise<{ id: string }> }) { action: null, }, }} - dispatch={() => {}} /> ); } diff --git a/apps/web/components/admin/page-editor/index.tsx b/apps/web/components/admin/page-editor/index.tsx index 88f5e1eee..c282dbf3f 100644 --- a/apps/web/components/admin/page-editor/index.tsx +++ b/apps/web/components/admin/page-editor/index.tsx @@ -519,52 +519,6 @@ export default function PageEditor({ [selectedWidget], ); - // const saveDraftTypefaces = async (fontName: string) => { - // const newTypefaces: Typeface[] = structuredClone(draftTypefaces); - // const defaultSection = newTypefaces.filter( - // (x) => x.section === "default", - // )[0]; - // defaultSection.typeface = fontName; - - // const query = ` - // mutation { - // site: updateDraftTypefaces( - // typefaces: ${getGraphQLQueryStringFromObject(newTypefaces)} - // ) { - // draftTypefaces { - // section, - // typeface, - // fontWeights, - // fontSize, - // lineHeight, - // letterSpacing, - // case - // }, - // } - // } - // `; - // const fetch = new FetchBuilder() - // .setUrl(`${address.backend}/api/graph`) - // .setPayload(query) - // .setIsGraphQLEndpoint(true) - // .build(); - // try { - // dispatch && dispatch(networkAction(true)); - // const response = await fetch.exec(); - // if (response.site) { - // setDraftTypefaces(response.site.draftTypefaces); - // } - // } catch (err: any) { - // toast({ - // title: TOAST_TITLE_ERROR, - // description: err.message, - // variant: "destructive", - // }); - // } finally { - // dispatch && dispatch(networkAction(false)); - // } - // }; - const onAddWidgetBelow = (index: number) => { setSelectedWidgetIndex(index); setLeftPaneContent("widgets"); diff --git a/apps/web/components/admin/settings/index.tsx b/apps/web/components/admin/settings/index.tsx index 73d68f462..ea9d79886 100644 --- a/apps/web/components/admin/settings/index.tsx +++ b/apps/web/components/admin/settings/index.tsx @@ -135,35 +135,6 @@ const Settings = (props: SettingsProps) => { loadAdminSettings(); }, []); - // useEffect(() => { - // props.dispatch( - // newSiteInfoAvailable({ - // title: settings.title || "", - // subtitle: settings.subtitle || "", - // logo: settings.logo, - // currencyISOCode: settings.currencyISOCode, - // paymentMethod: settings.paymentMethod, - // stripeKey: settings.stripeKey, - // codeInjectionHead: settings.codeInjectionHead - // ? encode(settings.codeInjectionHead) - // : "", - // codeInjectionBody: settings.codeInjectionBody - // ? encode(settings.codeInjectionBody) - // : "", - // mailingAddress: settings.mailingAddress || "", - // hideCourseLitBranding: settings.hideCourseLitBranding ?? false, - // razorpayKey: settings.razorpayKey, - // lemonsqueezyStoreId: settings.lemonsqueezyStoreId, - // lemonsqueezyOneTimeVariantId: - // settings.lemonsqueezyOneTimeVariantId, - // lemonsqueezySubscriptionMonthlyVariantId: - // settings.lemonsqueezySubscriptionMonthlyVariantId, - // lemonsqueezySubscriptionYearlyVariantId: - // settings.lemonsqueezySubscriptionYearlyVariantId, - // }), - // ); - // }, [settings]); - const loadAdminSettings = async () => { const query = ` query { diff --git a/docs/widgets.md b/docs/widgets.md deleted file mode 100644 index cf71aadd6..000000000 --- a/docs/widgets.md +++ /dev/null @@ -1,152 +0,0 @@ -# Widgets - -We can build custom widgets for CourseLit which can be displayed in the `top`, `bottom`, `aside` or `footer` sections of the application. - -## Sections - -The valid section values are `top`, `bottom`, `aside`, `footerLeft` and `footerRight`. - -## Installing A Widget - -To install a widget follow these steps. - -1. Install the package - -``` -pnpm --filter @courselit/web add my-widget -``` - -2. Now open `ui-config/widget.tsx` file located in `apps/web` and add the widget to the `widgets` section as shown below. - -```js -import mywidget from "my-widget"; - -export default { - widgets: { - // other widgets - [mywidget.metadata.name]: mywidget, - }, -}; -``` - -A CourseLit compatible widget exports an object called `metadata` which contains meta information about the widget. The `metadata` object has a property called `name`. Read more about the structure of a widget below. - -## Structure - -A widget needs to export the following objects in order for it to be detected by CourseLit. The names of the objects should be the same for every widget. - -1. **metadata**: This is a plain JSON object which specifies the configuration of the widget. -2. **widget**: The actual `React` component which will be visible on the public facing site. -3. **adminWidget**: This is an optional `React` component which will be visible in the admin area. This component is used to provide access to the settings and data of the widget to administrators of the app. - -The `widget` and `adminWidget` components receive the following props from the system. - -1. **name**: The name of the widget. This can be used while interacting with the database via GraphQL endpoints (described in the following sections). -2. **settings**: The widget's settings object. -3. **config**: An object containing various configuration settings. Check [this](../apps/web/components/public/base-layout/template/widget-by-name.tsx) file to see what all configurations are available. -4. **section**: A name of the section where the widget is being displayed. As a widget can be displayed in multiple sections (if it supports), you can use this value to adapt the styling of the widget. -5. **state**: The app's state powered by Redux. Equivalent to Redux's `store.getState()`. -6. **dispatch**: The Redux dispatcher. -7. **id**: An identifier to identify widget's data in the app state's `widgetsData` property. - -## Metadata - -The metadata object specifies how the widget is integrated into the system. The following settings are available. - -1. **name**: String. _(Required)_. Any one word string which is used to identify the widget in the system. You have to make sure that this does not conflict with any other widget in the system otherwise the database will be messed up. -2. **displayName**: String. _(Required)_. Any string. This is the name of widget an admin user will see while interacting with it from the dashboard. -3. **compatibleWith**: Array of strings. _(Required)_. An array of strings which specifies the section(s) of the application the widget is compatible with. The available sections are `top`, `bottom`, `aside`, `footerLeft` and `footerRight`. -4. **icon**: String. _(Optional)_. A URL string which points to an image. This will be used as the icon of the widget in the dashboard. If this setting is not provided, the default logo will be used. -5. **excludeFromPaths**: Array of strings. _(Optional)_. By default, once integrated the widget will be visible on every page. If there is a case where we do not want to display the widget on certain pages, the page URLs should be listed here. One can include `Next.js` based dynamic URLs like `/posts/[id]/[slug]` as CourseLit's front-end is based on [Next.js](https://nextjs.org/). - -### Example - -```json -export default { - name: "buttondown", - displayName: "Buttondown", - compatibleWith: ["bottom", "aside"], - icon: "https://buttondown.email/static/images/icons/icon@72.png", - excludeFromPaths: ["/post/[id]/[slug]", "/login"], -}; -``` - -## Saving settings - -A widget can save its settings inside the `Domain` model under the `layout` property. In your `adminWiget` component you can access a prop called `onChange`. You can call this method with the complete settings object for your widget. - -The settings object can be any arbitrary JavaScript object. - -```js -const AdminWidget = (props) => { - const { onChange } = props; - const settings = { - propA: "value", - propB: 1, - }; - - return ( -
- -
- ); -}; -``` - -This will reflect your changes in the `Edit Widget` component. - -## Server Side Rendering (SSR) - -It is recommended to fetch the data required for showing the widget, on the server side. You can request data from CourseLit's GraphQL API by attaching a method called `getData` to your `widget` component. - -While loading the app, all such methods from all the used widgets across the app will be combined and executed as a single query to reduce the round trips to the server. - -The data fetched from the server will be stored in the `widgetsData` property of the app state. Every query will get a unique id in the combined query so that while displaying your widget you can pull out the right data from `widgetsData`. - -The `getData` method has the following signature. - -```js -YourComponent.getData(widgetId: string, widgetSettings: Record) => string; -``` - -You will get a unique `widgetId` from the framework. You have to use this as a key to your query. In your React components (widget and adminWidget) you will get this id in a prop called `id`. - -### Example - -```js -// Fetches courses with a certain tag -Widget.getData = (id: string, settings: Record) => ` - ${id}: getProducts(offset: 1, tag: "${settings && settings.tag}") { - id, - title, - cost, - featuredImage { - thumbnail - }, - slug, - courseId, - isBlog, - description - } -`; -``` - -## Theming - -CourseLit uses [Material-UI's Theming](https://material-ui.com/customization/theming/) system hence you can introduce additional [custom variables](https://material-ui.com/customization/theming/#custom-variables) to the app's theme which you can later consume in your widget. - -> Make sure there is a default styling as other themes may or may not provide the custom variables required by your Widget. - -To learn how to design themes for CourseLit, see this [link](https://codelit.gitbook.io/courselit/administration-1/layout-and-themes#themes). - -## Shared Widgets - -Shared widgets are those whose settings are stored on the domain level, instead of page level. Hence, a user is not required to configure a shared widget individually for every single page it is used on. - -Any page can use a shared widget but the widget's settings are going to be saved and retrieved from the domain. - -⚠️ A shared widget's settings are immediately published and are reflected on all pages. There is no draft mode for shared widgets. - -## Something's Not Clear? - -Come chat with us in our [official Discord channel](https://discord.com/invite/GR4bQsN). From 1ad288e2720fdad5da66f6de33e6d9de876e7863 Mon Sep 17 00:00:00 2001 From: Rajat Date: Sun, 12 Oct 2025 06:49:09 +0000 Subject: [PATCH 2/8] Re-arrange FAQ items --- .../dashboard/page/[id]/page.tsx | 2 +- .../src/blocks/faq/admin-widget/index.tsx | 56 +++++++++++++------ .../blocks/faq/admin-widget/item-editor.tsx | 20 ++++++- .../page-blocks/src/blocks/faq/settings.ts | 1 + .../page-blocks/src/blocks/faq/widget.tsx | 12 +++- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx b/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx index 09e20e979..76502deaa 100644 --- a/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx +++ b/apps/web/app/(with-contexts)/dashboard/page/[id]/page.tsx @@ -44,7 +44,7 @@ export default function Page(props: { params: Promise<{ id: string }> }) { siteinfo: siteInfo, address: address, profile: profile as Profile, - auth: profile.email + auth: profile!.email ? { guest: false, checked: true, diff --git a/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx b/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx index c3638aebd..03ed5deda 100644 --- a/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx +++ b/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx @@ -14,7 +14,11 @@ import { CssIdField, MaxWidthSelector, VerticalPaddingSelector, + DragAndDrop, + IconButton, } from "@courselit/components-library"; +import { Edit } from "@courselit/icons"; +import { generateUniqueId } from "@courselit/utils"; export interface AdminWidgetProps { settings: Settings; @@ -39,7 +43,7 @@ export default function AdminWidget({ hideActionButtons, preservedStateAcrossRerender, theme, -}: AdminWidgetProps): JSX.Element { +}: AdminWidgetProps) { const dummyDescription: Record = { type: "doc", content: [ @@ -82,7 +86,8 @@ export default function AdminWidget({ const [headerAlignment, setHeaderAlignment] = useState( settings.headerAlignment || "center", ); - const [itemBeingEditedIndex, setItemBeingEditedIndex] = useState(-1); + const [itemBeingEditedIndex, setItemBeingEditedIndex] = + useState(-1); const [maxWidth, setMaxWidth] = useState< ThemeStyle["structure"]["page"]["width"] >(settings.maxWidth); @@ -100,6 +105,7 @@ export default function AdminWidget({ maxWidth, verticalPadding, cssId, + itemBeingEditedIndex, }); useEffect(() => { @@ -112,6 +118,7 @@ export default function AdminWidget({ maxWidth, verticalPadding, cssId, + itemBeingEditedIndex, ]); const onItemChange = (newItemData: Item) => { @@ -179,21 +186,36 @@ export default function AdminWidget({ -
    - {items.map((item: Item, index: number) => ( -
  • { - hideActionButtons(true, { - selectedItem: index, - }); - }} - className="p-1 border border-transparent hover:border-slate-300 rounded" - > - {item.title} -
  • - ))} -
+ ({ + item, + id: generateUniqueId(), + }))} + Renderer={({ item }) => ( +
+

{item.title}

+ { + hideActionButtons(true, { + selectedItem: items.findIndex( + (i) => i.title === item.title, + ), + }); + }} + > + + +
+ )} + onChange={(newItems: { item: Item }[]) => { + const itemsInNewOrder: Item[] = []; + for (const item of newItems) { + itemsInNewOrder.push(Object.assign({}, item.item)); + } + setItems(itemsInNewOrder); + }} + />
diff --git a/packages/page-blocks/src/blocks/faq/settings.ts b/packages/page-blocks/src/blocks/faq/settings.ts index 54cbadf9a..f49623f66 100644 --- a/packages/page-blocks/src/blocks/faq/settings.ts +++ b/packages/page-blocks/src/blocks/faq/settings.ts @@ -12,4 +12,5 @@ export default interface Settings extends WidgetDefaultSettings { itemsAlignment: Alignment; items?: Item[]; cssId?: string; + itemBeingEditedIndex?: number; } diff --git a/packages/page-blocks/src/blocks/faq/widget.tsx b/packages/page-blocks/src/blocks/faq/widget.tsx index 5a534448c..187c949ae 100644 --- a/packages/page-blocks/src/blocks/faq/widget.tsx +++ b/packages/page-blocks/src/blocks/faq/widget.tsx @@ -25,8 +25,10 @@ export default function Widget({ cssId, maxWidth, verticalPadding, + itemBeingEditedIndex, }, state, + editing, }: WidgetProps) { const { theme } = state; const overiddenTheme: ThemeStyle = JSON.parse(JSON.stringify(theme.theme)); @@ -34,6 +36,9 @@ export default function Widget({ maxWidth || theme.theme.structure.page.width; overiddenTheme.structure.section.padding.y = verticalPadding || theme.theme.structure.section.padding.y; + const accordionValue = editing + ? `${items[itemBeingEditedIndex]?.title}-${itemBeingEditedIndex}` + : undefined; return (
@@ -64,7 +69,12 @@ export default function Widget({
{items && items.length > 0 && (
- + {items.map((item: Item, index: number) => ( Date: Sun, 12 Oct 2025 09:54:34 +0000 Subject: [PATCH 3/8] FAQ block new layout switcher, re-arranger --- .../src/blocks/faq/admin-widget/index.tsx | 14 ++++++++ .../page-blocks/src/blocks/faq/settings.ts | 1 + .../page-blocks/src/blocks/faq/widget.tsx | 33 ++++++++++++++----- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx b/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx index 03ed5deda..c5e69b412 100644 --- a/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx +++ b/packages/page-blocks/src/blocks/faq/admin-widget/index.tsx @@ -95,6 +95,7 @@ export default function AdminWidget({ ThemeStyle["structure"]["section"]["padding"]["y"] >(settings.verticalPadding); const [cssId, setCssId] = useState(settings.cssId); + const [layout, setLayout] = useState(settings.layout || "vertical"); const onSettingsChanged = () => onChange({ @@ -106,6 +107,7 @@ export default function AdminWidget({ verticalPadding, cssId, itemBeingEditedIndex, + layout, }); useEffect(() => { @@ -119,6 +121,7 @@ export default function AdminWidget({ verticalPadding, cssId, itemBeingEditedIndex, + layout, ]); const onItemChange = (newItemData: Item) => { @@ -232,6 +235,17 @@ export default function AdminWidget({ ]} onChange={(value: Alignment) => setHeaderAlignment(value)} /> + setLayout(value)} + /> + setAlignment(value) + } + /> + )} -
- {hasHeroGraphic && ( -
-
- {isVideo(youtubeLink, media) ? ( - - ) : ( - {media?.caption - )} -
-
- )} + const mainContent = ( +
+ {hasHeroGraphic && (
+ {isVideo(youtubeLink, media) ? ( + + ) : ( + {media?.caption )} +
+
+ )} +
+
+ - + {description && ( +
- {title} - - {description && ( -
- + + +
+ )} +
+ {buttonAction && buttonCaption && ( + +
+ {buttonCaption} + + + )} + {secondaryButtonAction && secondaryButtonCaption && ( + + + )} -
- {buttonAction && buttonCaption && ( - - - - )} - {secondaryButtonAction && - secondaryButtonCaption && ( - - - - )} -
+
+ ); + + return ( +
+ {layout === "normal" ? ( + mainContent + ) : ( + + + {mainContent} + + + )}
); } diff --git a/packages/tailwind-config/tailwind.config.ts b/packages/tailwind-config/tailwind.config.ts index 394e624bf..761f7e703 100644 --- a/packages/tailwind-config/tailwind.config.ts +++ b/packages/tailwind-config/tailwind.config.ts @@ -322,6 +322,7 @@ const config: Config = { variants: ["hover", "disabled", "dark"], }, "transition", + "backdrop-blur-2xl", { pattern: /transition-(all|colors|opacity|shadow|transform|none)/, }, From 111d756058bf9fa0a6b9654f01f3ee851439e912 Mon Sep 17 00:00:00 2001 From: Rajat Date: Mon, 13 Oct 2025 02:32:07 +0000 Subject: [PATCH 5/8] tested: header layout --- .../components/admin/page-editor/index.tsx | 1 + .../src/blocks/header/admin-widget/index.tsx | 2 +- .../src/blocks/header/widget/index.tsx | 35 ++++++++++++------- packages/tailwind-config/tailwind.config.ts | 6 +++- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/apps/web/components/admin/page-editor/index.tsx b/apps/web/components/admin/page-editor/index.tsx index c282dbf3f..1e1e44ae9 100644 --- a/apps/web/components/admin/page-editor/index.tsx +++ b/apps/web/components/admin/page-editor/index.tsx @@ -716,6 +716,7 @@ export default function PageEditor({ onClick={onPublish} size="sm" className="gap-2 whitespace-nowrap" + disabled={loading} > {EDIT_PAGE_BUTTON_UPDATE} diff --git a/packages/page-blocks/src/blocks/header/admin-widget/index.tsx b/packages/page-blocks/src/blocks/header/admin-widget/index.tsx index de76434ec..2e234670d 100644 --- a/packages/page-blocks/src/blocks/header/admin-widget/index.tsx +++ b/packages/page-blocks/src/blocks/header/admin-widget/index.tsx @@ -206,7 +206,7 @@ export default function AdminWidget({

Backdrop blur

- +
diff --git a/packages/page-blocks/src/blocks/header/widget/index.tsx b/packages/page-blocks/src/blocks/header/widget/index.tsx index 9f13ba216..2ce14d585 100644 --- a/packages/page-blocks/src/blocks/header/widget/index.tsx +++ b/packages/page-blocks/src/blocks/header/widget/index.tsx @@ -20,8 +20,6 @@ import { Section, Link as PrimitiveLink, Button, - PageCard, - PageCardContent, } from "@courselit/page-primitives"; import PageLink from "./link"; import clsx from "clsx"; @@ -60,6 +58,8 @@ export default function Widget({ ); stargazers = stargazersCount; } + const cardBorderWidth = + overiddenTheme?.interactives?.card?.border?.width?.split("-")[1]; const mainContent = (
@@ -225,26 +225,35 @@ export default function Widget({ className={clsx( "sticky top-0 z-20", settings.layout === "fixed" - ? settings.backdropBlur - ? "border-b backdrop-blur-2xl bg-transparent" + ? cardBorderWidth + ? `border-b-${cardBorderWidth}` : "border-b" + : "", + settings.layout === "fixed" && + settings.backdropBlur && + "backdrop-blur-2xl", + settings.layout === "fixed" + ? settings.backdropBlur + ? "bg-transparent" + : "bg-background" : "bg-transparent", )} component="header" > {settings.layout === "floating" ? ( - - - {mainContent} - - + {mainContent} +
) : ( mainContent )} diff --git a/packages/tailwind-config/tailwind.config.ts b/packages/tailwind-config/tailwind.config.ts index 761f7e703..4e7a8ccd8 100644 --- a/packages/tailwind-config/tailwind.config.ts +++ b/packages/tailwind-config/tailwind.config.ts @@ -322,7 +322,6 @@ const config: Config = { variants: ["hover", "disabled", "dark"], }, "transition", - "backdrop-blur-2xl", { pattern: /transition-(all|colors|opacity|shadow|transform|none)/, }, @@ -359,6 +358,11 @@ const config: Config = { pattern: /border-(solid|dashed|dotted|double|none)/, variants: ["hover"], }, + "backdrop-blur-2xl", + "border-b", + { + pattern: /border-b-(0|2|4|8)/, + }, { pattern: /shadow-(sm|md|lg|xl|2xl|inner|none)/, variants: ["hover", "dark"], From 4b6c40c2bdfd1b59c9cde9d60dac4c04a36b0cf1 Mon Sep 17 00:00:00 2001 From: Rajat Date: Mon, 13 Oct 2025 03:44:55 +0000 Subject: [PATCH 6/8] header background for existing pages fix --- packages/page-blocks/src/blocks/header/widget/index.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/page-blocks/src/blocks/header/widget/index.tsx b/packages/page-blocks/src/blocks/header/widget/index.tsx index 2ce14d585..fec0e5c4a 100644 --- a/packages/page-blocks/src/blocks/header/widget/index.tsx +++ b/packages/page-blocks/src/blocks/header/widget/index.tsx @@ -60,6 +60,7 @@ export default function Widget({ } const cardBorderWidth = overiddenTheme?.interactives?.card?.border?.width?.split("-")[1]; + const isLayoutFixed = settings.layout === "fixed" || !settings.layout; const mainContent = (
@@ -224,15 +225,13 @@ export default function Widget({ theme={overiddenTheme} className={clsx( "sticky top-0 z-20", - settings.layout === "fixed" + isLayoutFixed ? cardBorderWidth ? `border-b-${cardBorderWidth}` : "border-b" : "", - settings.layout === "fixed" && - settings.backdropBlur && - "backdrop-blur-2xl", - settings.layout === "fixed" + isLayoutFixed && settings.backdropBlur && "backdrop-blur-2xl", + isLayoutFixed ? settings.backdropBlur ? "bg-transparent" : "bg-background" From dc0c75e63ed0aec956d3247ad6fde13306db0026 Mon Sep 17 00:00:00 2001 From: Rajat Date: Mon, 13 Oct 2025 04:19:05 +0000 Subject: [PATCH 7/8] media block border made configurable --- .../src/blocks/media/admin-widget.tsx | 19 +++++ .../page-blocks/src/blocks/media/settings.ts | 1 + .../page-blocks/src/blocks/media/widget.tsx | 72 ++++++++----------- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/packages/page-blocks/src/blocks/media/admin-widget.tsx b/packages/page-blocks/src/blocks/media/admin-widget.tsx index d91db546e..984c49a6f 100644 --- a/packages/page-blocks/src/blocks/media/admin-widget.tsx +++ b/packages/page-blocks/src/blocks/media/admin-widget.tsx @@ -16,9 +16,11 @@ import { Select, MaxWidthSelector, VerticalPaddingSelector, + Tooltip, } from "@courselit/components-library"; import { isVideo } from "@courselit/utils"; import type { Theme, ThemeStyle } from "@courselit/page-models"; +import { Help } from "@courselit/icons"; interface AdminWidgetProps { name: string; @@ -58,6 +60,9 @@ export default function AdminWidget({ const [objectFit, setObjectFit] = useState( settings.objectFit || "cover", ); + const [hasBorder, setHasBorder] = useState( + settings.hasBorder || true, + ); const onSettingsChanged = () => onChange({ @@ -70,6 +75,7 @@ export default function AdminWidget({ playVideoInModal, aspectRatio, objectFit, + hasBorder, }); useEffect(() => { @@ -84,6 +90,7 @@ export default function AdminWidget({ playVideoInModal, aspectRatio, objectFit, + hasBorder, ]); return ( @@ -188,6 +195,18 @@ export default function AdminWidget({ } onChange={setVerticalPadding} /> +
+
+

Border

+ + + +
+ setHasBorder(value)} + /> +
diff --git a/packages/page-blocks/src/blocks/media/settings.ts b/packages/page-blocks/src/blocks/media/settings.ts index d1abb14ed..0c7c3f862 100644 --- a/packages/page-blocks/src/blocks/media/settings.ts +++ b/packages/page-blocks/src/blocks/media/settings.ts @@ -8,4 +8,5 @@ export default interface Settings extends WidgetDefaultSettings { playVideoInModal?: boolean; aspectRatio?: AspectRatio; objectFit?: ImageObjectFit; + hasBorder?: boolean; } diff --git a/packages/page-blocks/src/blocks/media/widget.tsx b/packages/page-blocks/src/blocks/media/widget.tsx index bc5158d8d..de8237fd4 100644 --- a/packages/page-blocks/src/blocks/media/widget.tsx +++ b/packages/page-blocks/src/blocks/media/widget.tsx @@ -30,6 +30,7 @@ export default function Widget({ objectFit, maxWidth, verticalPadding, + hasBorder = true, }, state: { theme }, }: WidgetProps) { @@ -44,49 +45,34 @@ export default function Widget({ return (
- {hasHeroGraphic && ( -
-
- {isVideo(youtubeLink, media) ? ( - - ) : ( - {media?.caption - )} -
-
- )} - {!hasHeroGraphic && ( -
- -
- )} +
+ {isVideo(youtubeLink, media) ? ( + + ) : ( + {media?.caption + )} +
); From aa7b241033754903d673d1b7e54d1e33ca935251 Mon Sep 17 00:00:00 2001 From: Rajat Date: Mon, 13 Oct 2025 09:32:09 +0000 Subject: [PATCH 8/8] Fixed links on checkout and links texts --- .../components/public/payments/login-form.tsx | 17 ++++++++++------- apps/web/graphql/pages/helpers.ts | 4 ++-- packages/common-models/src/constants.ts | 4 ++-- .../src/blocks/footer/admin-widget/index.tsx | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/apps/web/components/public/payments/login-form.tsx b/apps/web/components/public/payments/login-form.tsx index 2ba211c72..0b06f52c8 100644 --- a/apps/web/components/public/payments/login-form.tsx +++ b/apps/web/components/public/payments/login-form.tsx @@ -12,7 +12,6 @@ import { FormItem, FormMessage, } from "@/components/ui/form"; -import Link from "next/link"; import { AddressContext, ProfileContext, @@ -168,19 +167,23 @@ export function LoginForm({ onLoginComplete }: LoginFormProps) { /> By signing in, you accept our{" "} - Terms - {" "} + {" "} and{" "} - Privacy Policy - +