singularity-components 0.1.194 → 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.
- package/dist/components/blocks/badges/category-badge.d.ts +11 -0
- package/dist/components/blocks/badges/category-badge.js +34 -0
- package/dist/components/blocks/badges/category-badge.js.map +1 -0
- package/dist/components/blocks/cards/blogpost-card.d.ts +4 -2
- package/dist/components/blocks/cards/blogpost-card.js +9 -4
- package/dist/components/blocks/cards/blogpost-card.js.map +1 -1
- package/dist/components/blocks/cards/card.d.ts +7 -8
- package/dist/components/blocks/directory/author-card.d.ts +10 -0
- package/dist/components/blocks/directory/author-card.js +50 -0
- package/dist/components/blocks/directory/author-card.js.map +1 -0
- package/dist/components/blocks/directory/category-card.d.ts +10 -0
- package/dist/components/blocks/directory/category-card.js +26 -0
- package/dist/components/blocks/directory/category-card.js.map +1 -0
- package/dist/components/blocks/empty-state/EmptyState.d.ts +2 -2
- package/dist/components/blocks/extras/extras-hub-card.d.ts +16 -0
- package/dist/components/blocks/extras/extras-hub-card.js +21 -0
- package/dist/components/blocks/extras/extras-hub-card.js.map +1 -0
- package/dist/components/blocks/gallery/image-gallery.d.ts +14 -0
- package/dist/components/blocks/gallery/image-gallery.js +211 -0
- package/dist/components/blocks/gallery/image-gallery.js.map +1 -0
- package/dist/components/blocks/index.d.ts +12 -1
- package/dist/components/blocks/index.js +11 -0
- package/dist/components/blocks/index.js.map +1 -1
- package/dist/components/blocks/loading/loading-skeletons.d.ts +15 -0
- package/dist/components/blocks/loading/loading-skeletons.js +78 -0
- package/dist/components/blocks/loading/loading-skeletons.js.map +1 -0
- package/dist/components/blocks/login/login.d.ts +78 -0
- package/dist/components/blocks/login/login.js +95 -0
- package/dist/components/blocks/login/login.js.map +1 -0
- package/dist/components/blocks/marketing/page-hero.d.ts +13 -0
- package/dist/components/blocks/marketing/page-hero.js +37 -0
- package/dist/components/blocks/marketing/page-hero.js.map +1 -0
- package/dist/components/blocks/marketing/stats-grid.d.ts +16 -0
- package/dist/components/blocks/marketing/stats-grid.js +30 -0
- package/dist/components/blocks/marketing/stats-grid.js.map +1 -0
- package/dist/components/blocks/marketing/timeline.d.ts +17 -0
- package/dist/components/blocks/marketing/timeline.js +45 -0
- package/dist/components/blocks/marketing/timeline.js.map +1 -0
- package/dist/components/blocks/marketing/values-grid.d.ts +16 -0
- package/dist/components/blocks/marketing/values-grid.js +29 -0
- package/dist/components/blocks/marketing/values-grid.js.map +1 -0
- package/dist/components/blocks/post-list/post-filters.d.ts +2 -2
- package/dist/components/blocks/post-list/post-list-with-filters.d.ts +2 -2
- package/dist/components/index.d.ts +30 -3
- package/dist/components/pages/about/about-page.d.ts +5 -0
- package/dist/components/pages/about/about-page.js +161 -0
- package/dist/components/pages/about/about-page.js.map +1 -0
- package/dist/components/pages/admin/admin-page.d.ts +2 -2
- package/dist/components/pages/admin/admin-page.js +4 -1
- package/dist/components/pages/admin/admin-page.js.map +1 -1
- package/dist/components/pages/author/author-page.d.ts +8 -0
- package/dist/components/pages/author/author-page.js +107 -0
- package/dist/components/pages/author/author-page.js.map +1 -0
- package/dist/components/pages/authors/authors-page.d.ts +5 -0
- package/dist/components/pages/authors/authors-page.js +25 -0
- package/dist/components/pages/authors/authors-page.js.map +1 -0
- package/dist/components/pages/blogpost/blogpost.d.ts +5 -2
- package/dist/components/pages/blogpost/blogpost.js +38 -18
- package/dist/components/pages/blogpost/blogpost.js.map +1 -1
- package/dist/components/pages/categories/categories-page.d.ts +5 -0
- package/dist/components/pages/categories/categories-page.js +33 -0
- package/dist/components/pages/categories/categories-page.js.map +1 -0
- package/dist/components/pages/category/category-page.d.ts +2 -2
- package/dist/components/pages/category/category-page.js +3 -1
- package/dist/components/pages/category/category-page.js.map +1 -1
- package/dist/components/pages/chat/chat-page.d.ts +2 -2
- package/dist/components/pages/contact/contact-page.d.ts +5 -0
- package/dist/components/pages/contact/contact-page.js +173 -0
- package/dist/components/pages/contact/contact-page.js.map +1 -0
- package/dist/components/pages/content-blocks/content-blocks-page.d.ts +5 -0
- package/dist/components/pages/content-blocks/content-blocks-page.js +86 -0
- package/dist/components/pages/content-blocks/content-blocks-page.js.map +1 -0
- package/dist/components/pages/extras/extras-hub-page.d.ts +10 -0
- package/dist/components/pages/extras/extras-hub-page.js +110 -0
- package/dist/components/pages/extras/extras-hub-page.js.map +1 -0
- package/dist/components/pages/index.d.ts +15 -1
- package/dist/components/pages/index.js +12 -0
- package/dist/components/pages/index.js.map +1 -1
- package/dist/components/pages/login/login-page.d.ts +2 -2
- package/dist/components/pages/login/login-page.js +19 -69
- package/dist/components/pages/login/login-page.js.map +1 -1
- package/dist/components/pages/maintenance/maintenance-page.d.ts +2 -2
- package/dist/components/pages/membership/membership-page.d.ts +5 -0
- package/dist/components/pages/membership/membership-page.js +131 -0
- package/dist/components/pages/membership/membership-page.js.map +1 -0
- package/dist/components/pages/mosaic/mosaic-page.d.ts +5 -0
- package/dist/components/pages/mosaic/mosaic-page.js +81 -0
- package/dist/components/pages/mosaic/mosaic-page.js.map +1 -0
- package/dist/components/pages/newsletter/newsletter-page.d.ts +5 -0
- package/dist/components/pages/newsletter/newsletter-page.js +148 -0
- package/dist/components/pages/newsletter/newsletter-page.js.map +1 -0
- package/dist/components/pages/not-found/not-found.d.ts +2 -2
- package/dist/components/pages/privacy/privacy-page.d.ts +2 -2
- package/dist/components/pages/resources/resources-page.d.ts +5 -0
- package/dist/components/pages/resources/resources-page.js +24 -0
- package/dist/components/pages/resources/resources-page.js.map +1 -0
- package/dist/components/pages/search/search-page.d.ts +2 -2
- package/dist/components/pages/startpage/startpage.d.ts +2 -2
- package/dist/components/pages/startpage/startpage.js +6 -4
- package/dist/components/pages/startpage/startpage.js.map +1 -1
- package/dist/components/pages/terms/terms-page.d.ts +2 -2
- package/dist/components/primitives/accordion/accordion.d.ts +5 -5
- package/dist/components/primitives/accordion/accordion.js +14 -16
- package/dist/components/primitives/accordion/accordion.js.map +1 -1
- package/dist/components/primitives/alert/alert.d.ts +4 -5
- package/dist/components/primitives/avatar/avatar.d.ts +6 -7
- package/dist/components/primitives/badge/badge.js +1 -1
- package/dist/components/primitives/badge/badge.js.map +1 -1
- package/dist/components/primitives/badge/badges.d.ts +1 -2
- package/dist/components/primitives/buttons/button.d.ts +4 -4
- package/dist/components/primitives/buttons/icon-button.d.ts +3 -3
- package/dist/components/primitives/buttons/link-button.d.ts +2 -3
- package/dist/components/primitives/collapsible/collapsible.d.ts +3 -4
- package/dist/components/primitives/collapsible/collapsible.js +4 -1
- package/dist/components/primitives/collapsible/collapsible.js.map +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu.d.ts +1 -2
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js +6 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/primitives/forms/checkbox.d.ts +2 -2
- package/dist/components/primitives/forms/checkbox.js +1 -1
- package/dist/components/primitives/forms/checkbox.js.map +1 -1
- package/dist/components/primitives/forms/field.d.ts +14 -13
- package/dist/components/primitives/forms/field.js +4 -2
- package/dist/components/primitives/forms/field.js.map +1 -1
- package/dist/components/primitives/forms/form-control.d.ts +28 -0
- package/dist/components/primitives/forms/form-control.js +40 -0
- package/dist/components/primitives/forms/form-control.js.map +1 -0
- package/dist/components/primitives/forms/form.d.ts +12 -0
- package/dist/components/primitives/forms/form.js +30 -0
- package/dist/components/primitives/forms/form.js.map +1 -0
- package/dist/components/primitives/forms/input.d.ts +1 -2
- package/dist/components/primitives/forms/select.d.ts +7 -8
- package/dist/components/primitives/forms/select.js +12 -12
- package/dist/components/primitives/forms/select.js.map +1 -1
- package/dist/components/primitives/forms/textarea.d.ts +1 -2
- package/dist/components/primitives/icon/icon.d.ts +4 -4
- package/dist/components/primitives/icon/icon.js +2 -1
- package/dist/components/primitives/icon/icon.js.map +1 -1
- package/dist/components/primitives/index.d.ts +6 -3
- package/dist/components/primitives/index.js +3 -0
- package/dist/components/primitives/index.js.map +1 -1
- package/dist/components/primitives/label/label.d.ts +1 -2
- package/dist/components/primitives/layout/layout.d.ts +5 -4
- package/dist/components/primitives/layout/layout.js.map +1 -1
- package/dist/components/primitives/link/link.d.ts +4 -5
- package/dist/components/primitives/separator/separator.d.ts +2 -2
- package/dist/components/primitives/sheet/sheet.d.ts +2 -3
- package/dist/components/primitives/sheet/sheet.js +1 -1
- package/dist/components/primitives/sheet/sheet.js.map +1 -1
- package/dist/components/primitives/skeleton/skeleton.d.ts +2 -2
- package/dist/components/primitives/sonner/sonner.d.ts +2 -2
- package/dist/components/primitives/spinner/spinner.d.ts +2 -2
- package/dist/components/primitives/stack/stack.d.ts +47 -3
- package/dist/components/primitives/stack/stack.js +44 -42
- package/dist/components/primitives/stack/stack.js.map +1 -1
- package/dist/components/primitives/text/heading.d.ts +2 -3
- package/dist/components/primitives/text/internal/text-element.d.ts +9 -4
- package/dist/components/primitives/text/internal/text-element.js +3 -0
- package/dist/components/primitives/text/internal/text-element.js.map +1 -1
- package/dist/components/primitives/text/text-code.d.ts +3 -3
- package/dist/components/primitives/text/text-div.d.ts +2 -3
- package/dist/components/primitives/text/text-span.d.ts +2 -3
- package/dist/components/primitives/text/text-time.d.ts +2 -3
- package/dist/components/primitives/text/text.d.ts +2 -3
- package/dist/components/primitives/ui-image/ui-image.d.ts +2 -3
- package/dist/components/primitives/ui-link/ui-link.d.ts +2 -3
- package/dist/components/providers/SingularityContext.d.ts +0 -1
- package/dist/components/providers/auth-provider.d.ts +2 -2
- package/dist/components/providers/index.d.ts +0 -1
- package/dist/components/providers/theme-provider.d.ts +1 -2
- package/dist/components/templates/container/container.d.ts +4 -5
- package/dist/components/templates/footer/footer.d.ts +2 -2
- package/dist/components/templates/form/form.d.ts +2 -2
- package/dist/components/templates/hero/hero.d.ts +2 -2
- package/dist/components/templates/index.d.ts +1 -1
- package/dist/components/templates/index.js +1 -0
- package/dist/components/templates/index.js.map +1 -1
- package/dist/components/templates/loading-screen/loading-screen.d.ts +10 -0
- package/dist/components/templates/loading-screen/loading-screen.js +39 -0
- package/dist/components/templates/loading-screen/loading-screen.js.map +1 -0
- package/dist/components/templates/navigation/header.d.ts +1 -2
- package/dist/components/templates/navigation/index.d.ts +0 -1
- package/dist/css/variables.css +2 -0
- package/dist/css/variables.css.map +1 -1
- package/dist/data/posts.d.ts +5 -0
- package/dist/data/posts.js +37 -4
- package/dist/data/posts.js.map +1 -1
- package/dist/index.d.ts +30 -3
- package/dist/lib/forms/field-props.d.ts +60 -0
- package/dist/lib/forms/field-props.js +60 -0
- package/dist/lib/forms/field-props.js.map +1 -0
- package/dist/lib/forms/index.d.ts +11 -0
- package/dist/lib/forms/index.js +3 -0
- package/dist/lib/forms/index.js.map +1 -0
- package/dist/lib/forms/tanstack-field.d.ts +56 -0
- package/dist/lib/forms/tanstack-field.js +114 -0
- package/dist/lib/forms/tanstack-field.js.map +1 -0
- package/dist/lib/index.d.ts +11 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/main.css +442 -117
- package/dist/main.css.map +1 -1
- package/package.json +64 -39
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './blocks/cards/card.js';
|
|
2
|
+
export { AuthorCard } from './blocks/directory/author-card.js';
|
|
3
|
+
export { CategoryCard } from './blocks/directory/category-card.js';
|
|
4
|
+
export { ExtrasHubCard, ExtrasHubItem } from './blocks/extras/extras-hub-card.js';
|
|
5
|
+
export { GalleryImage } from './blocks/gallery/image-gallery.js';
|
|
6
|
+
export { CommentSkeleton, PostCardSkeleton, PostListRowSkeleton, PostListSkeleton, SinglePostSkeleton } from './blocks/loading/loading-skeletons.js';
|
|
7
|
+
export { Login, LoginCredentials, LoginProps } from './blocks/login/login.js';
|
|
8
|
+
export { PageHero } from './blocks/marketing/page-hero.js';
|
|
9
|
+
export { StatItem, StatsGrid } from './blocks/marketing/stats-grid.js';
|
|
10
|
+
export { Timeline, TimelineItem } from './blocks/marketing/timeline.js';
|
|
11
|
+
export { ValueItem, ValuesGrid } from './blocks/marketing/values-grid.js';
|
|
2
12
|
export { PostListWithFilters } from './blocks/post-list/post-list-with-filters.js';
|
|
13
|
+
export { AboutPage } from './pages/about/about-page.js';
|
|
3
14
|
export { AdminPage, AdminPageProps } from './pages/admin/admin-page.js';
|
|
15
|
+
export { AuthorPage } from './pages/author/author-page.js';
|
|
16
|
+
export { AuthorsPage } from './pages/authors/authors-page.js';
|
|
4
17
|
export { BlogPost } from './pages/blogpost/blogpost.js';
|
|
18
|
+
export { CategoriesPage } from './pages/categories/categories-page.js';
|
|
5
19
|
export { CategoryPage } from './pages/category/category-page.js';
|
|
20
|
+
export { ChatPage } from './pages/chat/chat-page.js';
|
|
21
|
+
export { ContactPage } from './pages/contact/contact-page.js';
|
|
22
|
+
export { ContentBlocksPage } from './pages/content-blocks/content-blocks-page.js';
|
|
23
|
+
export { ExtrasHubPage } from './pages/extras/extras-hub-page.js';
|
|
6
24
|
export { LoginPage } from './pages/login/login-page.js';
|
|
7
25
|
export { MaintenancePage } from './pages/maintenance/maintenance-page.js';
|
|
26
|
+
export { MembershipPage } from './pages/membership/membership-page.js';
|
|
27
|
+
export { MosaicPage } from './pages/mosaic/mosaic-page.js';
|
|
28
|
+
export { NewsletterPage } from './pages/newsletter/newsletter-page.js';
|
|
8
29
|
export { NotFound } from './pages/not-found/not-found.js';
|
|
9
30
|
export { PrivacyPage } from './pages/privacy/privacy-page.js';
|
|
31
|
+
export { ResourcesPage } from './pages/resources/resources-page.js';
|
|
10
32
|
export { SearchPage } from './pages/search/search-page.js';
|
|
11
33
|
export { StartPage } from './pages/startpage/startpage.js';
|
|
12
34
|
export { TermsPage } from './pages/terms/terms-page.js';
|
|
@@ -20,6 +42,9 @@ export { LinkButton } from './primitives/buttons/link-button.js';
|
|
|
20
42
|
export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './primitives/collapsible/collapsible.js';
|
|
21
43
|
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './primitives/dropdown-menu/dropdown-menu.js';
|
|
22
44
|
export { Checkbox } from './primitives/forms/checkbox.js';
|
|
45
|
+
export { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle } from './primitives/forms/field.js';
|
|
46
|
+
export { Form, FormActions } from './primitives/forms/form.js';
|
|
47
|
+
export { FormControl } from './primitives/forms/form-control.js';
|
|
23
48
|
export { Input } from './primitives/forms/input.js';
|
|
24
49
|
export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './primitives/forms/select.js';
|
|
25
50
|
export { Textarea } from './primitives/forms/textarea.js';
|
|
@@ -32,7 +57,7 @@ export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHe
|
|
|
32
57
|
export { Skeleton } from './primitives/skeleton/skeleton.js';
|
|
33
58
|
export { Toaster } from './primitives/sonner/sonner.js';
|
|
34
59
|
export { Spinner } from './primitives/spinner/spinner.js';
|
|
35
|
-
export { Stack, StackProps, stackVariants } from './primitives/stack/stack.js';
|
|
60
|
+
export { Stack, StackProps, stackVariantOptions, stackVariants } from './primitives/stack/stack.js';
|
|
36
61
|
export { Heading, HeadingProps, headingVariants, headingVariantsProps } from './primitives/text/heading.js';
|
|
37
62
|
export { TextCode, TextCodeProps, textCodeVariants, textCodeVariantsProps } from './primitives/text/text-code.js';
|
|
38
63
|
export { TextDiv } from './primitives/text/text-div.js';
|
|
@@ -48,20 +73,22 @@ export { AuthProvider, useAuth } from './providers/auth-provider.js';
|
|
|
48
73
|
export { Theme, ThemeProvider, ThemeProviderProps, ThemeProviderState, useTheme } from './providers/theme-provider.js';
|
|
49
74
|
export { Container } from './templates/container/container.js';
|
|
50
75
|
export { Footer } from './templates/footer/footer.js';
|
|
76
|
+
export { LoadingScreen } from './templates/loading-screen/loading-screen.js';
|
|
51
77
|
export { Header, HeaderProps, NavLink } from './templates/navigation/header.js';
|
|
52
78
|
export { toast } from 'sonner';
|
|
53
|
-
import 'react/jsx-runtime';
|
|
54
79
|
import 'react';
|
|
80
|
+
import '../data/authors.js';
|
|
81
|
+
import 'lucide-react';
|
|
55
82
|
import '../data/posts.js';
|
|
56
83
|
import '@base-ui/react/accordion';
|
|
57
84
|
import 'class-variance-authority/types';
|
|
58
85
|
import 'class-variance-authority';
|
|
59
86
|
import '@base-ui/react/use-render';
|
|
60
87
|
import '@base-ui/react/button';
|
|
61
|
-
import 'lucide-react';
|
|
62
88
|
import '@radix-ui/react-collapsible';
|
|
63
89
|
import '@radix-ui/react-dropdown-menu';
|
|
64
90
|
import '@base-ui/react';
|
|
91
|
+
import '../lib/forms/field-props.js';
|
|
65
92
|
import '@base-ui/react/separator';
|
|
66
93
|
import '@radix-ui/react-dialog';
|
|
67
94
|
import './primitives/text/internal/text-element.js';
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { motion } from "framer-motion";
|
|
4
|
+
import { Layout, Heading, Text, Icon, Separator } from "../../primitives/index.js";
|
|
5
|
+
import { PageHero } from "../../blocks/marketing/page-hero.js";
|
|
6
|
+
import { StatsGrid } from "../../blocks/marketing/stats-grid.js";
|
|
7
|
+
import { Timeline } from "../../blocks/marketing/timeline.js";
|
|
8
|
+
import { ValuesGrid } from "../../blocks/marketing/values-grid.js";
|
|
9
|
+
import { Card, CardContent } from "../../blocks/cards/card.js";
|
|
10
|
+
import {
|
|
11
|
+
Avatar,
|
|
12
|
+
AvatarFallback,
|
|
13
|
+
AvatarImage
|
|
14
|
+
} from "../../primitives/avatar/avatar.js";
|
|
15
|
+
import { Link } from "../../primitives/link/link.js";
|
|
16
|
+
import { authors } from "../../../data/authors.js";
|
|
17
|
+
import { posts } from "../../../data/posts.js";
|
|
18
|
+
const stats = [
|
|
19
|
+
{
|
|
20
|
+
label: "Articles Published",
|
|
21
|
+
value: posts.length.toString(),
|
|
22
|
+
icon: "BookOpen"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
label: "Contributing Writers",
|
|
26
|
+
value: authors.length.toString(),
|
|
27
|
+
icon: "Users"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: "Categories Covered",
|
|
31
|
+
value: [...new Set(posts.flatMap((p) => p.categories))].length.toString(),
|
|
32
|
+
icon: "TrendingUp"
|
|
33
|
+
},
|
|
34
|
+
{ label: "Years Running", value: "3", icon: "Calendar" }
|
|
35
|
+
];
|
|
36
|
+
const timeline = [
|
|
37
|
+
{
|
|
38
|
+
year: "2023",
|
|
39
|
+
title: "The Beginning",
|
|
40
|
+
description: "Launched as a personal blog about slow living and intentional design."
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
year: "2023",
|
|
44
|
+
title: "Growing the Team",
|
|
45
|
+
description: "New contributing writers expanded coverage into culture and design."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
year: "2024",
|
|
49
|
+
title: "Community & Resources",
|
|
50
|
+
description: "Introduced the Resources hub and Mosaic gallery. Readership doubled."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
year: "2025",
|
|
54
|
+
title: "New Horizons",
|
|
55
|
+
description: "Expanded categories, launched chat, and hit a milestone of regular readers."
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
const values = [
|
|
59
|
+
{
|
|
60
|
+
title: "Depth over speed",
|
|
61
|
+
description: "We take time to research, write, and edit. Every piece earns its place."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
title: "Beauty in simplicity",
|
|
65
|
+
description: "Clean design, honest words, and images that breathe."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
title: "Community first",
|
|
69
|
+
description: "We write for curious minds who value connection and craft."
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
function AboutPage() {
|
|
73
|
+
return /* @__PURE__ */ jsxs(
|
|
74
|
+
motion.div,
|
|
75
|
+
{
|
|
76
|
+
initial: { opacity: 0, y: 20 },
|
|
77
|
+
animate: { opacity: 1, y: 0 },
|
|
78
|
+
transition: { duration: 0.3 },
|
|
79
|
+
children: [
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
PageHero,
|
|
82
|
+
{
|
|
83
|
+
icon: "Heart",
|
|
84
|
+
title: "About filion",
|
|
85
|
+
description: "We believe in the power of slow, intentional storytelling \u2014 depth over speed, beauty over noise, and presence over productivity."
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, className: "sg:max-w-4xl", children: /* @__PURE__ */ jsx(StatsGrid, { items: stats }) }) }),
|
|
89
|
+
/* @__PURE__ */ jsx("section", { className: "sg:bg-muted/40 sg:border-y sg:border-border", children: /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsxs(Layout.Col1, { hideDiv: true, className: "sg:max-w-3xl", children: [
|
|
90
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h2", className: "sg:mb-6", children: "Our Story" }),
|
|
91
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:space-y-4", children: [
|
|
92
|
+
/* @__PURE__ */ jsx(Text, { foreground: "muted-foreground", className: "sg:leading-relaxed", children: "What began as one writer's reflections on slow mornings and handwritten letters grew into a collective of voices united by curiosity and care." }),
|
|
93
|
+
/* @__PURE__ */ jsx(Text, { foreground: "muted-foreground", className: "sg:leading-relaxed", children: "Today, our team explores everything from minimalist design to global traditions, always with the same ethos: take your time, pay attention, and tell the story honestly." })
|
|
94
|
+
] })
|
|
95
|
+
] }) }) }),
|
|
96
|
+
/* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsxs(Layout.Col1, { hideDiv: true, className: "sg:max-w-4xl", children: [
|
|
97
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h2", className: "sg:mb-2", children: "The Team" }),
|
|
98
|
+
/* @__PURE__ */ jsx(Text, { foreground: "muted-foreground", className: "sg:mb-8", children: "The writers behind the words." }),
|
|
99
|
+
/* @__PURE__ */ jsx("div", { className: "sg:grid sg:gap-6 sm:sg:grid-cols-3", children: authors.map((author) => /* @__PURE__ */ jsx(
|
|
100
|
+
Link,
|
|
101
|
+
{
|
|
102
|
+
to: `/extras/authors/${author.slug}`,
|
|
103
|
+
variant: "no-decoration",
|
|
104
|
+
className: "sg:group",
|
|
105
|
+
children: /* @__PURE__ */ jsx(Card, { className: "sg:h-full sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40", children: /* @__PURE__ */ jsxs(CardContent, { className: "sg:pt-6 sg:text-center", children: [
|
|
106
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "sg:h-20 sg:w-20 sg:mx-auto sg:mb-3", children: [
|
|
107
|
+
/* @__PURE__ */ jsx(AvatarImage, { src: author.avatar, alt: author.name }),
|
|
108
|
+
/* @__PURE__ */ jsx(AvatarFallback, { children: author.name[0] })
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ jsx(
|
|
111
|
+
Heading,
|
|
112
|
+
{
|
|
113
|
+
variant: "h5",
|
|
114
|
+
className: "sg:group-hover:text-primary sg:transition-colors",
|
|
115
|
+
children: author.name
|
|
116
|
+
}
|
|
117
|
+
),
|
|
118
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", className: "sg:text-primary/80 sg:mb-2", children: author.role }),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
Text,
|
|
121
|
+
{
|
|
122
|
+
size: "sm",
|
|
123
|
+
foreground: "muted-foreground",
|
|
124
|
+
className: "sg:line-clamp-3 sg:leading-relaxed",
|
|
125
|
+
children: author.bio
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
] }) })
|
|
129
|
+
},
|
|
130
|
+
author.slug
|
|
131
|
+
)) })
|
|
132
|
+
] }) }),
|
|
133
|
+
/* @__PURE__ */ jsx(Separator, { className: "sg:max-w-3xl sg:mx-auto" }),
|
|
134
|
+
/* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, className: "sg:max-w-3xl", children: /* @__PURE__ */ jsx(
|
|
135
|
+
Timeline,
|
|
136
|
+
{
|
|
137
|
+
items: timeline,
|
|
138
|
+
description: "Key moments that shaped our journey."
|
|
139
|
+
}
|
|
140
|
+
) }) }),
|
|
141
|
+
/* @__PURE__ */ jsx("section", { className: "sg:bg-primary/5 sg:border-t sg:border-border", children: /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, className: "sg:max-w-3xl", children: /* @__PURE__ */ jsx(
|
|
142
|
+
ValuesGrid,
|
|
143
|
+
{
|
|
144
|
+
items: values,
|
|
145
|
+
icon: /* @__PURE__ */ jsx(
|
|
146
|
+
Icon,
|
|
147
|
+
{
|
|
148
|
+
icon: "Award",
|
|
149
|
+
className: "sg:h-8 sg:w-8 sg:text-primary sg:mx-auto sg:mb-4"
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
) }) }) })
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
export {
|
|
159
|
+
AboutPage
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=about-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/pages/about/about-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { motion } from \"framer-motion\";\r\nimport { Layout, Heading, Text, Icon, Separator } from \"../../primitives/index\";\r\nimport { PageHero } from \"../../blocks/marketing/page-hero\";\r\nimport { StatsGrid } from \"../../blocks/marketing/stats-grid\";\r\nimport { Timeline } from \"../../blocks/marketing/timeline\";\r\nimport { ValuesGrid } from \"../../blocks/marketing/values-grid\";\r\nimport { Card, CardContent } from \"../../blocks/cards/card\";\r\nimport {\r\n\tAvatar,\r\n\tAvatarFallback,\r\n\tAvatarImage,\r\n} from \"../../primitives/avatar/avatar\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport { authors } from \"../../../data/authors\";\r\nimport { posts } from \"../../../data/posts\";\r\n\r\nconst stats = [\r\n\t{\r\n\t\tlabel: \"Articles Published\",\r\n\t\tvalue: posts.length.toString(),\r\n\t\ticon: \"BookOpen\" as const,\r\n\t},\r\n\t{\r\n\t\tlabel: \"Contributing Writers\",\r\n\t\tvalue: authors.length.toString(),\r\n\t\ticon: \"Users\" as const,\r\n\t},\r\n\t{\r\n\t\tlabel: \"Categories Covered\",\r\n\t\tvalue: [...new Set(posts.flatMap((p) => p.categories))].length.toString(),\r\n\t\ticon: \"TrendingUp\" as const,\r\n\t},\r\n\t{ label: \"Years Running\", value: \"3\", icon: \"Calendar\" as const },\r\n];\r\n\r\nconst timeline = [\r\n\t{\r\n\t\tyear: \"2023\",\r\n\t\ttitle: \"The Beginning\",\r\n\t\tdescription:\r\n\t\t\t\"Launched as a personal blog about slow living and intentional design.\",\r\n\t},\r\n\t{\r\n\t\tyear: \"2023\",\r\n\t\ttitle: \"Growing the Team\",\r\n\t\tdescription:\r\n\t\t\t\"New contributing writers expanded coverage into culture and design.\",\r\n\t},\r\n\t{\r\n\t\tyear: \"2024\",\r\n\t\ttitle: \"Community & Resources\",\r\n\t\tdescription:\r\n\t\t\t\"Introduced the Resources hub and Mosaic gallery. Readership doubled.\",\r\n\t},\r\n\t{\r\n\t\tyear: \"2025\",\r\n\t\ttitle: \"New Horizons\",\r\n\t\tdescription:\r\n\t\t\t\"Expanded categories, launched chat, and hit a milestone of regular readers.\",\r\n\t},\r\n];\r\n\r\nconst values = [\r\n\t{\r\n\t\ttitle: \"Depth over speed\",\r\n\t\tdescription:\r\n\t\t\t\"We take time to research, write, and edit. Every piece earns its place.\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Beauty in simplicity\",\r\n\t\tdescription: \"Clean design, honest words, and images that breathe.\",\r\n\t},\r\n\t{\r\n\t\ttitle: \"Community first\",\r\n\t\tdescription:\r\n\t\t\t\"We write for curious minds who value connection and craft.\",\r\n\t},\r\n];\r\n\r\nexport function AboutPage() {\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=\"Heart\"\r\n\t\t\t\ttitle=\"About filion\"\r\n\t\t\t\tdescription=\"We believe in the power of slow, intentional storytelling — depth over speed, beauty over noise, and presence over productivity.\"\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-4xl\">\r\n\t\t\t\t\t<StatsGrid items={stats} />\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\r\n\t\t\t<section className=\"sg:bg-muted/40 sg:border-y sg:border-border\">\r\n\t\t\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t\t\t<Layout.Col1 hideDiv className=\"sg:max-w-3xl\">\r\n\t\t\t\t\t\t<Heading variant=\"h2\" className=\"sg:mb-6\">\r\n\t\t\t\t\t\t\tOur Story\r\n\t\t\t\t\t\t</Heading>\r\n\t\t\t\t\t\t<div className=\"sg:space-y-4\">\r\n\t\t\t\t\t\t\t<Text foreground=\"muted-foreground\" className=\"sg:leading-relaxed\">\r\n\t\t\t\t\t\t\t\tWhat began as one writer's reflections on slow mornings and\r\n\t\t\t\t\t\t\t\thandwritten letters grew into a collective of voices united by\r\n\t\t\t\t\t\t\t\tcuriosity and care.\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t<Text foreground=\"muted-foreground\" className=\"sg:leading-relaxed\">\r\n\t\t\t\t\t\t\t\tToday, our team explores everything from minimalist design to\r\n\t\t\t\t\t\t\t\tglobal traditions, always with the same ethos: take your time,\r\n\t\t\t\t\t\t\t\tpay attention, and tell the story honestly.\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</Layout.Col1>\r\n\t\t\t\t</Layout>\r\n\t\t\t</section>\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-4xl\">\r\n\t\t\t\t\t<Heading variant=\"h2\" className=\"sg:mb-2\">\r\n\t\t\t\t\t\tThe Team\r\n\t\t\t\t\t</Heading>\r\n\t\t\t\t\t<Text foreground=\"muted-foreground\" className=\"sg:mb-8\">\r\n\t\t\t\t\t\tThe writers behind the words.\r\n\t\t\t\t\t</Text>\r\n\t\t\t\t\t<div className=\"sg:grid sg:gap-6 sm:sg:grid-cols-3\">\r\n\t\t\t\t\t\t{authors.map((author) => (\r\n\t\t\t\t\t\t\t<Link\r\n\t\t\t\t\t\t\t\tkey={author.slug}\r\n\t\t\t\t\t\t\t\tto={`/extras/authors/${author.slug}`}\r\n\t\t\t\t\t\t\t\tvariant=\"no-decoration\"\r\n\t\t\t\t\t\t\t\tclassName=\"sg:group\"\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<Card className=\"sg:h-full sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40\">\r\n\t\t\t\t\t\t\t\t\t<CardContent className=\"sg:pt-6 sg:text-center\">\r\n\t\t\t\t\t\t\t\t\t\t<Avatar className=\"sg:h-20 sg:w-20 sg:mx-auto sg:mb-3\">\r\n\t\t\t\t\t\t\t\t\t\t\t<AvatarImage src={author.avatar} alt={author.name} />\r\n\t\t\t\t\t\t\t\t\t\t\t<AvatarFallback>{author.name[0]}</AvatarFallback>\r\n\t\t\t\t\t\t\t\t\t\t</Avatar>\r\n\t\t\t\t\t\t\t\t\t\t<Heading\r\n\t\t\t\t\t\t\t\t\t\t\tvariant=\"h5\"\r\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sg:group-hover:text-primary sg:transition-colors\"\r\n\t\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t\t{author.name}\r\n\t\t\t\t\t\t\t\t\t\t</Heading>\r\n\t\t\t\t\t\t\t\t\t\t<Text size=\"sm\" className=\"sg:text-primary/80 sg:mb-2\">\r\n\t\t\t\t\t\t\t\t\t\t\t{author.role}\r\n\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t\t<Text\r\n\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\t\t\t\tforeground=\"muted-foreground\"\r\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"sg:line-clamp-3 sg:leading-relaxed\"\r\n\t\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t\t{author.bio}\r\n\t\t\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t\t</CardContent>\r\n\t\t\t\t\t\t\t\t</Card>\r\n\t\t\t\t\t\t\t</Link>\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\r\n\t\t\t<Separator className=\"sg:max-w-3xl sg:mx-auto\" />\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\">\r\n\t\t\t\t\t<Timeline\r\n\t\t\t\t\t\titems={timeline}\r\n\t\t\t\t\t\tdescription=\"Key moments that shaped our journey.\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\r\n\t\t\t<section className=\"sg:bg-primary/5 sg:border-t sg:border-border\">\r\n\t\t\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t\t\t<Layout.Col1 hideDiv className=\"sg:max-w-3xl\">\r\n\t\t\t\t\t\t<ValuesGrid\r\n\t\t\t\t\t\t\titems={values}\r\n\t\t\t\t\t\t\ticon={\r\n\t\t\t\t\t\t\t\t<Icon\r\n\t\t\t\t\t\t\t\t\ticon=\"Award\"\r\n\t\t\t\t\t\t\t\t\tclassName=\"sg:h-8 sg:w-8 sg:text-primary sg:mx-auto sg:mb-4\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</Layout.Col1>\r\n\t\t\t\t</Layout>\r\n\t\t\t</section>\r\n\t\t</motion.div>\r\n\t);\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
3
|
interface AdminPageProps {
|
|
4
4
|
initialEditId?: number;
|
|
5
5
|
}
|
|
6
|
-
declare function AdminPage({ initialEditId }: AdminPageProps):
|
|
6
|
+
declare function AdminPage({ initialEditId }: AdminPageProps): React.JSX.Element;
|
|
7
7
|
|
|
8
8
|
export { AdminPage, type AdminPageProps };
|
|
@@ -23,6 +23,7 @@ function AdminPage({ initialEditId }) {
|
|
|
23
23
|
const { toast } = useToast();
|
|
24
24
|
const emptyPost = {
|
|
25
25
|
id: 0,
|
|
26
|
+
slug: "",
|
|
26
27
|
title: "",
|
|
27
28
|
excerpt: "",
|
|
28
29
|
content: "",
|
|
@@ -39,6 +40,7 @@ function AdminPage({ initialEditId }) {
|
|
|
39
40
|
if (post) {
|
|
40
41
|
setForm({
|
|
41
42
|
id: post.id,
|
|
43
|
+
slug: post.slug,
|
|
42
44
|
title: post.title,
|
|
43
45
|
excerpt: post.excerpt,
|
|
44
46
|
content: post.content,
|
|
@@ -66,7 +68,8 @@ function AdminPage({ initialEditId }) {
|
|
|
66
68
|
setEditing(null);
|
|
67
69
|
} else {
|
|
68
70
|
const nextId = Math.max(...postsList.map((p) => p.id), 0) + 1;
|
|
69
|
-
|
|
71
|
+
const slug = form.slug || form.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || `post-${nextId}`;
|
|
72
|
+
setPostsList((prev) => [{ ...form, id: nextId, slug }, ...prev]);
|
|
70
73
|
toast.success("Post created", {
|
|
71
74
|
description: `"${form.title}" has been published.`
|
|
72
75
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/pages/admin/admin-page.tsx"],"sourcesContent":["\"use client\";\nimport { useState, useMemo, useEffect } from \"react\";\nimport {\n Layout,\n Button,\n Input,\n Textarea,\n Label,\n Heading,\n Text,\n Icon,\n} from \"../../primitives/index\";\nimport { Card, CardContent } from \"../../blocks/index\";\nimport { posts as initialPosts, type BlogPost } from \"../../../data/posts\";\nimport { useToast } from \"../../primitives/sonner/use-toast\";\n\nconst POSTS_PER_PAGE = 5;\n\nexport interface AdminPageProps {\n initialEditId?: number;\n}\n\nexport function AdminPage({ initialEditId }: AdminPageProps) {\n const [postsList, setPostsList] = useState<BlogPost[]>(initialPosts);\n const [editing, setEditing] = useState<number | null>(null);\n const [showForm, setShowForm] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { toast } = useToast();\n\n const emptyPost: BlogPost = {\n id: 0,\n title: \"\",\n excerpt: \"\",\n content: \"\",\n primaryImage: \"\",\n originalImage: \"\",\n date: new Date().toISOString().slice(0, 10),\n author: \"Admin\",\n categories: [],\n };\n\n const [form, setForm] = useState(emptyPost);\n\n useEffect(() => {\n if (initialEditId) {\n const post = postsList.find((p) => p.id === initialEditId);\n if (post) {\n setForm({\n id: post.id,\n title: post.title,\n excerpt: post.excerpt,\n content: post.content,\n primaryImage: post.primaryImage,\n originalImage: post.originalImage,\n date: post.date,\n author: post.author,\n categories: post.categories,\n });\n setEditing(post.id);\n setShowForm(true);\n }\n }\n }, [initialEditId, postsList]);\n\n const handleSave = (e: React.FormEvent) => {\n e.preventDefault();\n if (!form.title.trim()) return;\n\n if (editing !== null) {\n setPostsList((prev) =>\n prev.map((p) => (p.id === editing ? { ...p, ...form } : p)),\n );\n toast.success(\"Post updated\", {\n description: `\"${form.title}\" has been saved.`,\n });\n setEditing(null);\n } else {\n const nextId = Math.max(...postsList.map((p) => p.id), 0) + 1;\n setPostsList((prev) => [{ ...form, id: nextId }, ...prev]);\n toast.success(\"Post created\", {\n description: `\"${form.title}\" has been published.`,\n });\n }\n\n setForm(emptyPost);\n setShowForm(false);\n };\n\n const handleEdit = (post: BlogPost) => {\n setForm(post);\n setEditing(post.id);\n setShowForm(true);\n };\n\n const [page, setPage] = useState(1);\n\n const handleDelete = (id: number) => {\n setPostsList((prev) => {\n const updated = prev.filter((p) => p.id !== id);\n const newTotalPages = Math.ceil(updated.length / POSTS_PER_PAGE);\n if (page > newTotalPages) setPage(Math.max(1, newTotalPages));\n return updated;\n });\n toast.message(\"Post deleted\");\n };\n\n const filteredPosts = useMemo(() => {\n if (!searchQuery.trim()) return postsList;\n const q = searchQuery.toLowerCase();\n return postsList.filter((p) => p.title.toLowerCase().includes(q));\n }, [postsList, searchQuery]);\n\n const totalPages = Math.ceil(filteredPosts.length / POSTS_PER_PAGE);\n const paginatedPosts = useMemo(\n () =>\n filteredPosts.slice((page - 1) * POSTS_PER_PAGE, page * POSTS_PER_PAGE),\n [filteredPosts, page],\n );\n\n return (\n <Layout type=\"col\" className=\"sg:py-16\" as=\"main\">\n <Layout.Col1 hideDiv>\n <div className=\"sg:space-y-8\">\n <div className=\"sg:flex sg:items-center sg:justify-between\">\n <div>\n <Heading variant=\"h1\">Admin</Heading>\n <Text className=\"sg:mt-1\" foreground=\"muted-foreground\">\n Manage your blog posts.\n </Text>\n </div>\n <Button\n onClick={() => {\n setShowForm(!showForm);\n setEditing(null);\n setForm(emptyPost);\n }}\n >\n <Icon icon=\"Plus\" size=\"xs\" className=\"sg:mr-1\" /> New post\n </Button>\n </div>\n\n {/* Search */}\n <div className=\"sg:relative\">\n <Icon\n icon=\"Search\"\n size=\"xs\"\n color=\"muted-foreground\"\n className=\"sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2\"\n />\n <Input\n placeholder=\"Search posts by title...\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setPage(1);\n }}\n className=\"sg:pl-9\"\n />\n </div>\n\n {/* Form */}\n {showForm && (\n <Card>\n <CardContent className=\"sg:p-6 sg:mt-6\">\n <Heading variant=\"h3\" className=\"sg:mb-4\">\n {editing !== null ? \"Edit Post\" : \"New Post\"}\n </Heading>\n <form onSubmit={handleSave} className=\"sg:space-y-4\">\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"title\">Title</Label>\n <Input\n id=\"title\"\n value={form.title}\n onChange={(e) =>\n setForm({ ...form, title: e.target.value })\n }\n required\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"excerpt\">Excerpt</Label>\n <Input\n id=\"excerpt\"\n value={form.excerpt || \"\"}\n onChange={(e) =>\n setForm({ ...form, excerpt: e.target.value })\n }\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"image\">Image URL</Label>\n <Input\n id=\"image\"\n value={form.primaryImage}\n onChange={(e) =>\n setForm({ ...form, primaryImage: e.target.value })\n }\n placeholder=\"https://...\"\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"content\">Content</Label>\n <Textarea\n id=\"content\"\n value={(form.content || \"\") as string}\n onChange={(e) =>\n setForm({\n ...form,\n content: e.target.value,\n })\n }\n className=\"sg:min-h-[200px]\"\n />\n </div>\n <div className=\"sg:flex sg:gap-2 sg:pt-2\">\n <Button type=\"submit\">\n {editing !== null ? \"Update\" : \"Publish\"}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n setShowForm(false);\n setEditing(null);\n setForm(emptyPost);\n }}\n >\n Cancel\n </Button>\n </div>\n </form>\n </CardContent>\n </Card>\n )}\n\n {/* Posts list */}\n <div className=\"sg:space-y-3\">\n {paginatedPosts.map((post) => (\n <Card key={post.id}>\n <CardContent className=\"sg:p-4 sg:flex sg:items-center sg:justify-between sg:pt-4\">\n <div className=\"sg:flex-1 sg:min-w-0\">\n <div className=\"sg:font-medium sg:truncate\">\n {post.title}\n </div>\n <Text size=\"sm\" foreground=\"muted-foreground\">\n {post.date} · {post.author}\n </Text>\n </div>\n <div className=\"sg:flex sg:gap-2 sg:ml-4\">\n <Button\n variant=\"ghost\"\n onClick={() => handleEdit(post)}\n aria-label={`Edit ${post.title}`}\n className=\"sg:px-2\"\n >\n <Icon icon=\"Pencil\" size=\"xs\" />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => handleDelete(post.id)}\n aria-label={`Delete ${post.title}`}\n className=\"sg:px-2 sg:text-destructive sg:hover:text-destructive sg:hover:bg-destructive/10\"\n >\n <Icon icon=\"Trash2\" size=\"xs\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n {paginatedPosts.length === 0 && (\n <Text\n foreground=\"muted-foreground\"\n className=\"sg:text-center sg:py-8\"\n >\n No posts found.\n </Text>\n )}\n </div>\n\n {/* Pagination */}\n {totalPages > 1 && (\n <div className=\"sg:flex sg:items-center sg:justify-center sg:gap-2 sg:pt-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page === 1}\n onClick={() => setPage(page - 1)}\n >\n <Icon icon=\"ChevronLeft\" size=\"xs\" className=\"sg:mr-1\" />{\" \"}\n Previous\n </Button>\n <Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:px-3\">\n Page {page} of {totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page === totalPages}\n onClick={() => setPage(page + 1)}\n >\n Next <Icon icon=\"ChevronRight\" size=\"xs\" className=\"sg:ml-1\" />\n </Button>\n </div>\n )}\n </div>\n </Layout.Col1>\n </Layout>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/pages/admin/admin-page.tsx"],"sourcesContent":["\"use client\";\nimport { useState, useMemo, useEffect } from \"react\";\nimport {\n Layout,\n Button,\n Input,\n Textarea,\n Label,\n Heading,\n Text,\n Icon,\n} from \"../../primitives/index\";\nimport { Card, CardContent } from \"../../blocks/index\";\nimport { posts as initialPosts, type BlogPost } from \"../../../data/posts\";\nimport { useToast } from \"../../primitives/sonner/use-toast\";\n\nconst POSTS_PER_PAGE = 5;\n\nexport interface AdminPageProps {\n initialEditId?: number;\n}\n\nexport function AdminPage({ initialEditId }: AdminPageProps) {\n const [postsList, setPostsList] = useState<BlogPost[]>(initialPosts);\n const [editing, setEditing] = useState<number | null>(null);\n const [showForm, setShowForm] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const { toast } = useToast();\n\n const emptyPost: BlogPost = {\n id: 0,\n slug: \"\",\n title: \"\",\n excerpt: \"\",\n content: \"\",\n primaryImage: \"\",\n originalImage: \"\",\n date: new Date().toISOString().slice(0, 10),\n author: \"Admin\",\n categories: [],\n };\n\n const [form, setForm] = useState(emptyPost);\n\n useEffect(() => {\n if (initialEditId) {\n const post = postsList.find((p) => p.id === initialEditId);\n if (post) {\n setForm({\n id: post.id,\n slug: post.slug,\n title: post.title,\n excerpt: post.excerpt,\n content: post.content,\n primaryImage: post.primaryImage,\n originalImage: post.originalImage,\n date: post.date,\n author: post.author,\n categories: post.categories,\n });\n setEditing(post.id);\n setShowForm(true);\n }\n }\n }, [initialEditId, postsList]);\n\n const handleSave = (e: React.FormEvent) => {\n e.preventDefault();\n if (!form.title.trim()) return;\n\n if (editing !== null) {\n setPostsList((prev) =>\n prev.map((p) => (p.id === editing ? { ...p, ...form } : p)),\n );\n toast.success(\"Post updated\", {\n description: `\"${form.title}\" has been saved.`,\n });\n setEditing(null);\n } else {\n const nextId = Math.max(...postsList.map((p) => p.id), 0) + 1;\n const slug =\n form.slug ||\n form.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\") ||\n `post-${nextId}`;\n setPostsList((prev) => [{ ...form, id: nextId, slug }, ...prev]);\n toast.success(\"Post created\", {\n description: `\"${form.title}\" has been published.`,\n });\n }\n\n setForm(emptyPost);\n setShowForm(false);\n };\n\n const handleEdit = (post: BlogPost) => {\n setForm(post);\n setEditing(post.id);\n setShowForm(true);\n };\n\n const [page, setPage] = useState(1);\n\n const handleDelete = (id: number) => {\n setPostsList((prev) => {\n const updated = prev.filter((p) => p.id !== id);\n const newTotalPages = Math.ceil(updated.length / POSTS_PER_PAGE);\n if (page > newTotalPages) setPage(Math.max(1, newTotalPages));\n return updated;\n });\n toast.message(\"Post deleted\");\n };\n\n const filteredPosts = useMemo(() => {\n if (!searchQuery.trim()) return postsList;\n const q = searchQuery.toLowerCase();\n return postsList.filter((p) => p.title.toLowerCase().includes(q));\n }, [postsList, searchQuery]);\n\n const totalPages = Math.ceil(filteredPosts.length / POSTS_PER_PAGE);\n const paginatedPosts = useMemo(\n () =>\n filteredPosts.slice((page - 1) * POSTS_PER_PAGE, page * POSTS_PER_PAGE),\n [filteredPosts, page],\n );\n\n return (\n <Layout type=\"col\" className=\"sg:py-16\" as=\"main\">\n <Layout.Col1 hideDiv>\n <div className=\"sg:space-y-8\">\n <div className=\"sg:flex sg:items-center sg:justify-between\">\n <div>\n <Heading variant=\"h1\">Admin</Heading>\n <Text className=\"sg:mt-1\" foreground=\"muted-foreground\">\n Manage your blog posts.\n </Text>\n </div>\n <Button\n onClick={() => {\n setShowForm(!showForm);\n setEditing(null);\n setForm(emptyPost);\n }}\n >\n <Icon icon=\"Plus\" size=\"xs\" className=\"sg:mr-1\" /> New post\n </Button>\n </div>\n\n {/* Search */}\n <div className=\"sg:relative\">\n <Icon\n icon=\"Search\"\n size=\"xs\"\n color=\"muted-foreground\"\n className=\"sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2\"\n />\n <Input\n placeholder=\"Search posts by title...\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setPage(1);\n }}\n className=\"sg:pl-9\"\n />\n </div>\n\n {/* Form */}\n {showForm && (\n <Card>\n <CardContent className=\"sg:p-6 sg:mt-6\">\n <Heading variant=\"h3\" className=\"sg:mb-4\">\n {editing !== null ? \"Edit Post\" : \"New Post\"}\n </Heading>\n <form onSubmit={handleSave} className=\"sg:space-y-4\">\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"title\">Title</Label>\n <Input\n id=\"title\"\n value={form.title}\n onChange={(e) =>\n setForm({ ...form, title: e.target.value })\n }\n required\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"excerpt\">Excerpt</Label>\n <Input\n id=\"excerpt\"\n value={form.excerpt || \"\"}\n onChange={(e) =>\n setForm({ ...form, excerpt: e.target.value })\n }\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"image\">Image URL</Label>\n <Input\n id=\"image\"\n value={form.primaryImage}\n onChange={(e) =>\n setForm({ ...form, primaryImage: e.target.value })\n }\n placeholder=\"https://...\"\n />\n </div>\n <div className=\"sg:space-y-2\">\n <Label htmlFor=\"content\">Content</Label>\n <Textarea\n id=\"content\"\n value={(form.content || \"\") as string}\n onChange={(e) =>\n setForm({\n ...form,\n content: e.target.value,\n })\n }\n className=\"sg:min-h-[200px]\"\n />\n </div>\n <div className=\"sg:flex sg:gap-2 sg:pt-2\">\n <Button type=\"submit\">\n {editing !== null ? \"Update\" : \"Publish\"}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => {\n setShowForm(false);\n setEditing(null);\n setForm(emptyPost);\n }}\n >\n Cancel\n </Button>\n </div>\n </form>\n </CardContent>\n </Card>\n )}\n\n {/* Posts list */}\n <div className=\"sg:space-y-3\">\n {paginatedPosts.map((post) => (\n <Card key={post.id}>\n <CardContent className=\"sg:p-4 sg:flex sg:items-center sg:justify-between sg:pt-4\">\n <div className=\"sg:flex-1 sg:min-w-0\">\n <div className=\"sg:font-medium sg:truncate\">\n {post.title}\n </div>\n <Text size=\"sm\" foreground=\"muted-foreground\">\n {post.date} · {post.author}\n </Text>\n </div>\n <div className=\"sg:flex sg:gap-2 sg:ml-4\">\n <Button\n variant=\"ghost\"\n onClick={() => handleEdit(post)}\n aria-label={`Edit ${post.title}`}\n className=\"sg:px-2\"\n >\n <Icon icon=\"Pencil\" size=\"xs\" />\n </Button>\n <Button\n variant=\"ghost\"\n onClick={() => handleDelete(post.id)}\n aria-label={`Delete ${post.title}`}\n className=\"sg:px-2 sg:text-destructive sg:hover:text-destructive sg:hover:bg-destructive/10\"\n >\n <Icon icon=\"Trash2\" size=\"xs\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n ))}\n {paginatedPosts.length === 0 && (\n <Text\n foreground=\"muted-foreground\"\n className=\"sg:text-center sg:py-8\"\n >\n No posts found.\n </Text>\n )}\n </div>\n\n {/* Pagination */}\n {totalPages > 1 && (\n <div className=\"sg:flex sg:items-center sg:justify-center sg:gap-2 sg:pt-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page === 1}\n onClick={() => setPage(page - 1)}\n >\n <Icon icon=\"ChevronLeft\" size=\"xs\" className=\"sg:mr-1\" />{\" \"}\n Previous\n </Button>\n <Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:px-3\">\n Page {page} of {totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page === totalPages}\n onClick={() => setPage(page + 1)}\n >\n Next <Icon icon=\"ChevronRight\" size=\"xs\" className=\"sg:ml-1\" />\n </Button>\n </div>\n )}\n </div>\n </Layout.Col1>\n </Layout>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { motion } from "framer-motion";
|
|
5
|
+
import {
|
|
6
|
+
Layout,
|
|
7
|
+
Heading,
|
|
8
|
+
Text,
|
|
9
|
+
TextSpan,
|
|
10
|
+
Icon,
|
|
11
|
+
Badges
|
|
12
|
+
} from "../../primitives/index.js";
|
|
13
|
+
import {
|
|
14
|
+
Avatar,
|
|
15
|
+
AvatarFallback,
|
|
16
|
+
AvatarImage
|
|
17
|
+
} from "../../primitives/avatar/avatar.js";
|
|
18
|
+
import CategoryBadge from "../../blocks/badges/category-badge.js";
|
|
19
|
+
import { LinkButton } from "../../primitives/buttons/link-button.js";
|
|
20
|
+
import { PostListWithFilters } from "../../blocks/post-list/post-list-with-filters.js";
|
|
21
|
+
import { authors } from "../../../data/authors.js";
|
|
22
|
+
import { posts } from "../../../data/posts.js";
|
|
23
|
+
function AuthorPage({ slug = "elena-marsh" }) {
|
|
24
|
+
const author = authors.find((a) => a.slug === slug);
|
|
25
|
+
const authorPosts = useMemo(
|
|
26
|
+
() => author ? posts.filter((p) => p.author === author.name) : [],
|
|
27
|
+
[author]
|
|
28
|
+
);
|
|
29
|
+
if (!author) {
|
|
30
|
+
return /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsxs(Layout.Col1, { hideDiv: true, className: "sg:text-center", children: [
|
|
31
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h2", className: "sg:mb-4", children: "Author not found" }),
|
|
32
|
+
/* @__PURE__ */ jsx(LinkButton, { variant: "outline", to: "/extras/authors", iconStart: "ArrowLeft", children: "Back to Authors" })
|
|
33
|
+
] }) });
|
|
34
|
+
}
|
|
35
|
+
return /* @__PURE__ */ jsx(Layout, { type: "col", className: "sg:py-16", children: /* @__PURE__ */ jsx(Layout.Col1, { hideDiv: true, children: /* @__PURE__ */ jsxs(
|
|
36
|
+
motion.div,
|
|
37
|
+
{
|
|
38
|
+
initial: { opacity: 0, y: 20 },
|
|
39
|
+
animate: { opacity: 1, y: 0 },
|
|
40
|
+
transition: { duration: 0.3 },
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
LinkButton,
|
|
44
|
+
{
|
|
45
|
+
variant: "ghost",
|
|
46
|
+
size: "sm",
|
|
47
|
+
to: "/extras/authors",
|
|
48
|
+
iconStart: "ArrowLeft",
|
|
49
|
+
className: "sg:mb-6",
|
|
50
|
+
children: "All Authors"
|
|
51
|
+
}
|
|
52
|
+
),
|
|
53
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:flex-col sm:sg:flex-row sg:items-start sg:gap-6 sg:mb-12", children: [
|
|
54
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "sg:h-24 sg:w-24", children: [
|
|
55
|
+
/* @__PURE__ */ jsx(AvatarImage, { src: author.avatar, alt: author.name }),
|
|
56
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "sg:text-2xl", children: author.name.split(" ").map((n) => n[0]).join("") })
|
|
57
|
+
] }),
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
59
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h1", children: author.name }),
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-center sg:gap-4 sg:mt-2", children: [
|
|
61
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", foreground: "muted-foreground", className: "sg:flex sg:items-center sg:gap-1", children: [
|
|
62
|
+
/* @__PURE__ */ jsx(Icon, { icon: "Briefcase", className: "sg:h-3.5 sg:w-3.5" }),
|
|
63
|
+
author.role
|
|
64
|
+
] }),
|
|
65
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", foreground: "muted-foreground", className: "sg:flex sg:items-center sg:gap-1", children: [
|
|
66
|
+
/* @__PURE__ */ jsx(Icon, { icon: "MapPin", className: "sg:h-3.5 sg:w-3.5" }),
|
|
67
|
+
author.location
|
|
68
|
+
] })
|
|
69
|
+
] }),
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
Text,
|
|
72
|
+
{
|
|
73
|
+
foreground: "muted-foreground",
|
|
74
|
+
className: "sg:mt-4 sg:leading-relaxed sg:max-w-2xl",
|
|
75
|
+
children: author.bio
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
/* @__PURE__ */ jsx(Badges, { className: "sg:mt-4", children: author.interests.map((interest) => /* @__PURE__ */ jsx(CategoryBadge, { category: interest, clickable: true }, interest)) })
|
|
79
|
+
] })
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsxs(Heading, { variant: "h3", className: "sg:mb-6", children: [
|
|
82
|
+
"Posts by ",
|
|
83
|
+
author.name,
|
|
84
|
+
" ",
|
|
85
|
+
/* @__PURE__ */ jsxs(TextSpan, { foreground: "muted-foreground", size: "lg", className: "sg:font-normal", children: [
|
|
86
|
+
"(",
|
|
87
|
+
authorPosts.length,
|
|
88
|
+
")"
|
|
89
|
+
] })
|
|
90
|
+
] }),
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
PostListWithFilters,
|
|
93
|
+
{
|
|
94
|
+
posts: authorPosts,
|
|
95
|
+
hideSearch: true,
|
|
96
|
+
hideAuthorFilter: true,
|
|
97
|
+
filterMode: "drawer"
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
) }) });
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
AuthorPage
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=author-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/pages/author/author-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useMemo } from \"react\";\r\nimport { motion } from \"framer-motion\";\r\nimport {\r\n\tLayout,\r\n\tHeading,\r\n\tText,\r\n\tTextSpan,\r\n\tIcon,\r\n\tBadges,\r\n} from \"../../primitives/index\";\r\nimport {\r\n\tAvatar,\r\n\tAvatarFallback,\r\n\tAvatarImage,\r\n} from \"../../primitives/avatar/avatar\";\r\nimport CategoryBadge from \"../../blocks/badges/category-badge\";\r\nimport { LinkButton } from \"../../primitives/buttons/link-button\";\r\nimport { PostListWithFilters } from \"../../blocks/post-list/post-list-with-filters\";\r\nimport { authors } from \"../../../data/authors\";\r\nimport { posts } from \"../../../data/posts\";\r\n\r\ntype Props = {\r\n\tslug?: string;\r\n};\r\n\r\nexport function AuthorPage({ slug = \"elena-marsh\" }: Props) {\r\n\tconst author = authors.find((a) => a.slug === slug);\r\n\r\n\tconst authorPosts = useMemo(\r\n\t\t() => (author ? posts.filter((p) => p.author === author.name) : []),\r\n\t\t[author],\r\n\t);\r\n\r\n\tif (!author) {\r\n\t\treturn (\r\n\t\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t\t<Layout.Col1 hideDiv className=\"sg:text-center\">\r\n\t\t\t\t\t<Heading variant=\"h2\" className=\"sg:mb-4\">\r\n\t\t\t\t\t\tAuthor not found\r\n\t\t\t\t\t</Heading>\r\n\t\t\t\t\t<LinkButton variant=\"outline\" to=\"/extras/authors\" iconStart=\"ArrowLeft\">\r\n\t\t\t\t\t\tBack to Authors\r\n\t\t\t\t\t</LinkButton>\r\n\t\t\t\t</Layout.Col1>\r\n\t\t\t</Layout>\r\n\t\t);\r\n\t}\r\n\r\n\treturn (\r\n\t\t<Layout type=\"col\" className=\"sg:py-16\">\r\n\t\t\t<Layout.Col1 hideDiv>\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<LinkButton\r\n\t\t\t\t\t\tvariant=\"ghost\"\r\n\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\tto=\"/extras/authors\"\r\n\t\t\t\t\t\ticonStart=\"ArrowLeft\"\r\n\t\t\t\t\t\tclassName=\"sg:mb-6\"\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\tAll Authors\r\n\t\t\t\t\t</LinkButton>\r\n\r\n\t\t\t\t\t<div className=\"sg:flex sg:flex-col sm:sg:flex-row sg:items-start sg:gap-6 sg:mb-12\">\r\n\t\t\t\t\t\t<Avatar className=\"sg:h-24 sg:w-24\">\r\n\t\t\t\t\t\t\t<AvatarImage src={author.avatar} alt={author.name} />\r\n\t\t\t\t\t\t\t<AvatarFallback className=\"sg:text-2xl\">\r\n\t\t\t\t\t\t\t\t{author.name\r\n\t\t\t\t\t\t\t\t\t.split(\" \")\r\n\t\t\t\t\t\t\t\t\t.map((n) => n[0])\r\n\t\t\t\t\t\t\t\t\t.join(\"\")}\r\n\t\t\t\t\t\t\t</AvatarFallback>\r\n\t\t\t\t\t\t</Avatar>\r\n\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t<Heading variant=\"h1\">{author.name}</Heading>\r\n\t\t\t\t\t\t\t<div className=\"sg:flex sg:items-center sg:gap-4 sg:mt-2\">\r\n\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:flex sg:items-center sg:gap-1\">\r\n\t\t\t\t\t\t\t\t\t<Icon icon=\"Briefcase\" className=\"sg:h-3.5 sg:w-3.5\" />\r\n\t\t\t\t\t\t\t\t\t{author.role}\r\n\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:flex sg:items-center sg:gap-1\">\r\n\t\t\t\t\t\t\t\t\t<Icon icon=\"MapPin\" className=\"sg:h-3.5 sg:w-3.5\" />\r\n\t\t\t\t\t\t\t\t\t{author.location}\r\n\t\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t<Text\r\n\t\t\t\t\t\t\t\tforeground=\"muted-foreground\"\r\n\t\t\t\t\t\t\t\tclassName=\"sg:mt-4 sg:leading-relaxed sg:max-w-2xl\"\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t{author.bio}\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t<Badges className=\"sg:mt-4\">\r\n\t\t\t\t\t\t\t\t{author.interests.map((interest) => (\r\n\t\t\t\t\t\t\t\t\t<CategoryBadge key={interest} category={interest} clickable />\r\n\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t</Badges>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<Heading variant=\"h3\" className=\"sg:mb-6\">\r\n\t\t\t\t\t\tPosts by {author.name}{\" \"}\r\n\t\t\t\t\t\t<TextSpan foreground=\"muted-foreground\" size=\"lg\" className=\"sg:font-normal\">\r\n\t\t\t\t\t\t\t({authorPosts.length})\r\n\t\t\t\t\t\t</TextSpan>\r\n\t\t\t\t\t</Heading>\r\n\r\n\t\t\t\t\t<PostListWithFilters\r\n\t\t\t\t\t\tposts={authorPosts}\r\n\t\t\t\t\t\thideSearch\r\n\t\t\t\t\t\thideAuthorFilter\r\n\t\t\t\t\t\tfilterMode=\"drawer\"\r\n\t\t\t\t\t/>\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":"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","names":[]}
|
|
@@ -0,0 +1,25 @@
|
|
|
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 { AuthorCard } from "../../blocks/directory/author-card.js";
|
|
6
|
+
import { authors } from "../../../data/authors.js";
|
|
7
|
+
function AuthorsPage() {
|
|
8
|
+
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(
|
|
9
|
+
motion.div,
|
|
10
|
+
{
|
|
11
|
+
initial: { opacity: 0, y: 20 },
|
|
12
|
+
animate: { opacity: 1, y: 0 },
|
|
13
|
+
transition: { duration: 0.3 },
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h1", className: "sg:mb-2", children: "Authors" }),
|
|
16
|
+
/* @__PURE__ */ jsx(Text, { foreground: "muted-foreground", className: "sg:mb-10", children: "Meet the voices behind the stories." }),
|
|
17
|
+
/* @__PURE__ */ jsx("div", { className: "sg:grid sg:gap-6", children: authors.map((author) => /* @__PURE__ */ jsx(AuthorCard, { author }, author.slug)) })
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
) }) });
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
AuthorsPage
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=authors-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/pages/authors/authors-page.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { motion } from \"framer-motion\";\r\nimport { Layout, Heading, Text } from \"../../primitives/index\";\r\nimport { AuthorCard } from \"../../blocks/directory/author-card\";\r\nimport { authors } from \"../../../data/authors\";\r\n\r\nexport function AuthorsPage() {\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\tAuthors\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\tMeet the voices behind the stories.\r\n\t\t\t\t\t</Text>\r\n\t\t\t\t\t<div className=\"sg:grid sg:gap-6\">\r\n\t\t\t\t\t\t{authors.map((author) => (\r\n\t\t\t\t\t\t\t<AuthorCard key={author.slug} author={author} />\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":";AAWI,SAKC,KALD;AATJ,SAAS,cAAc;AACvB,SAAS,QAAQ,SAAS,YAAY;AACtC,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAEjB,SAAS,cAAc;AAC7B,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,qBAE1C;AAAA,QACA,oBAAC,QAAK,YAAW,oBAAmB,WAAU,YAAW,iDAEzD;AAAA,QACA,oBAAC,SAAI,WAAU,oBACb,kBAAQ,IAAI,CAAC,WACb,oBAAC,cAA6B,UAAb,OAAO,IAAsB,CAC9C,GACF;AAAA;AAAA;AAAA,EACD,GACD,GACD;AAEF;","names":[]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface BlogPostProps {
|
|
4
|
+
slug?: string;
|
|
5
|
+
}
|
|
6
|
+
declare function BlogPost({ slug: propSlug }: BlogPostProps): React.JSX.Element;
|
|
4
7
|
|
|
5
8
|
export { BlogPost };
|