@opexa/portal-components 0.0.117 → 0.0.118

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ import type { CustomPromo as TCustomPromo } from '../../types';
2
+ export interface CustomPromoProps {
3
+ promo: TCustomPromo;
4
+ viewAllPromosUrl?: string;
5
+ className?: string;
6
+ }
7
+ export declare function CustomPromo(props: CustomPromoProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import Image from 'next/image';
4
+ import Link from 'next/link';
5
+ import { ChevronLeftIcon } from '../../icons/ChevronLeftIcon.js';
6
+ import { Prose } from '../../ui/Prose/index.js';
7
+ export function CustomPromo(props) {
8
+ return (_jsxs("div", { className: props.className, children: [_jsxs(Link, { href: props.viewAllPromosUrl ?? '/promos', className: "text-button-tertiary-fg flex w-fit items-center gap-lg text-lg font-semibold", children: [_jsx(ChevronLeftIcon, { className: "size-6" }), "Back to all Promotions"] }), _jsx(Image, { src: props.promo.banner, alt: "", width: 1024, height: 600, className: "mt-xl h-auto w-full rounded-xl lg:mt-6" }), _jsx("h1", { className: "mt-xl text-2xl font-semibold lg:mt-6 lg:text-3xl", children: props.promo.name }), _jsx(Prose, { className: "mt-2xl lg:mt-6", dangerouslySetInnerHTML: {
9
+ __html: props.promo.description,
10
+ } })] }));
11
+ }
@@ -0,0 +1 @@
1
+ export * from './CustomPromo';
@@ -0,0 +1 @@
1
+ export * from './CustomPromo.js';
@@ -3,5 +3,5 @@ interface CashbackProps {
3
3
  data: TCashback;
4
4
  viewDetailsUrl: string;
5
5
  }
6
- export declare function Cashback({ data, viewDetailsUrl, }: CashbackProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function Cashback({ data, viewDetailsUrl }: CashbackProps): import("react/jsx-runtime").JSX.Element;
7
7
  export {};
@@ -5,7 +5,7 @@ import { useShallow } from 'zustand/shallow';
5
5
  import { useAvailablePromosQuery } from '../../client/hooks/useAvailablePromosQuery.js';
6
6
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
7
7
  import { Button } from '../../ui/Button/index.js';
8
- export function Cashback({ data, viewDetailsUrl = '/promos/cashback', }) {
8
+ export function Cashback({ data, viewDetailsUrl }) {
9
9
  const globalStore = useGlobalStore(useShallow((ctx) => ({
10
10
  depositWithdrawal: ctx.depositWithdrawal,
11
11
  })));
@@ -0,0 +1,7 @@
1
+ import type { CustomPromo } from '../../types';
2
+ interface CustomPromoProps {
3
+ data: CustomPromo;
4
+ viewDetailsUrl: string;
5
+ }
6
+ export declare function CustomPromo({ data, viewDetailsUrl }: CustomPromoProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Image from 'next/image';
3
+ import Link from 'next/link';
4
+ import { Button } from '../../ui/Button/index.js';
5
+ export function CustomPromo({ data, viewDetailsUrl }) {
6
+ return (_jsxs("div", { className: "border-border-secondary bg-accent-50 bg-bg-primary-alt relative flex h-full flex-col overflow-hidden rounded-2xl border", children: [_jsx(Image, { src: data.banner, alt: data.name, width: 1200, height: 500, priority: true, className: "block aspect-[365/180] w-full object-cover" }), _jsxs("div", { className: "flex flex-grow flex-col px-4 pb-3xl pt-2xl", children: [_jsx("div", { className: "w-full grow text-center text-xl font-semibold", children: data.name }), _jsx("div", { className: "mt-auto flex flex-col gap-3 pt-4 lg:flex-row", children: _jsx(Button, { size: "sm", variant: "outline", asChild: true, children: _jsx(Link, { href: `${viewDetailsUrl}/${data.id}`, children: "Read more" }) }) })] })] }));
7
+ }
@@ -5,7 +5,7 @@ import { useShallow } from 'zustand/shallow';
5
5
  import { useAvailablePromosQuery } from '../../client/hooks/useAvailablePromosQuery.js';
6
6
  import { useGlobalStore } from '../../client/hooks/useGlobalStore.js';
7
7
  import { Button } from '../../ui/Button/index.js';
8
- export function Promo({ data, viewDetailsUrl = '/promos' }) {
8
+ export function Promo({ data, viewDetailsUrl }) {
9
9
  const globalStore = useGlobalStore(useShallow((ctx) => ({
10
10
  depositWithdrawal: ctx.depositWithdrawal,
11
11
  })));
@@ -1,3 +1,4 @@
1
+ import type { CustomPromo as TCustomPromo } from '../../types';
1
2
  export interface PromosCarouselProps {
2
3
  layout: 'carousel';
3
4
  /** @default "Promotions" */
@@ -8,6 +9,17 @@ export interface PromosCarouselProps {
8
9
  viewPromoDetailsUrl?: string;
9
10
  /** @default "/promos/cashback" */
10
11
  viewCashbackDetailsUrl?: string;
12
+ /** @default "/promos/custom" */
13
+ viewCustomPromoDetailsUrl?: string;
14
+ customPromos?: TCustomPromo[];
15
+ /**
16
+ * @description List of promo IDs to be excluded from the list.
17
+ * @example
18
+ * ```ts
19
+ * exclude={['12345']}
20
+ * ```
21
+ */
22
+ exclude?: string[];
11
23
  className?: string;
12
24
  }
13
25
  export declare function PromosCarousel(props: PromosCarouselProps): import("react/jsx-runtime").JSX.Element;
@@ -13,13 +13,16 @@ import { Gift01Icon } from '../../icons/Gift01Icon.js';
13
13
  import { Button } from '../../ui/Button/index.js';
14
14
  import { Empty } from '../shared/Empty.js';
15
15
  import { Cashback } from './Cashback.js';
16
+ import { CustomPromo } from './CustomPromo.js';
16
17
  import { Promo } from './Promo.js';
17
18
  export function PromosCarousel(props) {
18
19
  const promosQuery = usePromosQuery();
19
20
  const cashbacksQuery = useCashbacksQuery();
20
- const promos = promosQuery.data ?? [];
21
- const cashbacks = cashbacksQuery.data ?? [];
22
- const empty = promos.length <= 0 && cashbacks.length <= 0;
21
+ const blacklist = props.exclude ?? [];
22
+ const promos = promosQuery.data?.filter((item) => !blacklist.includes(item.id)) ?? [];
23
+ const cashbacks = cashbacksQuery.data?.filter((item) => !blacklist.includes(item.id)) ?? [];
24
+ const customPromos = props.customPromos?.filter((item) => !blacklist.includes(item.id)) ?? [];
25
+ const empty = promos.length <= 0 && cashbacks.length <= 0 && customPromos.length <= 0;
23
26
  const [emblaRef, emblaApi] = useEmblaCarousel({
24
27
  align: 'start',
25
28
  slidesToScroll: 1,
@@ -45,5 +48,5 @@ export function PromosCarousel(props) {
45
48
  onSelect(emblaApi);
46
49
  emblaApi.on('reInit', onSelect).on('select', onSelect);
47
50
  }, [emblaApi, onSelect]);
48
- return (_jsxs("div", { className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Promotions' }), _jsx("div", { className: "grow" }), _jsxs("div", { className: "flex items-center justify-center gap-xl", children: [_jsxs(Link, { href: props.viewAllUrl ?? '/promos', className: "text-button-tertiary-fg flex gap-sm text-sm font-semibold", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", onClick: onPrevButtonClick, disabled: prevBtnDisabled, "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-l-none", onClick: onNextButtonClick, disabled: nextBtnDisabled, "aria-label": "Next", children: _jsx(ArrowRightIcon, { className: "size-5" }) })] })] })] }), empty && (_jsx(Empty, { icon: Gift01Icon, title: "No Promos", message: "No promo is currently available.", className: "mt-8" })), !empty && (_jsx(_Fragment, { children: _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsxs("div", { className: twMerge('grid auto-cols-[100%] grid-flow-col gap-1.5 lg:auto-cols-[calc((100%-(1.25rem*2))/3)] lg:gap-2xl'), children: [promos.map((promo) => (_jsx(Promo, { data: promo, viewDetailsUrl: props.viewPromoDetailsUrl ?? '/promos' }, promo.id))), cashbacks.map((cashback) => (_jsx(Cashback, { data: cashback, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/cashback' }, cashback.id)))] }) }) }))] }));
51
+ return (_jsxs("div", { className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Promotions' }), _jsx("div", { className: "grow" }), _jsxs("div", { className: "flex items-center justify-center gap-xl", children: [_jsxs(Link, { href: props.viewAllUrl ?? '/promos', className: "text-button-tertiary-fg flex gap-sm text-sm font-semibold", children: ["See All", _jsx(ChevronRightIcon, { className: "size-5 lg:hidden" })] }), _jsxs("div", { className: "hidden lg:flex", children: [_jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-r-none border-r-0", onClick: onPrevButtonClick, disabled: prevBtnDisabled, "aria-label": "Previous", children: _jsx(ArrowLeftIcon, { className: "size-5" }) }), _jsx(Button, { variant: "outline", colorScheme: "gray", className: "rounded-l-none", onClick: onNextButtonClick, disabled: nextBtnDisabled, "aria-label": "Next", children: _jsx(ArrowRightIcon, { className: "size-5" }) })] })] })] }), empty && (_jsx(Empty, { icon: Gift01Icon, title: "No Promos", message: "No promo is currently available.", className: "mt-8" })), !empty && (_jsx(_Fragment, { children: _jsx("div", { ref: emblaRef, className: "relative mt-lg lg:overflow-hidden", children: _jsxs("div", { className: twMerge('grid auto-cols-[100%] grid-flow-col gap-1.5 lg:auto-cols-[calc((100%-(1.25rem*2))/3)] lg:gap-2xl'), children: [promos.map((promo) => (_jsx(Promo, { data: promo, viewDetailsUrl: props.viewPromoDetailsUrl ?? '/promos' }, promo.id))), cashbacks.map((cashback) => (_jsx(Cashback, { data: cashback, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/cashback' }, cashback.id))), customPromos.map((customPromo) => (_jsx(CustomPromo, { data: customPromo, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/custom' }, customPromo.id)))] }) }) }))] }));
49
52
  }
@@ -1,3 +1,4 @@
1
+ import type { CustomPromo as TCustomPromo } from '../../types';
1
2
  export interface PromosGridProps {
2
3
  layout: 'grid';
3
4
  /** @default "Promotions" */
@@ -6,6 +7,8 @@ export interface PromosGridProps {
6
7
  viewPromoDetailsUrl?: string;
7
8
  /** @default "/promos/cashback" */
8
9
  viewCashbackDetailsUrl?: string;
10
+ customPromos?: TCustomPromo[];
11
+ exclude?: string[];
9
12
  className?: string;
10
13
  }
11
14
  export declare function PromosGrid(props: PromosGridProps): import("react/jsx-runtime").JSX.Element;
@@ -3,15 +3,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCashbacksQuery } from '../../client/hooks/useCashbacksQuery.js';
4
4
  import { usePromosQuery } from '../../client/hooks/usePromosQuery.js';
5
5
  import { Cashback } from './Cashback.js';
6
+ import { CustomPromo } from './CustomPromo.js';
6
7
  import { Promo } from './Promo.js';
7
8
  export function PromosGrid(props) {
8
9
  const promosQuery = usePromosQuery();
9
10
  const cashbacksQuery = useCashbacksQuery();
10
- const promos = promosQuery.data ?? [];
11
- const cashbacks = cashbacksQuery.data ?? [];
12
- const empty = promos.length <= 0 && cashbacks.length <= 0;
11
+ const blacklist = props.exclude ?? [];
12
+ const promos = promosQuery.data?.filter((item) => !blacklist.includes(item.id)) ?? [];
13
+ const cashbacks = cashbacksQuery.data?.filter((item) => !blacklist.includes(item.id)) ?? [];
14
+ const customPromos = props.customPromos?.filter((item) => !blacklist.includes(item.id)) ?? [];
15
+ const empty = promos.length <= 0 && cashbacks.length <= 0 && customPromos.length <= 0;
13
16
  if (empty) {
14
17
  return (_jsx("div", { className: props.className, children: _jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Promos' }), _jsx("div", { className: "grow" })] }) }));
15
18
  }
16
- return (_jsxs("div", { className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Promos' }), _jsx("div", { className: "grow" })] }), _jsx("div", { className: "relative mt-lg lg:overflow-hidden", children: _jsxs("div", { className: "grid gap-3xl lg:grid-cols-3 lg:gap-2xl", children: [promos.map((promo) => (_jsx(Promo, { data: promo, viewDetailsUrl: props.viewPromoDetailsUrl ?? '/promos' }, promo.id))), cashbacks.map((cashback) => (_jsx(Cashback, { data: cashback, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/cashback' }, cashback.id)))] }) })] }));
19
+ return (_jsxs("div", { className: props.className, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("h2", { className: "text-lg font-semibold", children: props.heading ?? 'Promos' }), _jsx("div", { className: "grow" })] }), _jsx("div", { className: "relative mt-lg lg:overflow-hidden", children: _jsxs("div", { className: "grid gap-3xl lg:grid-cols-3 lg:gap-2xl", children: [promos.map((promo) => (_jsx(Promo, { data: promo, viewDetailsUrl: props.viewPromoDetailsUrl ?? '/promos' }, promo.id))), cashbacks.map((cashback) => (_jsx(Cashback, { data: cashback, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/cashback' }, cashback.id))), customPromos.map((customPromo) => (_jsx(CustomPromo, { data: customPromo, viewDetailsUrl: props.viewCashbackDetailsUrl ?? '/promos/custom' }, customPromo.id)))] }) })] }));
17
20
  }
@@ -835,4 +835,11 @@ export interface News {
835
835
  content: string;
836
836
  category: string;
837
837
  }
838
+ export interface CustomPromo {
839
+ id: string;
840
+ type: 'CUSTOM';
841
+ name: string;
842
+ banner: string;
843
+ description: string;
844
+ }
838
845
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opexa/portal-components",
3
- "version": "0.0.117",
3
+ "version": "0.0.118",
4
4
  "exports": {
5
5
  "./ui/*": {
6
6
  "types": "./dist/ui/*/index.d.ts",