@appcorp/fusion-storybook 0.3.59 → 0.3.61

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.
@@ -7,7 +7,10 @@ export declare const usePushCampaignModule: () => {
7
7
  closeDrawer: () => void;
8
8
  deleteLoading: boolean;
9
9
  handleAiCheck: () => Promise<void>;
10
- handleChange: (field: string, value: string | number | boolean | undefined | null) => void;
10
+ handleChange: (field: string, value: string | number | boolean | undefined | null | Array<{
11
+ classId: string | null;
12
+ sectionId: string | null;
13
+ }>) => void;
11
14
  handleCreate: () => void;
12
15
  handleDelete: (row?: TableRow) => void;
13
16
  handleEdit: (row?: TableRow) => void;
@@ -4,8 +4,13 @@ import { EnhancedInput } from "@appcorp/shadcn/components/enhanced-input";
4
4
  import { EnhancedTextarea } from "@appcorp/shadcn/components/enhanced-textarea";
5
5
  import { EnhancedCheckbox } from "@appcorp/shadcn/components/enhanced-checkbox";
6
6
  import { useTranslations } from "next-intl";
7
+ import { useEffect, useMemo } from "react";
8
+ import { useFetch } from "@react-pakistan/util-functions/hooks/use-fetch";
9
+ import { API_METHODS } from "@react-pakistan/util-functions/constants/api-methods";
7
10
  import { usePushCampaignModule } from "./context";
8
11
  import { getTranslatedError } from "../../utils/get-translated-error";
12
+ import { CLASS_API_ROUTES, SECTION_API_ROUTES } from "../../constants";
13
+ import { getCachedWorkspaceSync } from "../workspace/cache";
9
14
  const getMinScheduleDatetime = () => {
10
15
  const d = new Date();
11
16
  d.setHours(d.getHours() + 1);
@@ -15,7 +20,61 @@ const getMinScheduleDatetime = () => {
15
20
  export const PushCampaignForm = () => {
16
21
  const t = useTranslations("pushCampaign");
17
22
  const context = usePushCampaignModule();
18
- const { allStudents, body, errors, enabled, name, scheduledAt, status, title, aiCheckLoading, aiCheckPassed, aiCheckScore, aiSuggestions, } = context.state;
23
+ const { allStudents, audience, body, errors, enabled, name, scheduledAt, status, title, aiCheckLoading, aiCheckPassed, aiCheckScore, aiSuggestions, } = context.state;
19
24
  const { handleAiCheck, handleChange, } = context;
20
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "name", t }), id: "name", info: t("formNameInfo"), label: t("formNameLabel"), onChange: (e) => handleChange("name", e.target.value), placeholder: t("formNamePlaceholder"), required: true, value: name }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "title", t }), id: "title", info: t("formTitleInfo"), label: t("formTitleLabel"), maxLength: 100, onChange: (e) => handleChange("title", e.target.value), placeholder: t("formTitlePlaceholder"), required: true, value: title }), _jsx(EnhancedTextarea, { error: getTranslatedError({ errors, key: "body", t }), id: "body", info: t("formBodyInfo"), label: t("formBodyLabel"), maxLength: 300, onChange: (e) => handleChange("body", e.target.value), placeholder: t("formBodyPlaceholder"), required: true, rows: 4, value: body }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "scheduledAt", t }), id: "scheduledAt", info: t("formScheduledAtInfo"), label: t("formScheduledAtLabel"), min: getMinScheduleDatetime(), onChange: (e) => handleChange("scheduledAt", e.target.value), required: true, type: "datetime-local", value: scheduledAt })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAudience") }), _jsx(EnhancedCheckbox, { checked: allStudents, info: t("formAllStudentsInfo"), label: t("formAllStudentsLabel"), onCheckedChange: (checked) => handleChange("allStudents", checked) })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAiReview") }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("button", { className: "rounded bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50", disabled: aiCheckLoading || !title || !body, onClick: handleAiCheck, type: "button", children: aiCheckLoading ? t("aiCheckRunning") : t("aiCheckButton") }), aiCheckScore !== null && (_jsxs("span", { className: "text-sm font-medium", children: [t("aiCheckScore"), ": ", Math.round(aiCheckScore), "/10", aiCheckPassed ? " ✅" : " ❌"] }))] }), aiSuggestions && (_jsx("p", { className: "text-sm text-muted-foreground whitespace-pre-wrap", children: aiSuggestions }))] }), status && (_jsx("div", { className: "space-y-4", children: _jsx(EnhancedInput, { id: "status", label: t("formStatusLabel"), value: status, disabled: true }) })), _jsx(EnhancedCheckbox, { checked: enabled, info: t("formEnabledInfo"), label: t("formEnabledLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
25
+ const workspace = getCachedWorkspaceSync();
26
+ const { fetchNow: classFetchNow, data: classData } = useFetch(CLASS_API_ROUTES.UNIT, { method: API_METHODS.GET, params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id } });
27
+ const { fetchNow: sectionFetchNow, data: sectionData } = useFetch(SECTION_API_ROUTES.UNIT, { method: API_METHODS.GET, params: { workspaceId: workspace === null || workspace === void 0 ? void 0 : workspace.id } });
28
+ useEffect(() => {
29
+ if (workspace === null || workspace === void 0 ? void 0 : workspace.id) {
30
+ classFetchNow();
31
+ sectionFetchNow();
32
+ }
33
+ }, [workspace === null || workspace === void 0 ? void 0 : workspace.id]);
34
+ const classes = (classData === null || classData === void 0 ? void 0 : classData.items) || [];
35
+ const sections = (sectionData === null || sectionData === void 0 ? void 0 : sectionData.items) || [];
36
+ const sectionsByClass = useMemo(() => {
37
+ const map = {};
38
+ sections.forEach((s) => {
39
+ var _a;
40
+ const classId = (_a = s.class) === null || _a === void 0 ? void 0 : _a.id;
41
+ if (classId) {
42
+ if (!map[classId])
43
+ map[classId] = [];
44
+ map[classId].push(s);
45
+ }
46
+ });
47
+ return map;
48
+ }, [sections]);
49
+ const isClassChecked = (classId) => audience.some((a) => a.classId === classId);
50
+ const isSectionChecked = (classId, sectionId) => audience.some((a) => a.classId === classId && a.sectionId === sectionId);
51
+ const handleClassToggle = (classId, checked) => {
52
+ if (checked) {
53
+ handleChange("audience", [...audience, { classId, sectionId: null }]);
54
+ }
55
+ else {
56
+ handleChange("audience", audience.filter((a) => a.classId !== classId));
57
+ }
58
+ };
59
+ const handleSectionToggle = (classId, sectionId, checked) => {
60
+ if (checked) {
61
+ const withoutAllSections = audience.filter((a) => !(a.classId === classId && a.sectionId === null));
62
+ handleChange("audience", [
63
+ ...withoutAllSections,
64
+ { classId, sectionId },
65
+ ]);
66
+ }
67
+ else {
68
+ const filtered = audience.filter((a) => !(a.classId === classId && a.sectionId === sectionId));
69
+ if (!filtered.some((a) => a.classId === classId)) {
70
+ filtered.push({ classId, sectionId: null });
71
+ }
72
+ handleChange("audience", filtered);
73
+ }
74
+ };
75
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-4", children: [_jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "name", t }), id: "name", info: t("formNameInfo"), label: t("formNameLabel"), onChange: (e) => handleChange("name", e.target.value), placeholder: t("formNamePlaceholder"), required: true, value: name }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "title", t }), id: "title", info: t("formTitleInfo"), label: t("formTitleLabel"), maxLength: 100, onChange: (e) => handleChange("title", e.target.value), placeholder: t("formTitlePlaceholder"), required: true, value: title }), _jsx(EnhancedTextarea, { error: getTranslatedError({ errors, key: "body", t }), id: "body", info: t("formBodyInfo"), label: t("formBodyLabel"), maxLength: 300, onChange: (e) => handleChange("body", e.target.value), placeholder: t("formBodyPlaceholder"), required: true, rows: 4, value: body }), _jsx(EnhancedInput, { error: getTranslatedError({ errors, key: "scheduledAt", t }), id: "scheduledAt", info: t("formScheduledAtInfo"), label: t("formScheduledAtLabel"), min: getMinScheduleDatetime(), onChange: (e) => handleChange("scheduledAt", e.target.value), onClick: (e) => { var _a, _b; return (_b = (_a = e.target) === null || _a === void 0 ? void 0 : _a.showPicker) === null || _b === void 0 ? void 0 : _b.call(_a); }, required: true, type: "datetime-local", value: scheduledAt })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAudience") }), _jsx(EnhancedCheckbox, { checked: allStudents, info: t("formAllStudentsInfo"), label: t("formAllStudentsLabel"), onCheckedChange: (checked) => handleChange("allStudents", checked) }), !allStudents && (_jsxs("div", { className: "space-y-3 rounded-md border p-3", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: t("formAudienceSelectLabel") }), _jsxs("div", { className: "space-y-2", children: [classes.map((cls) => {
76
+ const classSections = sectionsByClass[cls.id];
77
+ const checked = isClassChecked(cls.id);
78
+ return (_jsxs("div", { className: "space-y-1", children: [_jsx(EnhancedCheckbox, { checked: checked, label: `${cls.name} (${cls.code})`, onCheckedChange: (c) => handleClassToggle(cls.id, c) }), checked && classSections && classSections.length > 0 && (_jsx("div", { className: "ml-7 space-y-1 border-l-2 pl-3", children: classSections.map((sec) => (_jsx(EnhancedCheckbox, { checked: isSectionChecked(cls.id, sec.id), label: sec.name, onCheckedChange: (c) => handleSectionToggle(cls.id, sec.id, c) }, sec.id))) }))] }, cls.id));
79
+ }), classes.length === 0 && (_jsx("p", { className: "text-sm text-muted-foreground", children: t("formAudienceNoClasses") }))] })] }))] }), _jsxs("div", { className: "space-y-4", children: [_jsx("h3", { className: "text-lg font-semibold", children: t("formSectionAiReview") }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("button", { className: "rounded bg-primary px-4 py-2 text-primary-foreground disabled:opacity-50", disabled: aiCheckLoading || !title || !body, onClick: handleAiCheck, type: "button", children: aiCheckLoading ? t("aiCheckRunning") : t("aiCheckButton") }), aiCheckScore !== null && (_jsxs("span", { className: "text-sm font-medium", children: [t("aiCheckScore"), ": ", Math.round(aiCheckScore), "/10", aiCheckPassed ? " ✅" : " ❌"] }))] }), aiSuggestions && (_jsx("p", { className: "text-sm text-muted-foreground whitespace-pre-wrap", children: aiSuggestions }))] }), status && (_jsx("div", { className: "space-y-4", children: _jsx(EnhancedInput, { id: "status", label: t("formStatusLabel"), value: status, disabled: true }) })), _jsx(EnhancedCheckbox, { checked: enabled, info: t("formEnabledInfo"), label: t("formEnabledLabel"), onCheckedChange: (checked) => handleChange("enabled", checked) })] }));
21
80
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appcorp/fusion-storybook",
3
- "version": "0.3.59",
3
+ "version": "0.3.61",
4
4
  "scripts": {
5
5
  "build-storybook": "storybook build",
6
6
  "build:next": "next build",
@@ -37,7 +37,7 @@
37
37
  ]
38
38
  },
39
39
  "devDependencies": {
40
- "@appcorp/shadcn": "^2.0.5",
40
+ "@appcorp/shadcn": "^2.0.6",
41
41
  "@chromatic-com/storybook": "^5.1.2",
42
42
  "@commitlint/cli": "^20.5.0",
43
43
  "@commitlint/config-conventional": "^20.5.0",