singularity-components 0.1.195 → 0.1.196

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.
Files changed (147) hide show
  1. package/dist/components/blocks/badges/category-badge.d.ts +11 -0
  2. package/dist/components/blocks/badges/category-badge.js +34 -0
  3. package/dist/components/blocks/badges/category-badge.js.map +1 -0
  4. package/dist/components/blocks/cards/blogpost-card.d.ts +3 -1
  5. package/dist/components/blocks/cards/blogpost-card.js +9 -4
  6. package/dist/components/blocks/cards/blogpost-card.js.map +1 -1
  7. package/dist/components/blocks/directory/author-card.d.ts +10 -0
  8. package/dist/components/blocks/directory/author-card.js +50 -0
  9. package/dist/components/blocks/directory/author-card.js.map +1 -0
  10. package/dist/components/blocks/directory/category-card.d.ts +10 -0
  11. package/dist/components/blocks/directory/category-card.js +26 -0
  12. package/dist/components/blocks/directory/category-card.js.map +1 -0
  13. package/dist/components/blocks/extras/extras-hub-card.d.ts +16 -0
  14. package/dist/components/blocks/extras/extras-hub-card.js +21 -0
  15. package/dist/components/blocks/extras/extras-hub-card.js.map +1 -0
  16. package/dist/components/blocks/gallery/image-gallery.d.ts +14 -0
  17. package/dist/components/blocks/gallery/image-gallery.js +211 -0
  18. package/dist/components/blocks/gallery/image-gallery.js.map +1 -0
  19. package/dist/components/blocks/index.d.ts +11 -0
  20. package/dist/components/blocks/index.js +10 -0
  21. package/dist/components/blocks/index.js.map +1 -1
  22. package/dist/components/blocks/loading/loading-skeletons.d.ts +15 -0
  23. package/dist/components/blocks/loading/loading-skeletons.js +78 -0
  24. package/dist/components/blocks/loading/loading-skeletons.js.map +1 -0
  25. package/dist/components/blocks/marketing/page-hero.d.ts +13 -0
  26. package/dist/components/blocks/marketing/page-hero.js +37 -0
  27. package/dist/components/blocks/marketing/page-hero.js.map +1 -0
  28. package/dist/components/blocks/marketing/stats-grid.d.ts +16 -0
  29. package/dist/components/blocks/marketing/stats-grid.js +30 -0
  30. package/dist/components/blocks/marketing/stats-grid.js.map +1 -0
  31. package/dist/components/blocks/marketing/timeline.d.ts +17 -0
  32. package/dist/components/blocks/marketing/timeline.js +45 -0
  33. package/dist/components/blocks/marketing/timeline.js.map +1 -0
  34. package/dist/components/blocks/marketing/values-grid.d.ts +16 -0
  35. package/dist/components/blocks/marketing/values-grid.js +29 -0
  36. package/dist/components/blocks/marketing/values-grid.js.map +1 -0
  37. package/dist/components/index.d.ts +28 -1
  38. package/dist/components/pages/about/about-page.d.ts +5 -0
  39. package/dist/components/pages/about/about-page.js +161 -0
  40. package/dist/components/pages/about/about-page.js.map +1 -0
  41. package/dist/components/pages/admin/admin-page.js +4 -1
  42. package/dist/components/pages/admin/admin-page.js.map +1 -1
  43. package/dist/components/pages/author/author-page.d.ts +8 -0
  44. package/dist/components/pages/author/author-page.js +107 -0
  45. package/dist/components/pages/author/author-page.js.map +1 -0
  46. package/dist/components/pages/authors/authors-page.d.ts +5 -0
  47. package/dist/components/pages/authors/authors-page.js +25 -0
  48. package/dist/components/pages/authors/authors-page.js.map +1 -0
  49. package/dist/components/pages/blogpost/blogpost.d.ts +4 -1
  50. package/dist/components/pages/blogpost/blogpost.js +38 -18
  51. package/dist/components/pages/blogpost/blogpost.js.map +1 -1
  52. package/dist/components/pages/categories/categories-page.d.ts +5 -0
  53. package/dist/components/pages/categories/categories-page.js +33 -0
  54. package/dist/components/pages/categories/categories-page.js.map +1 -0
  55. package/dist/components/pages/category/category-page.js +3 -1
  56. package/dist/components/pages/category/category-page.js.map +1 -1
  57. package/dist/components/pages/contact/contact-page.d.ts +5 -0
  58. package/dist/components/pages/contact/contact-page.js +173 -0
  59. package/dist/components/pages/contact/contact-page.js.map +1 -0
  60. package/dist/components/pages/content-blocks/content-blocks-page.d.ts +5 -0
  61. package/dist/components/pages/content-blocks/content-blocks-page.js +86 -0
  62. package/dist/components/pages/content-blocks/content-blocks-page.js.map +1 -0
  63. package/dist/components/pages/extras/extras-hub-page.d.ts +10 -0
  64. package/dist/components/pages/extras/extras-hub-page.js +110 -0
  65. package/dist/components/pages/extras/extras-hub-page.js.map +1 -0
  66. package/dist/components/pages/index.d.ts +14 -0
  67. package/dist/components/pages/index.js +12 -0
  68. package/dist/components/pages/index.js.map +1 -1
  69. package/dist/components/pages/membership/membership-page.d.ts +5 -0
  70. package/dist/components/pages/membership/membership-page.js +131 -0
  71. package/dist/components/pages/membership/membership-page.js.map +1 -0
  72. package/dist/components/pages/mosaic/mosaic-page.d.ts +5 -0
  73. package/dist/components/pages/mosaic/mosaic-page.js +81 -0
  74. package/dist/components/pages/mosaic/mosaic-page.js.map +1 -0
  75. package/dist/components/pages/newsletter/newsletter-page.d.ts +5 -0
  76. package/dist/components/pages/newsletter/newsletter-page.js +148 -0
  77. package/dist/components/pages/newsletter/newsletter-page.js.map +1 -0
  78. package/dist/components/pages/resources/resources-page.d.ts +5 -0
  79. package/dist/components/pages/resources/resources-page.js +24 -0
  80. package/dist/components/pages/resources/resources-page.js.map +1 -0
  81. package/dist/components/pages/startpage/startpage.js +6 -4
  82. package/dist/components/pages/startpage/startpage.js.map +1 -1
  83. package/dist/components/primitives/accordion/accordion.js +14 -16
  84. package/dist/components/primitives/accordion/accordion.js.map +1 -1
  85. package/dist/components/primitives/badge/badge.js +1 -1
  86. package/dist/components/primitives/badge/badge.js.map +1 -1
  87. package/dist/components/primitives/buttons/button.d.ts +2 -2
  88. package/dist/components/primitives/buttons/icon-button.d.ts +1 -1
  89. package/dist/components/primitives/collapsible/collapsible.js +4 -1
  90. package/dist/components/primitives/collapsible/collapsible.js.map +1 -1
  91. package/dist/components/primitives/dropdown-menu/dropdown-menu.js +6 -1
  92. package/dist/components/primitives/dropdown-menu/dropdown-menu.js.map +1 -1
  93. package/dist/components/primitives/forms/checkbox.js +1 -1
  94. package/dist/components/primitives/forms/checkbox.js.map +1 -1
  95. package/dist/components/primitives/forms/field.d.ts +4 -2
  96. package/dist/components/primitives/forms/field.js +4 -2
  97. package/dist/components/primitives/forms/field.js.map +1 -1
  98. package/dist/components/primitives/forms/form-control.d.ts +28 -0
  99. package/dist/components/primitives/forms/form-control.js +40 -0
  100. package/dist/components/primitives/forms/form-control.js.map +1 -0
  101. package/dist/components/primitives/forms/form.d.ts +12 -0
  102. package/dist/components/primitives/forms/form.js +30 -0
  103. package/dist/components/primitives/forms/form.js.map +1 -0
  104. package/dist/components/primitives/forms/select.js +12 -12
  105. package/dist/components/primitives/forms/select.js.map +1 -1
  106. package/dist/components/primitives/icon/icon.d.ts +3 -2
  107. package/dist/components/primitives/icon/icon.js +2 -1
  108. package/dist/components/primitives/icon/icon.js.map +1 -1
  109. package/dist/components/primitives/index.d.ts +4 -0
  110. package/dist/components/primitives/index.js +3 -0
  111. package/dist/components/primitives/index.js.map +1 -1
  112. package/dist/components/primitives/layout/layout.d.ts +1 -1
  113. package/dist/components/primitives/link/link.d.ts +2 -2
  114. package/dist/components/primitives/sheet/sheet.js +1 -1
  115. package/dist/components/primitives/sheet/sheet.js.map +1 -1
  116. package/dist/components/primitives/stack/stack.d.ts +2 -2
  117. package/dist/components/primitives/text/internal/text-element.d.ts +8 -2
  118. package/dist/components/primitives/text/internal/text-element.js +3 -0
  119. package/dist/components/primitives/text/internal/text-element.js.map +1 -1
  120. package/dist/components/primitives/text/text-code.d.ts +1 -1
  121. package/dist/components/templates/index.d.ts +1 -0
  122. package/dist/components/templates/index.js +1 -0
  123. package/dist/components/templates/index.js.map +1 -1
  124. package/dist/components/templates/loading-screen/loading-screen.d.ts +10 -0
  125. package/dist/components/templates/loading-screen/loading-screen.js +39 -0
  126. package/dist/components/templates/loading-screen/loading-screen.js.map +1 -0
  127. package/dist/css/variables.css +2 -0
  128. package/dist/css/variables.css.map +1 -1
  129. package/dist/data/posts.d.ts +5 -0
  130. package/dist/data/posts.js +37 -4
  131. package/dist/data/posts.js.map +1 -1
  132. package/dist/index.d.ts +28 -1
  133. package/dist/lib/forms/field-props.d.ts +60 -0
  134. package/dist/lib/forms/field-props.js +60 -0
  135. package/dist/lib/forms/field-props.js.map +1 -0
  136. package/dist/lib/forms/index.d.ts +11 -0
  137. package/dist/lib/forms/index.js +3 -0
  138. package/dist/lib/forms/index.js.map +1 -0
  139. package/dist/lib/forms/tanstack-field.d.ts +56 -0
  140. package/dist/lib/forms/tanstack-field.js +114 -0
  141. package/dist/lib/forms/tanstack-field.js.map +1 -0
  142. package/dist/lib/index.d.ts +11 -0
  143. package/dist/lib/index.js +1 -0
  144. package/dist/lib/index.js.map +1 -1
  145. package/dist/main.css +396 -87
  146. package/dist/main.css.map +1 -1
  147. package/package.json +14 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/pages/category/category-page.tsx"],"sourcesContent":["\"use client\";\nimport { useMemo } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { Layout, Heading, Text } from \"../../primitives/index\";\nimport { LinkButton } from \"../../primitives/buttons/link-button\";\nimport { posts } from \"../../../data/posts\";\nimport { PostListWithFilters } from \"../../blocks/post-list/post-list-with-filters\";\nimport EmptyState from \"../../blocks/empty-state/EmptyState\";\n\ninterface Props {\n category?: string;\n}\n\nexport function CategoryPage({ category: propCategory }: Props) {\n // In a real app, this would come from useParams()\n // For the library/storybook, we allow passing it as a prop\n const category = propCategory || \"Design\";\n const decodedCategory = decodeURIComponent(category);\n\n const categoryPosts = useMemo(\n () => posts.filter((p) => p.categories.includes(decodedCategory)),\n [decodedCategory],\n );\n\n if (!decodedCategory || categoryPosts.length === 0) {\n return (\n <Layout type=\"col\" className=\"sg:py-16\">\n <Layout.Col1 hideDiv>\n <EmptyState\n icon=\"Tag\"\n title=\"Category not found\"\n description={\n decodedCategory\n ? `No posts found in \"${decodedCategory}\". It may have been removed or renamed.`\n : \"This category doesn't exist.\"\n }\n actionLabel=\"Browse all posts\"\n actionTo=\"/posts\"\n className=\"sg:min-h-[60vh]\"\n />\n </Layout.Col1>\n </Layout>\n );\n }\n\n return (\n <Layout type=\"col\" className=\"sg:py-16\" as=\"main\">\n <Layout.Col1 hideDiv>\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n >\n <LinkButton\n variant=\"ghost\"\n size=\"sm\"\n to=\"/posts\"\n iconStart=\"ArrowLeft\"\n className=\"sg:mb-6\"\n >\n All Posts\n </LinkButton>\n\n <Heading variant=\"h1\" className=\"sg:mb-2 sg:capitalize\">\n {decodedCategory}\n </Heading>\n <Text foreground=\"muted-foreground\" className=\"sg:mb-12\">\n Explore {categoryPosts.length} story in this category.\n </Text>\n\n <PostListWithFilters\n posts={categoryPosts}\n hideSearch\n filterMode=\"drawer\"\n />\n </motion.div>\n </Layout.Col1>\n </Layout>\n );\n}\n"],"mappings":";AA4BU,cAsCA,YAtCA;AA3BV,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,QAAQ,SAAS,YAAY;AACtC,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,2BAA2B;AACpC,OAAO,gBAAgB;AAMhB,SAAS,aAAa,EAAE,UAAU,aAAa,GAAU;AAG9D,QAAM,WAAW,gBAAgB;AACjC,QAAM,kBAAkB,mBAAmB,QAAQ;AAEnD,QAAM,gBAAgB;AAAA,IACpB,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,eAAe,CAAC;AAAA,IAChE,CAAC,eAAe;AAAA,EAClB;AAEA,MAAI,CAAC,mBAAmB,cAAc,WAAW,GAAG;AAClD,WACE,oBAAC,UAAO,MAAK,OAAM,WAAU,YAC3B,8BAAC,OAAO,MAAP,EAAY,SAAO,MAClB;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAM;AAAA,QACN,aACE,kBACI,sBAAsB,eAAe,4CACrC;AAAA,QAEN,aAAY;AAAA,QACZ,UAAS;AAAA,QACT,WAAU;AAAA;AAAA,IACZ,GACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,UAAO,MAAK,OAAM,WAAU,YAAW,IAAG,QACzC,8BAAC,OAAO,MAAP,EAAY,SAAO,MAClB;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACC,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,UAAU,IAAI;AAAA,MAE5B;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,IAAG;AAAA,YACH,WAAU;AAAA,YACV,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QAEA,oBAAC,WAAQ,SAAQ,MAAK,WAAU,yBAC7B,2BACH;AAAA,QACA,qBAAC,QAAK,YAAW,oBAAmB,WAAU,YAAW;AAAA;AAAA,UAC9C,cAAc;AAAA,UAAO;AAAA,WAChC;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,YAAU;AAAA,YACV,YAAW;AAAA;AAAA,QACb;AAAA;AAAA;AAAA,EACF,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/pages/category/category-page.tsx"],"sourcesContent":["\"use client\";\nimport { useMemo } from \"react\";\nimport { motion } from \"framer-motion\";\nimport { Layout, Heading, Text } from \"../../primitives/index\";\nimport { LinkButton } from \"../../primitives/buttons/link-button\";\nimport { posts } from \"../../../data/posts\";\nimport { PostListWithFilters } from \"../../blocks/post-list/post-list-with-filters\";\nimport EmptyState from \"../../blocks/empty-state/EmptyState\";\n\ninterface Props {\n category?: string;\n}\n\nexport function CategoryPage({ category: propCategory }: Props) {\n // In a real app, this would come from useParams()\n // For the library/storybook, we allow passing it as a prop\n const category = propCategory || \"Design\";\n const decodedCategory = decodeURIComponent(category);\n\n const categoryPosts = useMemo(\n () => posts.filter((p) => p.categories.includes(decodedCategory)),\n [decodedCategory],\n );\n\n if (!decodedCategory || categoryPosts.length === 0) {\n return (\n <Layout type=\"col\" className=\"sg:py-16\">\n <Layout.Col1 hideDiv>\n <EmptyState\n icon=\"Tag\"\n title=\"Category not found\"\n description={\n decodedCategory\n ? `No posts found in \"${decodedCategory}\". It may have been removed or renamed.`\n : \"This category doesn't exist.\"\n }\n actionLabel=\"Browse all posts\"\n actionTo=\"/posts\"\n className=\"sg:min-h-[60vh]\"\n />\n </Layout.Col1>\n </Layout>\n );\n }\n\n return (\n <Layout type=\"col\" className=\"sg:py-16\" as=\"main\">\n <Layout.Col1 hideDiv>\n <motion.div\n initial={{ opacity: 0, y: 20 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.3 }}\n >\n <LinkButton\n variant=\"ghost\"\n size=\"sm\"\n to=\"/posts\"\n iconStart=\"ArrowLeft\"\n className=\"sg:mb-6\"\n >\n All Posts\n </LinkButton>\n\n <Heading variant=\"h1\" className=\"sg:mb-2 sg:capitalize\">\n {decodedCategory}\n </Heading>\n <Text foreground=\"muted-foreground\" className=\"sg:mb-12\">\n Explore {categoryPosts.length}{\" \"}\n {categoryPosts.length === 1 ? \"story\" : \"stories\"} in this category.\n </Text>\n\n <PostListWithFilters\n posts={categoryPosts}\n hideSearch\n filterMode=\"drawer\"\n />\n </motion.div>\n </Layout.Col1>\n </Layout>\n );\n}\n"],"mappings":";AA4BU,cAsCA,YAtCA;AA3BV,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,QAAQ,SAAS,YAAY;AACtC,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,2BAA2B;AACpC,OAAO,gBAAgB;AAMhB,SAAS,aAAa,EAAE,UAAU,aAAa,GAAU;AAG9D,QAAM,WAAW,gBAAgB;AACjC,QAAM,kBAAkB,mBAAmB,QAAQ;AAEnD,QAAM,gBAAgB;AAAA,IACpB,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,eAAe,CAAC;AAAA,IAChE,CAAC,eAAe;AAAA,EAClB;AAEA,MAAI,CAAC,mBAAmB,cAAc,WAAW,GAAG;AAClD,WACE,oBAAC,UAAO,MAAK,OAAM,WAAU,YAC3B,8BAAC,OAAO,MAAP,EAAY,SAAO,MAClB;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAM;AAAA,QACN,aACE,kBACI,sBAAsB,eAAe,4CACrC;AAAA,QAEN,aAAY;AAAA,QACZ,UAAS;AAAA,QACT,WAAU;AAAA;AAAA,IACZ,GACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,UAAO,MAAK,OAAM,WAAU,YAAW,IAAG,QACzC,8BAAC,OAAO,MAAP,EAAY,SAAO,MAClB;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACC,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,UAAU,IAAI;AAAA,MAE5B;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,IAAG;AAAA,YACH,WAAU;AAAA,YACV,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QAEA,oBAAC,WAAQ,SAAQ,MAAK,WAAU,yBAC7B,2BACH;AAAA,QACA,qBAAC,QAAK,YAAW,oBAAmB,WAAU,YAAW;AAAA;AAAA,UAC9C,cAAc;AAAA,UAAQ;AAAA,UAC9B,cAAc,WAAW,IAAI,UAAU;AAAA,UAAU;AAAA,WACpD;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,YAAU;AAAA,YACV,YAAW;AAAA;AAAA,QACb;AAAA;AAAA;AAAA,EACF,GACF,GACF;AAEJ;","names":[]}
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+
3
+ declare function ContactPage(): React.JSX.Element;
4
+
5
+ export { ContactPage };
@@ -0,0 +1,173 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { motion } from "framer-motion";
5
+ import {
6
+ Layout,
7
+ Heading,
8
+ Text,
9
+ Input,
10
+ Textarea,
11
+ Button,
12
+ Icon
13
+ } from "../../primitives/index.js";
14
+ import { Label } from "../../primitives/label/label.js";
15
+ import { PageHero } from "../../blocks/marketing/page-hero.js";
16
+ import { Card, CardContent } from "../../blocks/cards/card.js";
17
+ import { useToast } from "../../primitives/sonner/use-toast.js";
18
+ const initialForm = {
19
+ name: "",
20
+ email: "",
21
+ subject: "",
22
+ message: ""
23
+ };
24
+ function validateContact(form) {
25
+ const errors = {};
26
+ if (!form.name.trim()) errors.name = "Name is required";
27
+ if (!form.email.trim() || !form.email.includes("@")) {
28
+ errors.email = "Please enter a valid email";
29
+ }
30
+ if (!form.subject.trim()) errors.subject = "Subject is required";
31
+ if (!form.message.trim()) errors.message = "Message is required";
32
+ return errors;
33
+ }
34
+ function ContactPage() {
35
+ const { toast } = useToast();
36
+ const [form, setForm] = useState(initialForm);
37
+ const [errors, setErrors] = useState({});
38
+ const [sending, setSending] = useState(false);
39
+ const handleChange = (field, value) => {
40
+ setForm((prev) => ({ ...prev, [field]: value }));
41
+ if (errors[field]) setErrors((prev) => ({ ...prev, [field]: void 0 }));
42
+ };
43
+ const handleSubmit = (e) => {
44
+ e.preventDefault();
45
+ const fieldErrors = validateContact(form);
46
+ if (Object.keys(fieldErrors).length > 0) {
47
+ setErrors(fieldErrors);
48
+ return;
49
+ }
50
+ setSending(true);
51
+ setTimeout(() => {
52
+ setSending(false);
53
+ toast.message("Message sent!", {
54
+ description: "Thanks for reaching out. We'll get back to you soon."
55
+ });
56
+ setForm(initialForm);
57
+ setErrors({});
58
+ }, 1200);
59
+ };
60
+ return /* @__PURE__ */ jsxs(
61
+ motion.div,
62
+ {
63
+ initial: { opacity: 0, y: 20 },
64
+ animate: { opacity: 1, y: 0 },
65
+ transition: { duration: 0.3 },
66
+ children: [
67
+ /* @__PURE__ */ jsx(
68
+ PageHero,
69
+ {
70
+ icon: "Mail",
71
+ title: "Get in Touch",
72
+ description: "Have a question, idea, or just want to say hello? We'd love to hear from you."
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, className: "sg:max-w-5xl", children: /* @__PURE__ */ jsxs("div", { className: "sg:grid sg:gap-12 lg:sg:grid-cols-5", children: [
76
+ /* @__PURE__ */ jsxs("div", { className: "lg:sg:col-span-3", children: [
77
+ /* @__PURE__ */ jsx(Heading, { variant: "h3", className: "sg:mb-6", children: "Send a Message" }),
78
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "sg:space-y-5", noValidate: true, children: [
79
+ /* @__PURE__ */ jsxs("div", { className: "sg:grid sg:gap-5 sm:sg:grid-cols-2", children: [
80
+ /* @__PURE__ */ jsxs("div", { className: "sg:space-y-2", children: [
81
+ /* @__PURE__ */ jsx(Label, { htmlFor: "contact-name", children: "Name" }),
82
+ /* @__PURE__ */ jsx(
83
+ Input,
84
+ {
85
+ id: "contact-name",
86
+ value: form.name,
87
+ onChange: (e) => handleChange("name", e.target.value),
88
+ placeholder: "Your name",
89
+ "aria-invalid": !!errors.name
90
+ }
91
+ ),
92
+ errors.name && /* @__PURE__ */ jsx(Text, { size: "sm", className: "sg:text-destructive", children: errors.name })
93
+ ] }),
94
+ /* @__PURE__ */ jsxs("div", { className: "sg:space-y-2", children: [
95
+ /* @__PURE__ */ jsx(Label, { htmlFor: "contact-email", children: "Email" }),
96
+ /* @__PURE__ */ jsx(
97
+ Input,
98
+ {
99
+ id: "contact-email",
100
+ type: "email",
101
+ value: form.email,
102
+ onChange: (e) => handleChange("email", e.target.value),
103
+ placeholder: "you@example.com",
104
+ "aria-invalid": !!errors.email
105
+ }
106
+ ),
107
+ errors.email && /* @__PURE__ */ jsx(Text, { size: "sm", className: "sg:text-destructive", children: errors.email })
108
+ ] })
109
+ ] }),
110
+ /* @__PURE__ */ jsxs("div", { className: "sg:space-y-2", children: [
111
+ /* @__PURE__ */ jsx(Label, { htmlFor: "contact-subject", children: "Subject" }),
112
+ /* @__PURE__ */ jsx(
113
+ Input,
114
+ {
115
+ id: "contact-subject",
116
+ value: form.subject,
117
+ onChange: (e) => handleChange("subject", e.target.value),
118
+ placeholder: "What's this about?",
119
+ "aria-invalid": !!errors.subject
120
+ }
121
+ ),
122
+ errors.subject && /* @__PURE__ */ jsx(Text, { size: "sm", className: "sg:text-destructive", children: errors.subject })
123
+ ] }),
124
+ /* @__PURE__ */ jsxs("div", { className: "sg:space-y-2", children: [
125
+ /* @__PURE__ */ jsx(Label, { htmlFor: "contact-message", children: "Message" }),
126
+ /* @__PURE__ */ jsx(
127
+ Textarea,
128
+ {
129
+ id: "contact-message",
130
+ value: form.message,
131
+ onChange: (e) => handleChange("message", e.target.value),
132
+ placeholder: "Your message...",
133
+ rows: 6,
134
+ "aria-invalid": !!errors.message
135
+ }
136
+ ),
137
+ errors.message && /* @__PURE__ */ jsx(Text, { size: "sm", className: "sg:text-destructive", children: errors.message })
138
+ ] }),
139
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading: sending, iconStart: "Send", children: "Send message" })
140
+ ] })
141
+ ] }),
142
+ /* @__PURE__ */ jsx("div", { className: "lg:sg:col-span-2 sg:space-y-6", children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "sg:pt-6 sg:space-y-4", children: [
143
+ /* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-start sg:gap-3", children: [
144
+ /* @__PURE__ */ jsx(Icon, { icon: "Mail", className: "sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5" }),
145
+ /* @__PURE__ */ jsxs("div", { children: [
146
+ /* @__PURE__ */ jsx(Text, { fontweight: "medium", children: "Email" }),
147
+ /* @__PURE__ */ jsx(Text, { size: "sm", foreground: "muted-foreground", children: "hello@filion.se" })
148
+ ] })
149
+ ] }),
150
+ /* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-start sg:gap-3", children: [
151
+ /* @__PURE__ */ jsx(Icon, { icon: "MapPin", className: "sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5" }),
152
+ /* @__PURE__ */ jsxs("div", { children: [
153
+ /* @__PURE__ */ jsx(Text, { fontweight: "medium", children: "Location" }),
154
+ /* @__PURE__ */ jsx(Text, { size: "sm", foreground: "muted-foreground", children: "Stockholm, Sweden" })
155
+ ] })
156
+ ] }),
157
+ /* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-start sg:gap-3", children: [
158
+ /* @__PURE__ */ jsx(Icon, { icon: "Clock", className: "sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5" }),
159
+ /* @__PURE__ */ jsxs("div", { children: [
160
+ /* @__PURE__ */ jsx(Text, { fontweight: "medium", children: "Hours" }),
161
+ /* @__PURE__ */ jsx(Text, { size: "sm", foreground: "muted-foreground", children: "Mon\u2013Fri, 9am\u20135pm CET" })
162
+ ] })
163
+ ] })
164
+ ] }) }) })
165
+ ] }) }) })
166
+ ]
167
+ }
168
+ );
169
+ }
170
+ export {
171
+ ContactPage
172
+ };
173
+ //# sourceMappingURL=contact-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/pages/contact/contact-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useState } from \"react\";\r\nimport { motion } from \"framer-motion\";\r\nimport {\r\n\tLayout,\r\n\tHeading,\r\n\tText,\r\n\tInput,\r\n\tTextarea,\r\n\tButton,\r\n\tIcon,\r\n} from \"../../primitives/index\";\r\nimport { Label } from \"../../primitives/label/label\";\r\nimport { PageHero } from \"../../blocks/marketing/page-hero\";\r\nimport { Card, CardContent } from \"../../blocks/cards/card\";\r\nimport { useToast } from \"../../primitives/sonner/use-toast\";\r\n\r\ntype FormState = {\r\n\tname: string;\r\n\temail: string;\r\n\tsubject: string;\r\n\tmessage: string;\r\n};\r\n\r\nconst initialForm: FormState = {\r\n\tname: \"\",\r\n\temail: \"\",\r\n\tsubject: \"\",\r\n\tmessage: \"\",\r\n};\r\n\r\n/** Validates a simple contact form without external dependencies. */\r\nfunction validateContact(form: FormState): Partial<Record<keyof FormState, string>> {\r\n\tconst errors: Partial<Record<keyof FormState, string>> = {};\r\n\tif (!form.name.trim()) errors.name = \"Name is required\";\r\n\tif (!form.email.trim() || !form.email.includes(\"@\")) {\r\n\t\terrors.email = \"Please enter a valid email\";\r\n\t}\r\n\tif (!form.subject.trim()) errors.subject = \"Subject is required\";\r\n\tif (!form.message.trim()) errors.message = \"Message is required\";\r\n\treturn errors;\r\n}\r\n\r\nexport function ContactPage() {\r\n\tconst { toast } = useToast();\r\n\tconst [form, setForm] = useState<FormState>(initialForm);\r\n\tconst [errors, setErrors] = useState<Partial<Record<keyof FormState, string>>>({});\r\n\tconst [sending, setSending] = useState(false);\r\n\r\n\tconst handleChange = (field: keyof FormState, value: string) => {\r\n\t\tsetForm((prev) => ({ ...prev, [field]: value }));\r\n\t\tif (errors[field]) setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n\t};\r\n\r\n\tconst handleSubmit = (e: React.FormEvent) => {\r\n\t\te.preventDefault();\r\n\t\tconst fieldErrors = validateContact(form);\r\n\t\tif (Object.keys(fieldErrors).length > 0) {\r\n\t\t\tsetErrors(fieldErrors);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tsetSending(true);\r\n\t\tsetTimeout(() => {\r\n\t\t\tsetSending(false);\r\n\t\t\ttoast.message(\"Message sent!\", {\r\n\t\t\t\tdescription: \"Thanks for reaching out. We'll get back to you soon.\",\r\n\t\t\t});\r\n\t\t\tsetForm(initialForm);\r\n\t\t\tsetErrors({});\r\n\t\t}, 1200);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<motion.div\r\n\t\t\tinitial={{ opacity: 0, y: 20 }}\r\n\t\t\tanimate={{ opacity: 1, y: 0 }}\r\n\t\t\ttransition={{ duration: 0.3 }}\r\n\t\t>\r\n\t\t\t<PageHero\r\n\t\t\t\ticon=\"Mail\"\r\n\t\t\t\ttitle=\"Get in Touch\"\r\n\t\t\t\tdescription=\"Have a question, idea, or just want to say hello? We'd love to hear from you.\"\r\n\t\t\t/>\r\n\r\n\t\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t\t<Layout.Col1 hideDiv className=\"sg:max-w-5xl\">\r\n\t\t\t\t\t<div className=\"sg:grid sg:gap-12 lg:sg:grid-cols-5\">\r\n\t\t\t\t\t\t<div className=\"lg:sg:col-span-3\">\r\n\t\t\t\t\t\t\t<Heading variant=\"h3\" className=\"sg:mb-6\">\r\n\t\t\t\t\t\t\t\tSend a Message\r\n\t\t\t\t\t\t\t</Heading>\r\n\t\t\t\t\t\t\t<form onSubmit={handleSubmit} className=\"sg:space-y-5\" noValidate>\r\n\t\t\t\t\t\t\t\t<div className=\"sg:grid sg:gap-5 sm:sg:grid-cols-2\">\r\n\t\t\t\t\t\t\t\t\t<div className=\"sg:space-y-2\">\r\n\t\t\t\t\t\t\t\t\t\t<Label htmlFor=\"contact-name\">Name</Label>\r\n\t\t\t\t\t\t\t\t\t\t<Input\r\n\t\t\t\t\t\t\t\t\t\t\tid=\"contact-name\"\r\n\t\t\t\t\t\t\t\t\t\t\tvalue={form.name}\r\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => handleChange(\"name\", e.target.value)}\r\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"Your name\"\r\n\t\t\t\t\t\t\t\t\t\t\taria-invalid={!!errors.name}\r\n\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t{errors.name && (\r\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" className=\"sg:text-destructive\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t{errors.name}\r\n\t\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t<div className=\"sg:space-y-2\">\r\n\t\t\t\t\t\t\t\t\t\t<Label htmlFor=\"contact-email\">Email</Label>\r\n\t\t\t\t\t\t\t\t\t\t<Input\r\n\t\t\t\t\t\t\t\t\t\t\tid=\"contact-email\"\r\n\t\t\t\t\t\t\t\t\t\t\ttype=\"email\"\r\n\t\t\t\t\t\t\t\t\t\t\tvalue={form.email}\r\n\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => handleChange(\"email\", e.target.value)}\r\n\t\t\t\t\t\t\t\t\t\t\tplaceholder=\"you@example.com\"\r\n\t\t\t\t\t\t\t\t\t\t\taria-invalid={!!errors.email}\r\n\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t{errors.email && (\r\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" className=\"sg:text-destructive\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t{errors.email}\r\n\t\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t<div className=\"sg:space-y-2\">\r\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"contact-subject\">Subject</Label>\r\n\t\t\t\t\t\t\t\t\t<Input\r\n\t\t\t\t\t\t\t\t\t\tid=\"contact-subject\"\r\n\t\t\t\t\t\t\t\t\t\tvalue={form.subject}\r\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => handleChange(\"subject\", e.target.value)}\r\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"What's this about?\"\r\n\t\t\t\t\t\t\t\t\t\taria-invalid={!!errors.subject}\r\n\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t{errors.subject && (\r\n\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" className=\"sg:text-destructive\">\r\n\t\t\t\t\t\t\t\t\t\t\t{errors.subject}\r\n\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t<div className=\"sg:space-y-2\">\r\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"contact-message\">Message</Label>\r\n\t\t\t\t\t\t\t\t\t<Textarea\r\n\t\t\t\t\t\t\t\t\t\tid=\"contact-message\"\r\n\t\t\t\t\t\t\t\t\t\tvalue={form.message}\r\n\t\t\t\t\t\t\t\t\t\tonChange={(e) => handleChange(\"message\", e.target.value)}\r\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Your message...\"\r\n\t\t\t\t\t\t\t\t\t\trows={6}\r\n\t\t\t\t\t\t\t\t\t\taria-invalid={!!errors.message}\r\n\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t{errors.message && (\r\n\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" className=\"sg:text-destructive\">\r\n\t\t\t\t\t\t\t\t\t\t\t{errors.message}\r\n\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t<Button type=\"submit\" loading={sending} iconStart=\"Send\">\r\n\t\t\t\t\t\t\t\t\tSend message\r\n\t\t\t\t\t\t\t\t</Button>\r\n\t\t\t\t\t\t\t</form>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div className=\"lg:sg:col-span-2 sg:space-y-6\">\r\n\t\t\t\t\t\t\t<Card>\r\n\t\t\t\t\t\t\t\t<CardContent className=\"sg:pt-6 sg:space-y-4\">\r\n\t\t\t\t\t\t\t\t\t<div className=\"sg:flex sg:items-start sg:gap-3\">\r\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"Mail\" className=\"sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5\" />\r\n\t\t\t\t\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text fontweight=\"medium\">Email</Text>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\">\r\n\t\t\t\t\t\t\t\t\t\t\t\thello@filion.se\r\n\t\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t<div className=\"sg:flex sg:items-start sg:gap-3\">\r\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"MapPin\" className=\"sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5\" />\r\n\t\t\t\t\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text fontweight=\"medium\">Location</Text>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\">\r\n\t\t\t\t\t\t\t\t\t\t\t\tStockholm, Sweden\r\n\t\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t<div className=\"sg:flex sg:items-start sg:gap-3\">\r\n\t\t\t\t\t\t\t\t\t\t<Icon icon=\"Clock\" className=\"sg:h-5 sg:w-5 sg:text-primary sg:mt-0.5\" />\r\n\t\t\t\t\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text fontweight=\"medium\">Hours</Text>\r\n\t\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\">\r\n\t\t\t\t\t\t\t\t\t\t\t\tMon–Fri, 9am–5pm CET\r\n\t\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</CardContent>\r\n\t\t\t\t\t\t\t</Card>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\t\t</motion.div>\r\n\t);\r\n}\r\n"],"mappings":";AA+EG,cAeM,YAfN;AA7EH,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,MAAM,mBAAmB;AAClC,SAAS,gBAAgB;AASzB,MAAM,cAAyB;AAAA,EAC9B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,SAAS;AACV;AAGA,SAAS,gBAAgB,MAA2D;AACnF,QAAM,SAAmD,CAAC;AAC1D,MAAI,CAAC,KAAK,KAAK,KAAK,EAAG,QAAO,OAAO;AACrC,MAAI,CAAC,KAAK,MAAM,KAAK,KAAK,CAAC,KAAK,MAAM,SAAS,GAAG,GAAG;AACpD,WAAO,QAAQ;AAAA,EAChB;AACA,MAAI,CAAC,KAAK,QAAQ,KAAK,EAAG,QAAO,UAAU;AAC3C,MAAI,CAAC,KAAK,QAAQ,KAAK,EAAG,QAAO,UAAU;AAC3C,SAAO;AACR;AAEO,SAAS,cAAc;AAC7B,QAAM,EAAE,MAAM,IAAI,SAAS;AAC3B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAoB,WAAW;AACvD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAmD,CAAC,CAAC;AACjF,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,eAAe,CAAC,OAAwB,UAAkB;AAC/D,YAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,EAAE;AAC/C,QAAI,OAAO,KAAK,EAAG,WAAU,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,OAAU,EAAE;AAAA,EACzE;AAEA,QAAM,eAAe,CAAC,MAAuB;AAC5C,MAAE,eAAe;AACjB,UAAM,cAAc,gBAAgB,IAAI;AACxC,QAAI,OAAO,KAAK,WAAW,EAAE,SAAS,GAAG;AACxC,gBAAU,WAAW;AACrB;AAAA,IACD;AACA,eAAW,IAAI;AACf,eAAW,MAAM;AAChB,iBAAW,KAAK;AAChB,YAAM,QAAQ,iBAAiB;AAAA,QAC9B,aAAa;AAAA,MACd,CAAC;AACD,cAAQ,WAAW;AACnB,gBAAU,CAAC,CAAC;AAAA,IACb,GAAG,IAAI;AAAA,EACR;AAEA,SACC;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACA,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,UAAU,IAAI;AAAA,MAE5B;AAAA;AAAA,UAAC;AAAA;AAAA,YACA,MAAK;AAAA,YACL,OAAM;AAAA,YACN,aAAY;AAAA;AAAA,QACb;AAAA,QAEA,oBAAC,UAAO,MAAK,OAAM,WAAU,YAC5B,8BAAC,OAAO,MAAP,EAAY,SAAO,MAAC,WAAU,gBAC9B,+BAAC,SAAI,WAAU,uCACd;AAAA,+BAAC,SAAI,WAAU,oBACd;AAAA,gCAAC,WAAQ,SAAQ,MAAK,WAAU,WAAU,4BAE1C;AAAA,YACA,qBAAC,UAAK,UAAU,cAAc,WAAU,gBAAe,YAAU,MAChE;AAAA,mCAAC,SAAI,WAAU,sCACd;AAAA,qCAAC,SAAI,WAAU,gBACd;AAAA,sCAAC,SAAM,SAAQ,gBAAe,kBAAI;AAAA,kBAClC;AAAA,oBAAC;AAAA;AAAA,sBACA,IAAG;AAAA,sBACH,OAAO,KAAK;AAAA,sBACZ,UAAU,CAAC,MAAM,aAAa,QAAQ,EAAE,OAAO,KAAK;AAAA,sBACpD,aAAY;AAAA,sBACZ,gBAAc,CAAC,CAAC,OAAO;AAAA;AAAA,kBACxB;AAAA,kBACC,OAAO,QACP,oBAAC,QAAK,MAAK,MAAK,WAAU,uBACxB,iBAAO,MACT;AAAA,mBAEF;AAAA,gBACA,qBAAC,SAAI,WAAU,gBACd;AAAA,sCAAC,SAAM,SAAQ,iBAAgB,mBAAK;AAAA,kBACpC;AAAA,oBAAC;AAAA;AAAA,sBACA,IAAG;AAAA,sBACH,MAAK;AAAA,sBACL,OAAO,KAAK;AAAA,sBACZ,UAAU,CAAC,MAAM,aAAa,SAAS,EAAE,OAAO,KAAK;AAAA,sBACrD,aAAY;AAAA,sBACZ,gBAAc,CAAC,CAAC,OAAO;AAAA;AAAA,kBACxB;AAAA,kBACC,OAAO,SACP,oBAAC,QAAK,MAAK,MAAK,WAAU,uBACxB,iBAAO,OACT;AAAA,mBAEF;AAAA,iBACD;AAAA,cACA,qBAAC,SAAI,WAAU,gBACd;AAAA,oCAAC,SAAM,SAAQ,mBAAkB,qBAAO;AAAA,gBACxC;AAAA,kBAAC;AAAA;AAAA,oBACA,IAAG;AAAA,oBACH,OAAO,KAAK;AAAA,oBACZ,UAAU,CAAC,MAAM,aAAa,WAAW,EAAE,OAAO,KAAK;AAAA,oBACvD,aAAY;AAAA,oBACZ,gBAAc,CAAC,CAAC,OAAO;AAAA;AAAA,gBACxB;AAAA,gBACC,OAAO,WACP,oBAAC,QAAK,MAAK,MAAK,WAAU,uBACxB,iBAAO,SACT;AAAA,iBAEF;AAAA,cACA,qBAAC,SAAI,WAAU,gBACd;AAAA,oCAAC,SAAM,SAAQ,mBAAkB,qBAAO;AAAA,gBACxC;AAAA,kBAAC;AAAA;AAAA,oBACA,IAAG;AAAA,oBACH,OAAO,KAAK;AAAA,oBACZ,UAAU,CAAC,MAAM,aAAa,WAAW,EAAE,OAAO,KAAK;AAAA,oBACvD,aAAY;AAAA,oBACZ,MAAM;AAAA,oBACN,gBAAc,CAAC,CAAC,OAAO;AAAA;AAAA,gBACxB;AAAA,gBACC,OAAO,WACP,oBAAC,QAAK,MAAK,MAAK,WAAU,uBACxB,iBAAO,SACT;AAAA,iBAEF;AAAA,cACA,oBAAC,UAAO,MAAK,UAAS,SAAS,SAAS,WAAU,QAAO,0BAEzD;AAAA,eACD;AAAA,aACD;AAAA,UAEA,oBAAC,SAAI,WAAU,iCACd,8BAAC,QACA,+BAAC,eAAY,WAAU,wBACtB;AAAA,iCAAC,SAAI,WAAU,mCACd;AAAA,kCAAC,QAAK,MAAK,QAAO,WAAU,2CAA0C;AAAA,cACtE,qBAAC,SACA;AAAA,oCAAC,QAAK,YAAW,UAAS,mBAAK;AAAA,gBAC/B,oBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,6BAE9C;AAAA,iBACD;AAAA,eACD;AAAA,YACA,qBAAC,SAAI,WAAU,mCACd;AAAA,kCAAC,QAAK,MAAK,UAAS,WAAU,2CAA0C;AAAA,cACxE,qBAAC,SACA;AAAA,oCAAC,QAAK,YAAW,UAAS,sBAAQ;AAAA,gBAClC,oBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,+BAE9C;AAAA,iBACD;AAAA,eACD;AAAA,YACA,qBAAC,SAAI,WAAU,mCACd;AAAA,kCAAC,QAAK,MAAK,SAAQ,WAAU,2CAA0C;AAAA,cACvE,qBAAC,SACA;AAAA,oCAAC,QAAK,YAAW,UAAS,mBAAK;AAAA,gBAC/B,oBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,4CAE9C;AAAA,iBACD;AAAA,eACD;AAAA,aACD,GACD,GACD;AAAA,WACD,GACD,GACD;AAAA;AAAA;AAAA,EACD;AAEF;","names":[]}
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+
3
+ declare function ContentBlocksPage(): React.JSX.Element;
4
+
5
+ export { ContentBlocksPage };
@@ -0,0 +1,86 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { motion } from "framer-motion";
4
+ import {
5
+ Layout,
6
+ Heading,
7
+ Text,
8
+ Alert,
9
+ AlertDescription,
10
+ AlertTitle,
11
+ Accordion,
12
+ AccordionContent,
13
+ AccordionItem,
14
+ AccordionTrigger
15
+ } from "../../primitives/index.js";
16
+ import { LinkButton } from "../../primitives/buttons/link-button.js";
17
+ import { PageHero } from "../../blocks/marketing/page-hero.js";
18
+ import { Card, CardContent } from "../../blocks/cards/card.js";
19
+ import { TextCode } from "../../primitives/text/text-code.js";
20
+ function ContentBlocksPage() {
21
+ return /* @__PURE__ */ jsxs(
22
+ motion.div,
23
+ {
24
+ initial: { opacity: 0, y: 20 },
25
+ animate: { opacity: 1, y: 0 },
26
+ transition: { duration: 0.3 },
27
+ children: [
28
+ /* @__PURE__ */ jsx(
29
+ PageHero,
30
+ {
31
+ icon: "Layers",
32
+ title: "Content Blocks",
33
+ description: "Reusable editorial patterns for articles and marketing pages."
34
+ }
35
+ ),
36
+ /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsxs(Layout.Col1, { hideDiv: true, className: "sg:max-w-3xl sg:space-y-12", children: [
37
+ /* @__PURE__ */ jsxs("section", { className: "sg:space-y-4", children: [
38
+ /* @__PURE__ */ jsx(Heading, { variant: "h2", children: "Callouts" }),
39
+ /* @__PURE__ */ jsxs(Alert, { children: [
40
+ /* @__PURE__ */ jsx(AlertTitle, { children: "Info" }),
41
+ /* @__PURE__ */ jsx(AlertDescription, { children: "Use callouts to highlight tips, warnings, or key takeaways." })
42
+ ] })
43
+ ] }),
44
+ /* @__PURE__ */ jsxs("section", { className: "sg:space-y-4", children: [
45
+ /* @__PURE__ */ jsx(Heading, { variant: "h2", children: "Code Snippets" }),
46
+ /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "sg:pt-6", children: /* @__PURE__ */ jsx(TextCode, { children: `const featured = posts.filter((p) => p.featured);` }) }) })
47
+ ] }),
48
+ /* @__PURE__ */ jsxs("section", { className: "sg:space-y-4", children: [
49
+ /* @__PURE__ */ jsx(Heading, { variant: "h2", children: "Quote Block" }),
50
+ /* @__PURE__ */ jsxs("blockquote", { className: "sg:border-l-4 sg:border-primary sg:pl-6 sg:py-2", children: [
51
+ /* @__PURE__ */ jsx(Text, { size: "lg", className: "sg:italic", children: '"Design is not just what it looks like \u2014 design is how it works."' }),
52
+ /* @__PURE__ */ jsx(Text, { size: "sm", foreground: "muted-foreground", className: "sg:mt-2", children: "\u2014 Steve Jobs" })
53
+ ] })
54
+ ] }),
55
+ /* @__PURE__ */ jsxs("section", { className: "sg:space-y-4", children: [
56
+ /* @__PURE__ */ jsx(Heading, { variant: "h2", children: "FAQ Accordion" }),
57
+ /* @__PURE__ */ jsxs(Accordion, { multiple: false, "aria-label": "Content blocks FAQ", children: [
58
+ /* @__PURE__ */ jsxs(AccordionItem, { value: "item-1", children: [
59
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: "What are content blocks?" }),
60
+ /* @__PURE__ */ jsx(AccordionContent, { children: "Reusable UI patterns for editorial and marketing content." })
61
+ ] }),
62
+ /* @__PURE__ */ jsxs(AccordionItem, { value: "item-2", children: [
63
+ /* @__PURE__ */ jsx(AccordionTrigger, { children: "How do I use them?" }),
64
+ /* @__PURE__ */ jsx(AccordionContent, { children: "Import the block components and compose them in your pages." })
65
+ ] })
66
+ ] })
67
+ ] }),
68
+ /* @__PURE__ */ jsxs("section", { className: "sg:space-y-4", children: [
69
+ /* @__PURE__ */ jsx(Heading, { variant: "h2", children: "Inline CTA" }),
70
+ /* @__PURE__ */ jsx(Card, { className: "sg:bg-primary/5 sg:border-primary/20", children: /* @__PURE__ */ jsxs(CardContent, { className: "sg:py-6 sg:flex sg:flex-col sm:sg:flex-row sg:items-center sg:justify-between sg:gap-4", children: [
71
+ /* @__PURE__ */ jsxs("div", { children: [
72
+ /* @__PURE__ */ jsx(Heading, { variant: "h4", children: "Stay in the loop" }),
73
+ /* @__PURE__ */ jsx(Text, { size: "sm", foreground: "muted-foreground", children: "Get curated stories delivered weekly." })
74
+ ] }),
75
+ /* @__PURE__ */ jsx(LinkButton, { to: "/extras/newsletter", children: "Subscribe" })
76
+ ] }) })
77
+ ] })
78
+ ] }) })
79
+ ]
80
+ }
81
+ );
82
+ }
83
+ export {
84
+ ContentBlocksPage
85
+ };
86
+ //# sourceMappingURL=content-blocks-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/pages/content-blocks/content-blocks-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { motion } from \"framer-motion\";\r\nimport {\r\n\tLayout,\r\n\tHeading,\r\n\tText,\r\n\tAlert,\r\n\tAlertDescription,\r\n\tAlertTitle,\r\n\tAccordion,\r\n\tAccordionContent,\r\n\tAccordionItem,\r\n\tAccordionTrigger,\r\n} from \"../../primitives/index\";\r\nimport { LinkButton } from \"../../primitives/buttons/link-button\";\r\nimport { PageHero } from \"../../blocks/marketing/page-hero\";\r\nimport { Card, CardContent } from \"../../blocks/cards/card\";\r\nimport { TextCode } from \"../../primitives/text/text-code\";\r\n\r\nexport function ContentBlocksPage() {\r\n\treturn (\r\n\t\t<motion.div\r\n\t\t\tinitial={{ opacity: 0, y: 20 }}\r\n\t\t\tanimate={{ opacity: 1, y: 0 }}\r\n\t\t\ttransition={{ duration: 0.3 }}\r\n\t\t>\r\n\t\t\t<PageHero\r\n\t\t\t\ticon=\"Layers\"\r\n\t\t\t\ttitle=\"Content Blocks\"\r\n\t\t\t\tdescription=\"Reusable editorial patterns for articles and marketing pages.\"\r\n\t\t\t/>\r\n\r\n\t\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t\t<Layout.Col1 hideDiv className=\"sg:max-w-3xl sg:space-y-12\">\r\n\t\t\t\t\t<section className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\">Callouts</Heading>\r\n\t\t\t\t\t\t<Alert>\r\n\t\t\t\t\t\t\t<AlertTitle>Info</AlertTitle>\r\n\t\t\t\t\t\t\t<AlertDescription>\r\n\t\t\t\t\t\t\t\tUse callouts to highlight tips, warnings, or key takeaways.\r\n\t\t\t\t\t\t\t</AlertDescription>\r\n\t\t\t\t\t\t</Alert>\r\n\t\t\t\t\t</section>\r\n\r\n\t\t\t\t\t<section className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\">Code Snippets</Heading>\r\n\t\t\t\t\t\t<Card>\r\n\t\t\t\t\t\t\t<CardContent className=\"sg:pt-6\">\r\n\t\t\t\t\t\t\t\t<TextCode>{`const featured = posts.filter((p) => p.featured);`}</TextCode>\r\n\t\t\t\t\t\t\t</CardContent>\r\n\t\t\t\t\t\t</Card>\r\n\t\t\t\t\t</section>\r\n\r\n\t\t\t\t\t<section className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\">Quote Block</Heading>\r\n\t\t\t\t\t\t<blockquote className=\"sg:border-l-4 sg:border-primary sg:pl-6 sg:py-2\">\r\n\t\t\t\t\t\t\t<Text size=\"lg\" className=\"sg:italic\">\r\n\t\t\t\t\t\t\t\t&quot;Design is not just what it looks like — design is how it works.&quot;\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:mt-2\">\r\n\t\t\t\t\t\t\t\t— Steve Jobs\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t</blockquote>\r\n\t\t\t\t\t</section>\r\n\r\n\t\t\t\t\t<section className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\">FAQ Accordion</Heading>\r\n\t\t\t\t\t\t<Accordion multiple={false} aria-label=\"Content blocks FAQ\">\r\n\t\t\t\t\t\t\t<AccordionItem value=\"item-1\">\r\n\t\t\t\t\t\t\t\t<AccordionTrigger>What are content blocks?</AccordionTrigger>\r\n\t\t\t\t\t\t\t\t<AccordionContent>\r\n\t\t\t\t\t\t\t\t\tReusable UI patterns for editorial and marketing content.\r\n\t\t\t\t\t\t\t\t</AccordionContent>\r\n\t\t\t\t\t\t\t</AccordionItem>\r\n\t\t\t\t\t\t\t<AccordionItem value=\"item-2\">\r\n\t\t\t\t\t\t\t\t<AccordionTrigger>How do I use them?</AccordionTrigger>\r\n\t\t\t\t\t\t\t\t<AccordionContent>\r\n\t\t\t\t\t\t\t\t\tImport the block components and compose them in your pages.\r\n\t\t\t\t\t\t\t\t</AccordionContent>\r\n\t\t\t\t\t\t\t</AccordionItem>\r\n\t\t\t\t\t\t</Accordion>\r\n\t\t\t\t\t</section>\r\n\r\n\t\t\t\t\t<section className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\">Inline CTA</Heading>\r\n\t\t\t\t\t\t<Card className=\"sg:bg-primary/5 sg:border-primary/20\">\r\n\t\t\t\t\t\t\t<CardContent className=\"sg:py-6 sg:flex sg:flex-col sm:sg:flex-row sg:items-center sg:justify-between sg:gap-4\">\r\n\t\t\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t\t\t<Heading variant=\"h4\">Stay in the loop</Heading>\r\n\t\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\">\r\n\t\t\t\t\t\t\t\t\t\tGet curated stories delivered weekly.\r\n\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t<LinkButton to=\"/extras/newsletter\">Subscribe</LinkButton>\r\n\t\t\t\t\t\t\t</CardContent>\r\n\t\t\t\t\t\t</Card>\r\n\t\t\t\t\t</section>\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\t\t</motion.div>\r\n\t);\r\n}\r\n"],"mappings":";AA2BG,cAUG,YAVH;AAzBH,SAAS,cAAc;AACvB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,kBAAkB;AAC3B,SAAS,gBAAgB;AACzB,SAAS,MAAM,mBAAmB;AAClC,SAAS,gBAAgB;AAElB,SAAS,oBAAoB;AACnC,SACC;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACA,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,UAAU,IAAI;AAAA,MAE5B;AAAA;AAAA,UAAC;AAAA;AAAA,YACA,MAAK;AAAA,YACL,OAAM;AAAA,YACN,aAAY;AAAA;AAAA,QACb;AAAA,QAEA,oBAAC,UAAO,MAAK,OAAM,WAAU,YAC5B,+BAAC,OAAO,MAAP,EAAY,SAAO,MAAC,WAAU,8BAC9B;AAAA,+BAAC,aAAQ,WAAU,gBAClB;AAAA,gCAAC,WAAQ,SAAQ,MAAK,sBAAQ;AAAA,YAC9B,qBAAC,SACA;AAAA,kCAAC,cAAW,kBAAI;AAAA,cAChB,oBAAC,oBAAiB,yEAElB;AAAA,eACD;AAAA,aACD;AAAA,UAEA,qBAAC,aAAQ,WAAU,gBAClB;AAAA,gCAAC,WAAQ,SAAQ,MAAK,2BAAa;AAAA,YACnC,oBAAC,QACA,8BAAC,eAAY,WAAU,WACtB,8BAAC,YAAU,+DAAoD,GAChE,GACD;AAAA,aACD;AAAA,UAEA,qBAAC,aAAQ,WAAU,gBAClB;AAAA,gCAAC,WAAQ,SAAQ,MAAK,yBAAW;AAAA,YACjC,qBAAC,gBAAW,WAAU,mDACrB;AAAA,kCAAC,QAAK,MAAK,MAAK,WAAU,aAAY,oFAEtC;AAAA,cACA,oBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,WAAU,WAAU,+BAElE;AAAA,eACD;AAAA,aACD;AAAA,UAEA,qBAAC,aAAQ,WAAU,gBAClB;AAAA,gCAAC,WAAQ,SAAQ,MAAK,2BAAa;AAAA,YACnC,qBAAC,aAAU,UAAU,OAAO,cAAW,sBACtC;AAAA,mCAAC,iBAAc,OAAM,UACpB;AAAA,oCAAC,oBAAiB,sCAAwB;AAAA,gBAC1C,oBAAC,oBAAiB,uEAElB;AAAA,iBACD;AAAA,cACA,qBAAC,iBAAc,OAAM,UACpB;AAAA,oCAAC,oBAAiB,gCAAkB;AAAA,gBACpC,oBAAC,oBAAiB,yEAElB;AAAA,iBACD;AAAA,eACD;AAAA,aACD;AAAA,UAEA,qBAAC,aAAQ,WAAU,gBAClB;AAAA,gCAAC,WAAQ,SAAQ,MAAK,wBAAU;AAAA,YAChC,oBAAC,QAAK,WAAU,wCACf,+BAAC,eAAY,WAAU,0FACtB;AAAA,mCAAC,SACA;AAAA,oCAAC,WAAQ,SAAQ,MAAK,8BAAgB;AAAA,gBACtC,oBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,mDAE9C;AAAA,iBACD;AAAA,cACA,oBAAC,cAAW,IAAG,sBAAqB,uBAAS;AAAA,eAC9C,GACD;AAAA,aACD;AAAA,WACD,GACD;AAAA;AAAA;AAAA,EACD;AAEF;","names":[]}
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { ExtrasHubItem } from '../../blocks/extras/extras-hub-card.js';
3
+ import 'lucide-react';
4
+
5
+ type Props = {
6
+ items?: ExtrasHubItem[];
7
+ };
8
+ declare function ExtrasHubPage({ items }: Props): React.JSX.Element;
9
+
10
+ export { ExtrasHubPage };
@@ -0,0 +1,110 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { motion } from "framer-motion";
4
+ import { Layout, Heading, Text } from "../../primitives/index.js";
5
+ import { ExtrasHubCard } from "../../blocks/extras/extras-hub-card.js";
6
+ const defaultItems = [
7
+ {
8
+ title: "About",
9
+ description: "Our mission, story, team, and journey.",
10
+ to: "/extras/about",
11
+ icon: "Info"
12
+ },
13
+ {
14
+ title: "Contact",
15
+ description: "Get in touch \u2014 form, map, and social links.",
16
+ to: "/extras/contact",
17
+ icon: "Mail"
18
+ },
19
+ {
20
+ title: "Newsletter",
21
+ description: "Subscribe for weekly curated stories and exclusive content.",
22
+ to: "/extras/newsletter",
23
+ icon: "Newspaper"
24
+ },
25
+ {
26
+ title: "Membership",
27
+ description: "Premium plans, benefits comparison, and pricing.",
28
+ to: "/extras/membership",
29
+ icon: "Crown"
30
+ },
31
+ {
32
+ title: "Content Blocks",
33
+ description: "Callouts, code snippets, quotes, tables, CTAs, and more.",
34
+ to: "/extras/content-blocks",
35
+ icon: "Layers"
36
+ },
37
+ {
38
+ title: "Resources",
39
+ description: "Curated links, tools, and references for creators.",
40
+ to: "/extras/resources",
41
+ icon: "Sparkles"
42
+ },
43
+ {
44
+ title: "Mosaic",
45
+ description: "A visual mosaic of images from our blog posts.",
46
+ to: "/extras/showcase",
47
+ icon: "Palette"
48
+ },
49
+ {
50
+ title: "Authors",
51
+ description: "Meet the writers behind the stories.",
52
+ to: "/extras/authors",
53
+ icon: "Users"
54
+ },
55
+ {
56
+ title: "Categories",
57
+ description: "Browse all post categories in one place.",
58
+ to: "/extras/categories",
59
+ icon: "Tag"
60
+ },
61
+ {
62
+ title: "Search",
63
+ description: "Find posts by keyword, category, or author with flexible filters.",
64
+ to: "/extras/search",
65
+ icon: "Search"
66
+ },
67
+ {
68
+ title: "Search (Compact)",
69
+ description: "Same search with filters always in a slide-out drawer.",
70
+ to: "/extras/search-compact",
71
+ icon: "Search"
72
+ },
73
+ {
74
+ title: "Chat",
75
+ description: "AI chatbot demo with conversational interface.",
76
+ to: "/extras/chat",
77
+ icon: "MessageCircle"
78
+ },
79
+ {
80
+ title: "Privacy Policy",
81
+ description: "How we handle your data and protect your privacy.",
82
+ to: "/extras/privacy",
83
+ icon: "Shield"
84
+ },
85
+ {
86
+ title: "Terms of Service",
87
+ description: "Rules and conditions for using the site.",
88
+ to: "/extras/terms",
89
+ icon: "FileText"
90
+ }
91
+ ];
92
+ function ExtrasHubPage({ items = defaultItems }) {
93
+ return /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, className: "sg:max-w-3xl", children: /* @__PURE__ */ jsxs(
94
+ motion.div,
95
+ {
96
+ initial: { opacity: 0, y: 20 },
97
+ animate: { opacity: 1, y: 0 },
98
+ transition: { duration: 0.3 },
99
+ children: [
100
+ /* @__PURE__ */ jsx(Heading, { variant: "h1", className: "sg:mb-2", children: "Extras" }),
101
+ /* @__PURE__ */ jsx(Text, { foreground: "muted-foreground", className: "sg:mb-10", children: "Bonus content and additional pages." }),
102
+ /* @__PURE__ */ jsx("div", { className: "sg:grid sg:gap-4 sm:sg:grid-cols-2", children: items.map((item) => /* @__PURE__ */ jsx(ExtrasHubCard, { item }, item.to)) })
103
+ ]
104
+ }
105
+ ) }) });
106
+ }
107
+ export {
108
+ ExtrasHubPage
109
+ };
110
+ //# sourceMappingURL=extras-hub-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/pages/extras/extras-hub-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { motion } from \"framer-motion\";\r\nimport { Layout, Heading, Text } from \"../../primitives/index\";\r\nimport { ExtrasHubCard, type ExtrasHubItem } from \"../../blocks/extras/extras-hub-card\";\r\n\r\nconst defaultItems: ExtrasHubItem[] = [\r\n\t{\r\n\t\ttitle: \"About\",\r\n\t\tdescription: \"Our mission, story, team, and journey.\",\r\n\t\tto: \"/extras/about\",\r\n\t\ticon: \"Info\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Contact\",\r\n\t\tdescription: \"Get in touch — form, map, and social links.\",\r\n\t\tto: \"/extras/contact\",\r\n\t\ticon: \"Mail\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Newsletter\",\r\n\t\tdescription: \"Subscribe for weekly curated stories and exclusive content.\",\r\n\t\tto: \"/extras/newsletter\",\r\n\t\ticon: \"Newspaper\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Membership\",\r\n\t\tdescription: \"Premium plans, benefits comparison, and pricing.\",\r\n\t\tto: \"/extras/membership\",\r\n\t\ticon: \"Crown\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Content Blocks\",\r\n\t\tdescription: \"Callouts, code snippets, quotes, tables, CTAs, and more.\",\r\n\t\tto: \"/extras/content-blocks\",\r\n\t\ticon: \"Layers\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Resources\",\r\n\t\tdescription: \"Curated links, tools, and references for creators.\",\r\n\t\tto: \"/extras/resources\",\r\n\t\ticon: \"Sparkles\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Mosaic\",\r\n\t\tdescription: \"A visual mosaic of images from our blog posts.\",\r\n\t\tto: \"/extras/showcase\",\r\n\t\ticon: \"Palette\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Authors\",\r\n\t\tdescription: \"Meet the writers behind the stories.\",\r\n\t\tto: \"/extras/authors\",\r\n\t\ticon: \"Users\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Categories\",\r\n\t\tdescription: \"Browse all post categories in one place.\",\r\n\t\tto: \"/extras/categories\",\r\n\t\ticon: \"Tag\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Search\",\r\n\t\tdescription: \"Find posts by keyword, category, or author with flexible filters.\",\r\n\t\tto: \"/extras/search\",\r\n\t\ticon: \"Search\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Search (Compact)\",\r\n\t\tdescription: \"Same search with filters always in a slide-out drawer.\",\r\n\t\tto: \"/extras/search-compact\",\r\n\t\ticon: \"Search\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Chat\",\r\n\t\tdescription: \"AI chatbot demo with conversational interface.\",\r\n\t\tto: \"/extras/chat\",\r\n\t\ticon: \"MessageCircle\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Privacy Policy\",\r\n\t\tdescription: \"How we handle your data and protect your privacy.\",\r\n\t\tto: \"/extras/privacy\",\r\n\t\ticon: \"Shield\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Terms of Service\",\r\n\t\tdescription: \"Rules and conditions for using the site.\",\r\n\t\tto: \"/extras/terms\",\r\n\t\ticon: \"FileText\",\r\n\t},\r\n];\r\n\r\ntype Props = {\r\n\titems?: ExtrasHubItem[];\r\n};\r\n\r\nexport function ExtrasHubPage({ items = defaultItems }: Props) {\r\n\treturn (\r\n\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t<Layout.Col1 hideDiv className=\"sg:max-w-3xl\">\r\n\t\t\t\t<motion.div\r\n\t\t\t\t\tinitial={{ opacity: 0, y: 20 }}\r\n\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\r\n\t\t\t\t\ttransition={{ duration: 0.3 }}\r\n\t\t\t\t>\r\n\t\t\t\t\t<Heading variant=\"h1\" className=\"sg:mb-2\">\r\n\t\t\t\t\t\tExtras\r\n\t\t\t\t\t</Heading>\r\n\t\t\t\t\t<Text foreground=\"muted-foreground\" className=\"sg:mb-10\">\r\n\t\t\t\t\t\tBonus content and additional pages.\r\n\t\t\t\t\t</Text>\r\n\t\t\t\t\t<div className=\"sg:grid sg:gap-4 sm:sg:grid-cols-2\">\r\n\t\t\t\t\t\t{items.map((item) => (\r\n\t\t\t\t\t\t\t<ExtrasHubCard key={item.to} item={item} />\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</motion.div>\r\n\t\t\t</Layout.Col1>\r\n\t\t</Layout>\r\n\t);\r\n}\r\n"],"mappings":";AAqGI,SAKC,KALD;AAnGJ,SAAS,cAAc;AACvB,SAAS,QAAQ,SAAS,YAAY;AACtC,SAAS,qBAAyC;AAElD,MAAM,eAAgC;AAAA,EACrC;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AAAA,EACA;AAAA,IACC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,IAAI;AAAA,IACJ,MAAM;AAAA,EACP;AACD;AAMO,SAAS,cAAc,EAAE,QAAQ,aAAa,GAAU;AAC9D,SACC,oBAAC,UAAO,MAAK,OAAM,WAAU,YAC5B,8BAAC,OAAO,MAAP,EAAY,SAAO,MAAC,WAAU,gBAC9B;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MACA,SAAS,EAAE,SAAS,GAAG,GAAG,GAAG;AAAA,MAC7B,SAAS,EAAE,SAAS,GAAG,GAAG,EAAE;AAAA,MAC5B,YAAY,EAAE,UAAU,IAAI;AAAA,MAE5B;AAAA,4BAAC,WAAQ,SAAQ,MAAK,WAAU,WAAU,oBAE1C;AAAA,QACA,oBAAC,QAAK,YAAW,oBAAmB,WAAU,YAAW,iDAEzD;AAAA,QACA,oBAAC,SAAI,WAAU,sCACb,gBAAM,IAAI,CAAC,SACX,oBAAC,iBAA4B,QAAT,KAAK,EAAgB,CACzC,GACF;AAAA;AAAA;AAAA,EACD,GACD,GACD;AAEF;","names":[]}
@@ -1,11 +1,25 @@
1
+ export { AboutPage } from './about/about-page.js';
1
2
  export { AdminPage, AdminPageProps } from './admin/admin-page.js';
3
+ export { AuthorPage } from './author/author-page.js';
4
+ export { AuthorsPage } from './authors/authors-page.js';
2
5
  export { BlogPost } from './blogpost/blogpost.js';
6
+ export { CategoriesPage } from './categories/categories-page.js';
3
7
  export { CategoryPage } from './category/category-page.js';
8
+ export { ChatPage } from './chat/chat-page.js';
9
+ export { ContactPage } from './contact/contact-page.js';
10
+ export { ContentBlocksPage } from './content-blocks/content-blocks-page.js';
11
+ export { ExtrasHubPage } from './extras/extras-hub-page.js';
4
12
  export { LoginPage } from './login/login-page.js';
5
13
  export { MaintenancePage } from './maintenance/maintenance-page.js';
14
+ export { MembershipPage } from './membership/membership-page.js';
15
+ export { MosaicPage } from './mosaic/mosaic-page.js';
16
+ export { NewsletterPage } from './newsletter/newsletter-page.js';
6
17
  export { NotFound } from './not-found/not-found.js';
7
18
  export { PrivacyPage } from './privacy/privacy-page.js';
19
+ export { ResourcesPage } from './resources/resources-page.js';
8
20
  export { SearchPage } from './search/search-page.js';
9
21
  export { StartPage } from './startpage/startpage.js';
10
22
  export { TermsPage } from './terms/terms-page.js';
11
23
  import 'react';
24
+ import '../blocks/extras/extras-hub-card.js';
25
+ import 'lucide-react';
@@ -1,10 +1,22 @@
1
+ export * from "./about/about-page.js";
1
2
  export * from "./admin/admin-page.js";
3
+ export * from "./author/author-page.js";
4
+ export * from "./authors/authors-page.js";
2
5
  export * from "./blogpost/blogpost.js";
6
+ export * from "./categories/categories-page.js";
3
7
  export * from "./category/category-page.js";
8
+ export * from "./chat/chat-page.js";
9
+ export * from "./contact/contact-page.js";
10
+ export * from "./content-blocks/content-blocks-page.js";
11
+ export * from "./extras/extras-hub-page.js";
4
12
  export * from "./login/login-page.js";
5
13
  export * from "./maintenance/maintenance-page.js";
14
+ export * from "./membership/membership-page.js";
15
+ export * from "./mosaic/mosaic-page.js";
16
+ export * from "./newsletter/newsletter-page.js";
6
17
  export * from "./not-found/not-found.js";
7
18
  export * from "./privacy/privacy-page.js";
19
+ export * from "./resources/resources-page.js";
8
20
  export * from "./search/search-page.js";
9
21
  export * from "./startpage/startpage.js";
10
22
  export * from "./terms/terms-page.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/pages/index.ts"],"sourcesContent":["/**\n * Pages index\n *\n * Please keep exports sorted alphabetically by path!\n */\n\nexport * from \"./admin/admin-page\";\nexport * from \"./blogpost/blogpost\";\nexport * from \"./category/category-page\";\nexport * from \"./login/login-page\";\nexport * from \"./maintenance/maintenance-page\";\nexport * from \"./not-found/not-found\";\nexport * from \"./privacy/privacy-page\";\nexport * from \"./search/search-page\";\nexport * from \"./startpage/startpage\";\nexport * from \"./terms/terms-page\";\n"],"mappings":"AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/pages/index.ts"],"sourcesContent":["/**\n * Pages index\n *\n * Please keep exports sorted alphabetically by path!\n */\n\nexport * from \"./about/about-page\";\nexport * from \"./admin/admin-page\";\nexport * from \"./author/author-page\";\nexport * from \"./authors/authors-page\";\nexport * from \"./blogpost/blogpost\";\nexport * from \"./categories/categories-page\";\nexport * from \"./category/category-page\";\nexport * from \"./chat/chat-page\";\nexport * from \"./contact/contact-page\";\nexport * from \"./content-blocks/content-blocks-page\";\nexport * from \"./extras/extras-hub-page\";\nexport * from \"./login/login-page\";\nexport * from \"./maintenance/maintenance-page\";\nexport * from \"./membership/membership-page\";\nexport * from \"./mosaic/mosaic-page\";\nexport * from \"./newsletter/newsletter-page\";\nexport * from \"./not-found/not-found\";\nexport * from \"./privacy/privacy-page\";\nexport * from \"./resources/resources-page\";\nexport * from \"./search/search-page\";\nexport * from \"./startpage/startpage\";\nexport * from \"./terms/terms-page\";\n"],"mappings":"AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+
3
+ declare function MembershipPage(): React.JSX.Element;
4
+
5
+ export { MembershipPage };