@donotdev/templates 0.0.4 → 0.0.6

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,66 @@
1
+ /**
2
+
3
+ * @fileoverview Admin Landing Template Component
4
+
5
+ * @description Reusable admin login/landing page template with auth providers, loading state, and support links
6
+
7
+ *
8
+
9
+ * @version 0.0.1
10
+
11
+ * @since 0.0.1
12
+
13
+ * @author AMBROISE PARK Consulting
14
+
15
+ */
16
+ import { type ReactNode } from 'react';
17
+ export interface AdminLandingTemplateProps {
18
+ /** Page title (e.g., "Admin Login") */
19
+ title: string;
20
+ /** Page subtitle (e.g., "Car Inventory & CRM Management System") */
21
+ subtitle?: string;
22
+ /** Message section with title and content */
23
+ message?: {
24
+ title: string;
25
+ content: string;
26
+ };
27
+ /** Support/contact link configuration */
28
+ supportLink?: {
29
+ label?: string;
30
+ path?: string;
31
+ };
32
+ /** Public website link configuration */
33
+ publicWebsiteLink?: {
34
+ label?: string;
35
+ path?: string;
36
+ };
37
+ /** Redirect configuration */
38
+ redirectConfig?: {
39
+ condition: (user: any) => boolean;
40
+ redirectTo: string;
41
+ };
42
+ /** Additional content to render below auth providers */
43
+ children?: ReactNode;
44
+ }
45
+ /**
46
+
47
+ * AdminLandingTemplate - Reusable admin login/landing page
48
+
49
+ *
50
+
51
+ * Handles loading state, redirect logic, and displays auth providers with support links.
52
+
53
+ * Uses AppConfig for default link values (support link and public website URL).
54
+
55
+ *
56
+
57
+ * @version 0.0.1
58
+
59
+ * @since 0.0.1
60
+
61
+ * @author AMBROISE PARK Consulting
62
+
63
+ */
64
+ export declare function AdminLandingTemplate({ title, subtitle, message, supportLink, publicWebsiteLink, redirectConfig, children, }: AdminLandingTemplateProps): import("react/jsx-runtime").JSX.Element | null;
65
+ export default AdminLandingTemplate;
66
+ //# sourceMappingURL=AdminLandingTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminLandingTemplate.d.ts","sourceRoot":"","sources":["../src/AdminLandingTemplate.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgBlD,MAAM,WAAW,yBAAyB;IACxC,uCAAuC;IAEvC,KAAK,EAAE,MAAM,CAAC;IAEd,oEAAoE;IAEpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,6CAA6C;IAE7C,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QAEd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF,yCAAyC;IAEzC,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IAEF,wCAAwC;IAExC,iBAAiB,CAAC,EAAE;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IAEF,6BAA6B;IAE7B,cAAc,CAAC,EAAE;QACf,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;QAElC,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,wDAAwD;IAExD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AAEH,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EAEL,QAAQ,EAER,OAAO,EAEP,WAAW,EAEX,iBAAiB,EAEjB,cAAc,EAEd,QAAQ,GACT,EAAE,yBAAyB,kDAkG3B;AAED,eAAe,oBAAoB,CAAC"}
@@ -0,0 +1 @@
1
+ "use client";import{jsx as t,Fragment as x,jsxs as a}from"react/jsx-runtime";import{useEffect as y}from"react";import{HeroSection as z,Section as T,Text as j,Stack as L}from"@donotdev/components";import{useTranslation as C,useAppConfig as P}from"@donotdev/core";import{PageContainer as A,useNavigate as W,useRedirectGuard as _,Loader as k,Link as f}from"@donotdev/ui";import{MultipleAuthProviders as F}from"@donotdev/auth";function R({title:m,subtitle:h,message:i,supportLink:s,publicWebsiteLink:c,redirectConfig:l,children:g}){const{t:d}=C("dndev"),p=W(),u=P("app"),{shouldRedirect:n,redirectTo:e,isChecking:v}=_({condition:l?.condition,redirectTo:l?.redirectTo});if(y(()=>{n&&e&&p(e,{replace:!0})},[n,e,p]),v)return t(k,{});if(n&&e)return null;const o=s?.path||u?.links?.support,r=c?.path||u?.url,b=s?.label||d("adminLanding.contactSupport","Contact Support"),S=c?.label||d("adminLanding.visitWebsite","Visit Website");return a(A,{children:[t(z,{title:m,subtitle:h,variant:"primary"}),i&&t(T,{title:i.title,align:"center",children:t(j,{as:"p",level:"body",children:i.content})}),t(F,{}),g,(o||r)&&a(L,{direction:"row",gap:"tight",justify:"center",align:"center",children:[o&&a(x,{children:[t(f,{path:o,style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:b}),r&&t("span",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:" | "})]}),r&&t(f,{path:r,style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)"},children:S})]})]})}var V=R;export{R as AdminLandingTemplate,V as default};
@@ -1,27 +1,9 @@
1
- import type { ComponentType } from 'react';
2
1
  export interface MarkdownViewerProps {
3
- /** Pre-parsed HTML (from getStaticProps) */
4
- html?: string;
5
- /** Raw markdown content (parses on client) */
2
+ /** Raw markdown content */
6
3
  content?: string;
7
4
  /** Additional CSS classes */
8
5
  className?: string;
9
6
  }
10
- /**
11
- * MarkdownViewer - Renders markdown content using framework components
12
- *
13
- * Features:
14
- * - Accepts pre-parsed HTML (Next.js SSR) or raw markdown (client-side)
15
- * - Code blocks use framework Code component (Shiki syntax highlighting)
16
- * - Links use framework Link component (internal) or <a> (external)
17
- * - Framework prose typography
18
- * - Theme-aware styling
19
- * - 100% Lighthouse compliant
20
- *
21
- * @version 0.0.1
22
- * @since 0.0.1
23
- * @author AMBROISE PARK Consulting
24
- */
25
- export declare const MarkdownViewer: ComponentType<MarkdownViewerProps>;
7
+ export declare const MarkdownViewer: import("react").NamedExoticComponent<MarkdownViewerProps>;
26
8
  export default MarkdownViewer;
27
9
  //# sourceMappingURL=MarkdownViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownViewer.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownViewer.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,OAAO,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,mBAAmB,CA2V7D,CAAC;AAEF,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"MarkdownViewer.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownViewer.tsx"],"names":[],"mappings":"AAyBA,MAAM,WAAW,mBAAmB;IAClC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiFD,eAAO,MAAM,cAAc,2DAA2B,CAAC;AACvD,eAAe,cAAc,CAAC"}
@@ -1 +1 @@
1
- "use client";import{jsx as r}from"react/jsx-runtime";import{marked as M}from"marked";import{useMemo as g}from"react";import{Code as x,cn as b}from"@donotdev/components";import{isClient as v}from"@donotdev/core";import{Link as T}from"@donotdev/ui";const B=({html:d,content:l,className:p})=>{const m=g(()=>{if(d)return d;if(!l||!v())return"";try{const i=M.parse(l);return typeof i=="string"?i:i.toString()}catch{return""}},[d,l]),c=g(()=>{if(!m)return null;const f=new DOMParser().parseFromString(m,"text/html").body,h=s=>{if(s.nodeType===Node.TEXT_NODE)return s.textContent;if(s.nodeType!==Node.ELEMENT_NODE)return null;const o=s,y=o.tagName.toLowerCase(),e=Array.from(o.childNodes).map(h).filter(Boolean);switch(y){case"pre":{const t=o.querySelector("code");if(!t)return null;const a=t.textContent||"",u=t.className.replace("language-","")||"text";return r(x,{language:u,children:a},Math.random())}case"a":{const t=o.getAttribute("href")||"",a=o.textContent||"";return t.startsWith("http")||t.startsWith("//")?r("a",{href:t,target:"_blank",rel:"noopener noreferrer",style:{color:"var(--primary)",textDecoration:"none"},onMouseEnter:n=>{n.currentTarget.style.textDecoration="underline"},onMouseLeave:n=>{n.currentTarget.style.textDecoration="none"},children:a},Math.random()):r(T,{path:t,style:{color:"var(--primary)",textDecoration:"none"},onMouseEnter:n=>{n.currentTarget.style.textDecoration="underline"},onMouseLeave:n=>{n.currentTarget.style.textDecoration="none"},children:a},Math.random())}case"h1":return r("h1",{style:{fontSize:"var(--font-size-3xl)",fontWeight:700,marginTop:"2rem",marginBottom:"1rem"},children:e},Math.random());case"h2":return r("h2",{style:{fontSize:"var(--font-size-2xl)",fontWeight:700,marginTop:"1.5rem",marginBottom:"0.75rem"},children:e},Math.random());case"h3":return r("h3",{style:{fontSize:"var(--font-size-xl)",fontWeight:600,marginTop:"1rem",marginBottom:"0.5rem"},children:e},Math.random());case"h4":return r("h4",{style:{fontSize:"var(--font-size-lg)",fontWeight:600,marginTop:"0.75rem",marginBottom:"0.5rem"},children:e},Math.random());case"p":return r("p",{style:{marginBottom:"1rem",lineHeight:1.6},children:e},Math.random());case"ul":return r("ul",{style:{listStyleType:"disc",listStylePosition:"inside",marginBottom:"1rem",display:"grid",gap:"var(--gap-sm)"},children:e},Math.random());case"ol":return r("ol",{style:{listStyleType:"decimal",listStylePosition:"inside",marginBottom:"1rem",display:"grid",gap:"var(--gap-sm)"},children:e},Math.random());case"li":return r("li",{children:e},Math.random());case"blockquote":return r("blockquote",{style:{borderLeft:"4px solid var(--primary)",paddingLeft:"1rem",fontStyle:"italic",marginTop:"1rem",marginBottom:"1rem"},children:e},Math.random());case"code":return r("code",{style:{backgroundColor:"var(--muted)",paddingLeft:"0.375rem",paddingRight:"0.375rem",paddingTop:"0.125rem",paddingBottom:"0.125rem",borderRadius:"var(--radius-lg)",fontSize:"var(--font-size-sm)",fontFamily:"monospace"},children:o.textContent},Math.random());case"strong":case"b":return r("strong",{children:e},Math.random());case"em":case"i":return r("em",{children:e},Math.random());case"img":{const t=o.getAttribute("src")||"",a=o.getAttribute("alt")||"";return r("img",{src:t,alt:a,className:"dndev-w-full",style:{maxWidth:"100%",height:"auto",marginTop:"1rem",marginBottom:"1rem",borderRadius:"var(--radius-lg)"},loading:"lazy"},Math.random())}case"table":return r("div",{className:"dndev-overflow-x-hidden",style:{marginTop:"1rem",marginBottom:"1rem"},children:r("table",{style:{minWidth:"100%",borderCollapse:"collapse",border:"1px solid var(--border)"},children:e})},Math.random());case"thead":return r("thead",{children:e},Math.random());case"tbody":return r("tbody",{children:e},Math.random());case"tr":return r("tr",{style:{borderBottom:"1px solid var(--border)"},children:e},Math.random());case"th":return r("th",{style:{border:"1px solid var(--border)",padding:"0.5rem 1rem",textAlign:"left",fontWeight:600,backgroundColor:"var(--muted)"},children:e},Math.random());case"td":return r("td",{style:{border:"1px solid var(--border)",padding:"0.5rem 1rem"},children:e},Math.random());case"hr":return r("hr",{style:{marginTop:"2rem",marginBottom:"2rem",borderColor:"var(--border)"}},Math.random());default:return r("div",{children:e},Math.random())}};return Array.from(f.childNodes).map(h).filter(Boolean)},[m]);return c?r("div",{className:b(p),style:{maxWidth:"none"},children:c}):null};var D=B;export{B as MarkdownViewer,D as default};
1
+ "use client";import{jsx as s}from"react/jsx-runtime";import{memo as p,useMemo as h}from"react";import{marked as x}from"marked";import g,{domToReact as k,Element as a}from"html-react-parser";import{Code as w,cn as b}from"@donotdev/components";import{Link as E}from"@donotdev/ui";function m(n){let o="";for(const r of n.children)r.type==="text"?o+=r.data:r instanceof a&&(o+=m(r));return o}const M=({content:n,className:o})=>{const r=h(()=>{if(!n)return null;const d=x.parse(n,{async:!1,gfm:!0,breaks:!0});return g(d,{replace(i){if(!(i instanceof a))return;const{name:c,attribs:u,children:f}=i;if(c==="pre"){const e=f.find(t=>t instanceof a&&t.name==="code");if(e){const t=/language-(\w+)/.exec(e.attribs?.class||"")?.[1]||"text";return s(w,{language:t,children:m(e).replace(/\n$/,"")})}}if(c==="a"){const e=u?.href||"",t=e.startsWith("http")||e.startsWith("//"),l=k(f);return t?s("a",{href:e,target:"_blank",rel:"noopener noreferrer",children:l}):s(E,{path:e,children:l})}}})},[n]);return r?s("div",{className:b("prose",o),children:r}):null},j=p(M);var B=j;export{j as MarkdownViewer,B as default};
@@ -1 +1 @@
1
- {"version":3,"file":"EntityFormTemplate.d.ts","sourceRoot":"","sources":["../../src/crud/EntityFormTemplate.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAgB7B,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,gBAAgB,CAAC;AAqDxB;;;;;GAKG;AACH,UAAU,uBAAuB,CAAC,OAAO,SAAS,WAAW,CAAC,GAAG,CAAC;IAChE,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA6HD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,WAAW,CAAC,GAAG,CAAC,EAAE,EACnE,MAAM,EACN,WAAW,EACX,QAAQ,EACR,SAAS,GACV,EAAE,uBAAuB,CAAC,OAAO,CAAC,2CAublC;AAED,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"EntityFormTemplate.d.ts","sourceRoot":"","sources":["../../src/crud/EntityFormTemplate.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAe7B,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,gBAAgB,CAAC;AAmDxB;;;;;GAKG;AACH,UAAU,uBAAuB,CAAC,OAAO,SAAS,WAAW,CAAC,GAAG,CAAC;IAChE,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7C,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA6HD;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,SAAS,WAAW,CAAC,GAAG,CAAC,EAAE,EACnE,MAAM,EACN,WAAW,EACX,QAAQ,EACR,SAAS,GACV,EAAE,uBAAuB,CAAC,OAAO,CAAC,2CAodlC;AAED,eAAe,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- "use client";import{jsx as p,jsxs as u}from"react/jsx-runtime";import{valibotResolver as U}from"@hookform/resolvers/valibot";import{useReducer as j,useEffect as N,useCallback as h}from"react";import{useForm as k}from"react-hook-form";import"valibot";import{Card as z,Button as E,BUTTON_VARIANT as R,Progress as B,Badge as F,BADGE_VARIANT as I,Alert as M,ALERT_VARIANT as $,Stack as v,Grid as G}from"@donotdev/components";import{useTranslation as J,handleError as O}from"@donotdev/core";import{useNavigate as q}from"@donotdev/ui";import{FormFieldRenderer as K}from"@donotdev/crud";function W(n,o){switch(o.type){case"SET_CURRENT_STEP":return{...n,currentStep:o.payload};case"SET_STEP_ERRORS":return{...n,stepErrors:o.payload};case"SET_FORM_DATA":return{...n,formData:o.payload};case"SET_LAST_SAVED":return{...n,lastSaved:o.payload};case"SET_IS_SAVING":return{...n,isSaving:o.payload};case"RESET_FORM":return{currentStep:0,stepErrors:[],formData:{},lastSaved:null,isSaving:!1};default:return n}}import{ChevronLeft as Y,ChevronRight as H,Save as Q,CheckCircle as X}from"lucide-react";function Z(n,o,y){const c=new Set,a=new Set;return n.forEach(l=>{(Array.isArray(l.condition)?l.condition:[l.condition]).every(r=>{const e=o[r.field];switch(r.operator){case"equals":return e===r.value;case"not-equals":return e!==r.value;case"contains":return String(e).includes(String(r.value));case"greater-than":return e>r.value;case"less-than":return e<r.value;case"exists":return e!=null&&e!=="";case"not-exists":return e==null||e==="";default:return r.evaluate?r.evaluate(o):!1}})&&(l.showFields?.forEach(r=>c.add(r)),l.hideFields?.forEach(r=>c.delete(r)),l.disableFields?.forEach(r=>a.add(r)),l.enableFields?.forEach(r=>a.delete(r)))}),{visibleFields:c,disabledFields:a}}function ee(n,o,y,c){const a=n[o];if(!a)return[];let l=[...a.fields];if(c){const{visibleFields:f,disabledFields:S}=Z(c,y,o);l=l.filter(r=>f.has(r)||f.size===0)}return l}function te(n,o,y){const c=[];if(n.fields.forEach(a=>{const l=o[a],f=y.entries;if(!f)return;const S=f[a];S&&S.type==="optional"||(l==null||l==="")&&c.push(`${a} is required`)}),n.validation?.validate){const a=n.validation.validate(o);a!==!0&&c.push(n.validation.message||String(a))}return{isValid:c.length===0,errors:c}}function re({schema:n,initialData:o,onSubmit:y,isLoading:c}){const{t:a}=J(),l=q(),f=!!(o&&"id"in o&&o.id),{collection:S,entity:r}=n.metadata,e=n.metadata.form||{type:"single"},[t,m]=j(W,{currentStep:0,stepErrors:[],formData:o||{},lastSaved:null,isSaving:!1}),d=k({resolver:U(n),defaultValues:o}),w=n.entries||{},T=Object.entries(w).map(([s,i])=>{try{return{name:s,type:"text",label:s,validation:{},options:{},visibility:"user"}}catch(g){return O(g,`Failed to process field configuration for ${s}`),{name:s,type:"text",label:s,validation:{},options:{},visibility:"user"}}});N(()=>{if(!e.persist||!e.persistence?.autoSaveInterval)return;const s=setInterval(async()=>{const i=d.getValues();JSON.stringify(i)!==JSON.stringify(t.formData)&&await _(i)},e.persistence.autoSaveInterval);return()=>clearInterval(s)},[e.persist,e.persistence?.autoSaveInterval,d,t.formData]);const _=h(async s=>{if(e.persist)try{m({type:"SET_IS_SAVING",payload:!0});const i=e.persistence?.key||`form-draft-${S}`;localStorage.setItem(i,JSON.stringify({data:s,timestamp:new Date().toISOString(),step:t.currentStep})),m({type:"SET_FORM_DATA",payload:s}),m({type:"SET_LAST_SAVED",payload:new Date})}catch{}finally{m({type:"SET_IS_SAVING",payload:!1})}},[e.persist,e.persistence?.key,S,t.currentStep]),b=h(()=>{if(e.persist)try{const s=e.persistence?.key||`form-draft-${S}`,i=localStorage.getItem(s);if(i){const{data:g,step:L}=JSON.parse(i);d.reset(g),m({type:"SET_FORM_DATA",payload:g}),e.type==="multi-step"&&e.steps&&m({type:"SET_CURRENT_STEP",payload:Math.min(L,e.steps.length-1)})}}catch{}},[e.persist,e.persistence?.key,S,d,e.type,e.steps]);N(()=>{f||b()},[f,b]);const C=h(()=>e.type==="multi-step"&&e.steps?ee(e.steps,t.currentStep,d.getValues(),e.rules):T.map(s=>s.name),[e.type,e.steps,e.rules,t.currentStep,d,T]),x=h(async()=>{if(!e.steps||t.currentStep>=e.steps.length-1)return;const s=e.steps[t.currentStep];if(!s)return;const i=d.getValues(),g=te(s,i,n);if(!g.isValid){m({type:"SET_STEP_ERRORS",payload:g.errors});return}m({type:"SET_STEP_ERRORS",payload:[]}),m({type:"SET_CURRENT_STEP",payload:t.currentStep+1})},[e.steps,t.currentStep,d,n]),V=h(()=>{t.currentStep>0&&(m({type:"SET_CURRENT_STEP",payload:t.currentStep-1}),m({type:"SET_STEP_ERRORS",payload:[]}))},[t.currentStep]),D=d.handleSubmit(async s=>{try{if(e.persist){const i=e.persistence?.key||`form-draft-${S}`;localStorage.removeItem(i)}await y(s)}catch(i){O(i,f?a("error.update.entity",{entity:r}):a("error.create.entity",{entity:r}))}}),A=e.type==="multi-step"&&e.steps?(t.currentStep+1)/e.steps.length*100:0,P=e.steps?.[t.currentStep];return p(v,{gap:"medium",children:u(z,{title:u(v,{direction:"row",align:"center",justify:"between",children:[u("div",{children:[p("div",{style:{fontSize:"var(--font-size-xl)",fontWeight:600},children:f?a("edit.entity",{entity:r}):a("create.entity",{entity:r})}),e.type==="multi-step"&&e.steps&&u("p",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)",marginTop:"var(--gap-sm)"},children:["Step ",t.currentStep+1," of ",e.steps.length,":"," ",P?.title]})]}),e.persist&&e.persistence?.showSaveIndicator&&p(v,{direction:"row",align:"center",gap:"tight",children:t.isSaving?p(F,{variant:I.SECONDARY,children:"Saving..."}):t.lastSaved?u(F,{variant:I.OUTLINE,className:"dndev-flex dndev-items-center dndev-gap-sm",children:[p(X,{className:"dndev-size-md"}),"Saved ",t.lastSaved.toLocaleTimeString()]}):null})]}),children:[e.type==="multi-step"&&e.behavior?.showProgress&&u("div",{style:{marginTop:"var(--gap-md)"},children:[p(B,{value:A,style:{height:"0.5rem"}}),u(v,{direction:"row",justify:"between",style:{marginTop:"var(--gap-sm)",fontSize:"var(--font-size-xs)",color:"var(--muted-foreground)"},children:[u("span",{children:[Math.round(A),"% complete"]}),u("span",{children:["Step ",t.currentStep+1," of"," ",e.steps?.length||0]})]})]}),t.stepErrors.length>0&&p(M,{variant:$.ERROR,description:p(v,{as:"ul",gap:"tight",style:{listStyle:"disc",listStylePosition:"inside"},children:t.stepErrors.map((s,i)=>p("li",{children:s},i))}),style:{marginBottom:"var(--gap-lg)"}}),p("form",{onSubmit:D,children:u(v,{gap:"large",children:[p(G,{cols:3,gap:"large",className:"dndev-grid-responsive-1-2-3",children:C().map(s=>{const i=T.find(g=>g.name===s);return i?p(K,{name:i.name,control:d.control,errors:d.formState.errors,config:i,t:a},i.name):null})}),u(v,{direction:"row",justify:"between",align:"center",style:{paddingTop:"var(--gap-lg)",borderTop:"1px solid var(--border)"},children:[u(v,{direction:"row",gap:"tight",children:[e.type==="multi-step"&&t.currentStep>0&&p(E,{type:"button",variant:R.OUTLINE,onClick:V,className:"dndev-gap-sm",icon:Y,children:"Previous"}),p(E,{type:"button",variant:R.OUTLINE,onClick:()=>l(`/${S}`),children:a("cancel")})]}),u(v,{direction:"row",gap:"tight",children:[e.persist&&p(E,{type:"button",variant:R.OUTLINE,onClick:()=>_(d.getValues()),disabled:t.isSaving,className:"dndev-gap-sm",icon:Q,children:"Save Draft"}),e.type==="multi-step"&&e.steps&&t.currentStep<e.steps.length-1&&p(E,{type:"button",onClick:x,className:"dndev-gap-sm",icon:H,iconEnd:!0,children:"Next"}),(e.type==="single"||e.type==="multi-step"&&e.steps&&t.currentStep===e.steps.length-1)&&p(E,{type:"submit",disabled:c||d.formState.isSubmitting,children:a(f?"update":"create")})]})]})]})})]})})}var Se=re;export{re as EntityFormTemplate,Se as default};
1
+ "use client";import{jsx as l,jsxs as u}from"react/jsx-runtime";import{useReducer as U,useEffect as N,useCallback as h}from"react";import{useForm as z}from"react-hook-form";import{ChevronLeft as B,ChevronRight as M,Save as $,CheckCircle as G}from"lucide-react";import{valibotResolver as J}from"@hookform/resolvers/valibot";import"valibot";import{Card as q,Button as E,BUTTON_VARIANT as R,Progress as K,Badge as F,BADGE_VARIANT as O,Alert as I,ALERT_VARIANT as w,Stack as y,Grid as W}from"@donotdev/components";import{useTranslation as Y,handleError as C}from"@donotdev/core";import{useNavigate as H}from"@donotdev/ui";import{FormFieldRenderer as Q}from"@donotdev/crud";function X(a,o){switch(o.type){case"SET_CURRENT_STEP":return{...a,currentStep:o.payload};case"SET_STEP_ERRORS":return{...a,stepErrors:o.payload};case"SET_FORM_DATA":return{...a,formData:o.payload};case"SET_LAST_SAVED":return{...a,lastSaved:o.payload};case"SET_IS_SAVING":return{...a,isSaving:o.payload};case"RESET_FORM":return{currentStep:0,stepErrors:[],formData:{},lastSaved:null,isSaving:!1};default:return a}}function Z(a,o,v){const d=new Set,i=new Set;return a.forEach(c=>{(Array.isArray(c.condition)?c.condition:[c.condition]).every(n=>{const e=o[n.field];switch(n.operator){case"equals":return e===n.value;case"not-equals":return e!==n.value;case"contains":return String(e).includes(String(n.value));case"greater-than":return e>n.value;case"less-than":return e<n.value;case"exists":return e!=null&&e!=="";case"not-exists":return e==null||e==="";default:return n.evaluate?n.evaluate(o):!1}})&&(c.showFields?.forEach(n=>d.add(n)),c.hideFields?.forEach(n=>d.delete(n)),c.disableFields?.forEach(n=>i.add(n)),c.enableFields?.forEach(n=>i.delete(n)))}),{visibleFields:d,disabledFields:i}}function ee(a,o,v,d){const i=a[o];if(!i)return[];let c=[...i.fields];if(d){const{visibleFields:S,disabledFields:f}=Z(d,v,o);c=c.filter(n=>S.has(n)||S.size===0)}return c}function te(a,o,v){const d=[];if(a.fields.forEach(i=>{const c=o[i],S=v.entries;if(!S)return;const f=S[i];f&&f.type==="optional"||(c==null||c==="")&&d.push(`${i} is required`)}),a.validation?.validate){const i=a.validation.validate(o);i!==!0&&d.push(a.validation.message||String(i))}return{isValid:d.length===0,errors:d}}function re({schema:a,initialData:o,onSubmit:v,isLoading:d}){const{t:i}=Y(),c=H(),S=!!(o&&"id"in o&&o.id),{collection:f,entity:n}=a.metadata,e=a.metadata.form||{type:"single"},[r,m]=U(X,{currentStep:0,stepErrors:[],formData:o||{},lastSaved:null,isSaving:!1}),p=z({resolver:J(a),defaultValues:o}),x=a.entries||{},T=Object.entries(x).map(([t,s])=>{try{return{name:t,type:"text",label:t,validation:{},options:{},visibility:"user"}}catch(g){return C(g,`Failed to process field configuration for ${t}`),{name:t,type:"text",label:t,validation:{},options:{},visibility:"user"}}});N(()=>{if(!e.persist||!e.persistence?.autoSaveInterval)return;const t=setInterval(async()=>{const s=p.getValues();JSON.stringify(s)!==JSON.stringify(r.formData)&&await _(s)},e.persistence.autoSaveInterval);return()=>clearInterval(t)},[e.persist,e.persistence?.autoSaveInterval,p,r.formData]);const _=h(async t=>{if(e.persist)try{m({type:"SET_IS_SAVING",payload:!0});const s=e.persistence?.key||`form-draft-${f}`;localStorage.setItem(s,JSON.stringify({data:t,timestamp:new Date().toISOString(),step:r.currentStep})),m({type:"SET_FORM_DATA",payload:t}),m({type:"SET_LAST_SAVED",payload:new Date})}catch{}finally{m({type:"SET_IS_SAVING",payload:!1})}},[e.persist,e.persistence?.key,f,r.currentStep]),b=h(()=>{if(e.persist)try{const t=e.persistence?.key||`form-draft-${f}`,s=localStorage.getItem(t);if(s){const{data:g,step:L}=JSON.parse(s);p.reset(g),m({type:"SET_FORM_DATA",payload:g}),e.type==="multi-step"&&e.steps&&m({type:"SET_CURRENT_STEP",payload:Math.min(L,e.steps.length-1)})}}catch{}},[e.persist,e.persistence?.key,f,p,e.type,e.steps]);N(()=>{S||b()},[S,b]);const V=h(()=>e.type==="multi-step"&&e.steps?ee(e.steps,r.currentStep,p.getValues(),e.rules):T.map(t=>t.name),[e.type,e.steps,e.rules,r.currentStep,p,T]),D=h(async()=>{if(!e.steps||r.currentStep>=e.steps.length-1)return;const t=e.steps[r.currentStep];if(!t)return;const s=p.getValues(),g=te(t,s,a);if(!g.isValid){m({type:"SET_STEP_ERRORS",payload:g.errors});return}m({type:"SET_STEP_ERRORS",payload:[]}),m({type:"SET_CURRENT_STEP",payload:r.currentStep+1})},[e.steps,r.currentStep,p,a]),P=h(()=>{r.currentStep>0&&(m({type:"SET_CURRENT_STEP",payload:r.currentStep-1}),m({type:"SET_STEP_ERRORS",payload:[]}))},[r.currentStep]),j=p.handleSubmit(async t=>{try{if(e.persist){const s=e.persistence?.key||`form-draft-${f}`;localStorage.removeItem(s)}await v(t)}catch(s){C(s,S?i("error.update.entity",{entity:n}):i("error.create.entity",{entity:n}))}},t=>{}),A=e.type==="multi-step"&&e.steps?(r.currentStep+1)/e.steps.length*100:0,k=e.steps?.[r.currentStep];return l(y,{gap:"medium",children:u(q,{title:u(y,{direction:"row",align:"center",justify:"between",children:[u("div",{children:[l("div",{style:{fontSize:"var(--font-size-xl)",fontWeight:600},children:S?i("edit.entity",{entity:n}):i("create.entity",{entity:n})}),e.type==="multi-step"&&e.steps&&u("p",{style:{fontSize:"var(--font-size-sm)",color:"var(--muted-foreground)",marginTop:"var(--gap-sm)"},children:["Step ",r.currentStep+1," of ",e.steps.length,":"," ",k?.title]})]}),e.persist&&e.persistence?.showSaveIndicator&&l(y,{direction:"row",align:"center",gap:"tight",children:r.isSaving?l(F,{variant:O.SECONDARY,children:"Saving..."}):r.lastSaved?u(F,{variant:O.OUTLINE,className:"dndev-flex dndev-items-center dndev-gap-sm",children:[l(G,{className:"dndev-size-md"}),"Saved ",r.lastSaved.toLocaleTimeString()]}):null})]}),children:[e.type==="multi-step"&&e.behavior?.showProgress&&u("div",{style:{marginTop:"var(--gap-md)"},children:[l(K,{value:A,style:{height:"0.5rem"}}),u(y,{direction:"row",justify:"between",style:{marginTop:"var(--gap-sm)",fontSize:"var(--font-size-xs)",color:"var(--muted-foreground)"},children:[u("span",{children:[Math.round(A),"% complete"]}),u("span",{children:["Step ",r.currentStep+1," of"," ",e.steps?.length||0]})]})]}),r.stepErrors.length>0&&l(I,{variant:w.ERROR,description:l(y,{as:"ul",gap:"tight",style:{listStyle:"disc",listStylePosition:"inside"},children:r.stepErrors.map((t,s)=>l("li",{children:t},s))}),style:{marginBottom:"var(--gap-lg)"}}),l("form",{onSubmit:j,children:u(y,{gap:"large",children:[Object.keys(p.formState.errors).length>0&&l(I,{variant:w.ERROR,description:l(y,{as:"ul",gap:"tight",style:{listStyle:"disc",listStylePosition:"inside"},children:Object.entries(p.formState.errors).map(([t,s])=>{const g=s?.message||(typeof s=="string"?s:`${t} is invalid`);return l("li",{children:g},t)})}),style:{marginBottom:"var(--gap-md)"}}),l(W,{cols:3,gap:"large",className:"dndev-grid-responsive-1-2-3",children:V().map(t=>{const s=T.find(g=>g.name===t);return s?l(Q,{name:s.name,control:p.control,errors:p.formState.errors,config:s,t:i},s.name):null})}),u(y,{direction:"row",justify:"between",align:"center",style:{paddingTop:"var(--gap-lg)",borderTop:"1px solid var(--border)"},children:[u(y,{direction:"row",gap:"tight",children:[e.type==="multi-step"&&r.currentStep>0&&l(E,{type:"button",variant:R.OUTLINE,onClick:P,className:"dndev-gap-sm",icon:B,children:"Previous"}),l(E,{type:"button",variant:R.OUTLINE,onClick:()=>c(`/${f}`),children:i("cancel")})]}),u(y,{direction:"row",gap:"tight",children:[e.persist&&l(E,{type:"button",variant:R.OUTLINE,onClick:()=>_(p.getValues()),disabled:r.isSaving,className:"dndev-gap-sm",icon:$,children:"Save Draft"}),e.type==="multi-step"&&e.steps&&r.currentStep<e.steps.length-1&&l(E,{type:"button",onClick:D,className:"dndev-gap-sm",icon:M,iconEnd:!0,children:"Next"}),(e.type==="single"||e.type==="multi-step"&&e.steps&&r.currentStep===e.steps.length-1)&&l(E,{type:"submit",disabled:d||p.formState.isSubmitting,children:i(S?"update":"create")})]})]})]})})]})})}var Se=re;export{re as EntityFormTemplate,Se as default};
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './HomeTemplate';
2
2
  export * from './WhatsNewTemplate';
3
3
  export * from './DashboardTemplate';
4
4
  export * from './LoginTemplate';
5
+ export * from './AdminLandingTemplate';
5
6
  export * from './ProfileTemplate';
6
7
  export * from './billing';
7
8
  export * from './crud';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use client";export*from"./HomeTemplate";export*from"./WhatsNewTemplate";export*from"./DashboardTemplate";export*from"./LoginTemplate";export*from"./ProfileTemplate";export*from"./billing";export*from"./crud";export*from"./legal";export*from"./components/MarkdownViewer";
1
+ "use client";export*from"./HomeTemplate";export*from"./WhatsNewTemplate";export*from"./DashboardTemplate";export*from"./LoginTemplate";export*from"./AdminLandingTemplate";export*from"./ProfileTemplate";export*from"./billing";export*from"./crud";export*from"./legal";export*from"./components/MarkdownViewer";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donotdev/templates",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -45,19 +45,20 @@
45
45
  "type-check": "tsc --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@donotdev/adv-comps": "0.0.4",
49
- "@donotdev/components": "0.0.4",
50
- "@donotdev/core": "0.0.4",
51
- "@donotdev/crud": "0.0.4",
52
- "@donotdev/ui": "0.0.4",
48
+ "@donotdev/adv-comps": "^0.0.8",
49
+ "@donotdev/components": "^0.0.12",
50
+ "@donotdev/core": "^0.0.12",
51
+ "@donotdev/crud": "^0.0.5",
52
+ "@donotdev/ui": "^0.0.8",
53
53
  "@hookform/resolvers": "^5.2.2",
54
+ "html-react-parser": "^5.2.11",
54
55
  "marked": "^17.0.1",
55
- "react-hook-form": "^7.68.0"
56
+ "react-hook-form": "^7.71.0"
56
57
  },
57
58
  "peerDependencies": {
58
- "@donotdev/auth": "0.0.4",
59
- "@donotdev/billing": "0.0.4",
60
- "@donotdev/oauth": "0.0.4",
59
+ "@donotdev/auth": "^0.0.5",
60
+ "@donotdev/billing": "^0.0.5",
61
+ "@donotdev/oauth": "^0.0.5",
61
62
  "lucide-react": "^0.562.0",
62
63
  "react": "^19.2.3",
63
64
  "react-dom": "^19.2.3",