From 34fe0f16907bd03360d4938212cee4a113e9f30e Mon Sep 17 00:00:00 2001 From: Babayaga Date: Fri, 6 Feb 2026 12:31:07 +0100 Subject: [PATCH] db | cache | kats:) | gallery | widgets --- packages/ui/src/App.tsx | 2 + packages/ui/src/components/GalleryLarge.tsx | 10 +- packages/ui/src/components/ListLayout.tsx | 7 +- packages/ui/src/components/PageActions.tsx | 32 +- packages/ui/src/components/PageCard.tsx | 68 ++-- packages/ui/src/components/PhotoCard.tsx | 26 +- packages/ui/src/components/PhotoGrid.tsx | 247 ++++++++++----- packages/ui/src/components/TopNavigation.tsx | 9 +- .../ui/src/components/admin/AdminSidebar.tsx | 6 +- .../ui/src/components/admin/BansManager.tsx | 291 ++++++++++++++++++ .../components/admin/ViolationsMonitor.tsx | 200 ++++++++++++ .../ui/src/components/feed/MobileFeed.tsx | 7 +- .../ui/src/components/hmi/LayoutContainer.tsx | 4 +- .../playground/PlaygroundHeader.tsx | 169 +++++++++- .../ui/src/components/types/RJSFTemplates.tsx | 16 +- .../ui/src/components/types/TypeBuilder.tsx | 25 +- .../ui/src/components/types/TypeRenderer.tsx | 129 +++++--- .../src/components/types/TypesPlayground.tsx | 25 +- .../components/widgets/CategoryManager.tsx | 75 +++-- .../src/components/widgets/GalleryWidget.tsx | 229 ++++++++++++++ .../src/components/widgets/PageCardWidget.tsx | 246 +++++++++++++++ .../components/widgets/PagePickerDialog.tsx | 11 +- .../components/widgets/PhotoCardWidget.tsx | 27 +- .../components/widgets/PhotoGridWidget.tsx | 38 +-- .../widgets/WidgetPropertiesForm.tsx | 2 +- .../widgets/WidgetSettingsManager.tsx | 6 - packages/ui/src/hooks/useAuth.tsx | 2 - packages/ui/src/hooks/useFeedData.ts | 14 +- packages/ui/src/hooks/useLayouts.ts | 126 ++++++++ packages/ui/src/hooks/usePlaygroundLogic.tsx | 138 ++++++++- .../ui/src/integrations/supabase/types.ts | 54 +++- packages/ui/src/lib/db.ts | 165 +++++++++- packages/ui/src/lib/mediaRegistry.ts | 78 ++++- packages/ui/src/lib/registerWidgets.ts | 211 ++++++++----- packages/ui/src/pages/AdminPage.tsx | 64 +++- packages/ui/src/pages/Index.tsx | 77 +++-- packages/ui/src/pages/PlaygroundCanvas.tsx | 6 + packages/ui/src/pages/Post.tsx | 39 ++- packages/ui/src/pages/Post/adapters.ts | 175 +++++++++++ .../pages/Post/renderers/CompactRenderer.tsx | 57 ++-- .../renderers/components/CompactFilmStrip.tsx | 31 +- .../components/CompactMediaViewer.tsx | 32 +- .../components/CompactPostHeader.tsx | 29 +- .../Post/renderers/components/Gallery.tsx | 157 ++++++++++ packages/ui/src/pages/Post/types.ts | 39 ++- packages/ui/src/pages/Post/usePostActions.ts | 20 ++ packages/ui/src/pages/UserPage.tsx | 1 + packages/ui/src/pages/UserProfile.tsx | 50 +-- packages/ui/src/types.ts | 129 +++++++- 49 files changed, 3019 insertions(+), 582 deletions(-) create mode 100644 packages/ui/src/components/admin/BansManager.tsx create mode 100644 packages/ui/src/components/admin/ViolationsMonitor.tsx create mode 100644 packages/ui/src/components/widgets/GalleryWidget.tsx create mode 100644 packages/ui/src/components/widgets/PageCardWidget.tsx create mode 100644 packages/ui/src/hooks/useLayouts.ts create mode 100644 packages/ui/src/pages/Post/adapters.ts create mode 100644 packages/ui/src/pages/Post/renderers/components/Gallery.tsx diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index 3a90aba4..9bba293c 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -82,6 +82,7 @@ const AppWrapper = () => { } /> } /> } /> + } /> } /> } /> } /> @@ -114,6 +115,7 @@ const AppWrapper = () => { } /> } /> } /> + } /> } /> } /> } /> diff --git a/packages/ui/src/components/GalleryLarge.tsx b/packages/ui/src/components/GalleryLarge.tsx index 8c147596..ef8fd2bf 100644 --- a/packages/ui/src/components/GalleryLarge.tsx +++ b/packages/ui/src/components/GalleryLarge.tsx @@ -1,16 +1,13 @@ -import { MediaGrid, PhotoGrid } from "./PhotoGrid"; import MediaCard from "./MediaCard"; import React, { useEffect, useState, useRef } from "react"; import { useAuth } from "@/hooks/useAuth"; import { useNavigate } from "react-router-dom"; -import { useProfiles } from "@/contexts/ProfilesContext"; import { usePostNavigation } from "@/hooks/usePostNavigation"; import { useOrganization } from "@/contexts/OrganizationContext"; import { useFeedData } from "@/hooks/useFeedData"; import { normalizeMediaType, isVideoType } from "@/lib/mediaRegistry"; -import { UserProfile } from '../pages/Post/types'; import * as db from '../pages/Post/db'; -import type { MediaItem, MediaType } from "@/types"; +import type { MediaItem } from "@/types"; import { supabase } from "@/integrations/supabase/client"; // Duplicate types for now or we could reuse specific generic props @@ -24,6 +21,7 @@ interface GalleryLargeProps { navigationSource?: 'home' | 'collection' | 'tag' | 'user'; navigationSourceId?: string; sortBy?: FeedSortOption; + categorySlugs?: string[]; } const GalleryLarge = ({ @@ -31,7 +29,8 @@ const GalleryLarge = ({ customLoading, navigationSource = 'home', navigationSourceId, - sortBy = 'latest' + sortBy = 'latest', + categorySlugs }: GalleryLargeProps) => { const { user } = useAuth(); const navigate = useNavigate(); @@ -48,6 +47,7 @@ const GalleryLarge = ({ isOrgContext, orgSlug, sortBy, + categorySlugs, // Disable hook if we have custom pictures enabled: !customPictures }); diff --git a/packages/ui/src/components/ListLayout.tsx b/packages/ui/src/components/ListLayout.tsx index 9561ed66..6ce9369b 100644 --- a/packages/ui/src/components/ListLayout.tsx +++ b/packages/ui/src/components/ListLayout.tsx @@ -17,6 +17,7 @@ interface ListLayoutProps { navigationSource?: 'home' | 'collection' | 'tag' | 'user'; navigationSourceId?: string; isOwner?: boolean; // Not strictly used for rendering list but good for consistency + categorySlugs?: string[]; } const ListItem = ({ item, isSelected, onClick }: { item: any, isSelected: boolean, onClick: () => void }) => { @@ -95,7 +96,8 @@ const ListItem = ({ item, isSelected, onClick }: { item: any, isSelected: boolea export const ListLayout = ({ sortBy = 'latest', navigationSource = 'home', - navigationSourceId + navigationSourceId, + categorySlugs }: ListLayoutProps) => { const navigate = useNavigate(); const isMobile = useIsMobile(); @@ -114,7 +116,8 @@ export const ListLayout = ({ sourceId: navigationSourceId, isOrgContext, orgSlug, - sortBy + sortBy, + categorySlugs }); // console.log('posts', feedPosts); diff --git a/packages/ui/src/components/PageActions.tsx b/packages/ui/src/components/PageActions.tsx index db30d8c2..6cee4793 100644 --- a/packages/ui/src/components/PageActions.tsx +++ b/packages/ui/src/components/PageActions.tsx @@ -36,6 +36,7 @@ interface PageActionsProps { onToggleEditMode?: () => void; onPageUpdate: (updatedPage: Page) => void; onDelete?: () => void; + onMetaUpdated?: () => void; className?: string; showLabels?: boolean; } @@ -47,6 +48,7 @@ export const PageActions = ({ onToggleEditMode, onPageUpdate, onDelete, + onMetaUpdated, className, showLabels = true }: PageActionsProps) => { @@ -109,18 +111,24 @@ export const PageActions = ({ } }; - const handleMetaUpdate = (newMeta: any) => { - // PageActions locally updates the page object. - // Ideally we should reload the page via UserPage but this gives instant feedback. + const handleMetaUpdate = async (newMeta: any) => { + // Update local state immediately for responsive UI onPageUpdate({ ...page, meta: newMeta }); - // NOTE: If meta update persists to DB elsewhere (CategoryManager), it should probably handle invalidation too. - // But if CategoryManager is purely local until save, then we do nothing. - // Looking at CategoryManager usage, it likely saves. - // We might want to pass invalidatePageCache to it or call it here if we know it saved. - // Use timeout to debounce invalidation? For now assume CategoryManager handles its own saving/invalidation or we rely on page refresh. - // Actually, CategoryManager props has "onPageMetaUpdate", which updates local state. - // If CategoryManager saves to DB, it should invalidate. - // Let's stick to the handlers we control here. + + // Persist to database + try { + const { updatePageMeta } = await import('@/lib/db'); + await updatePageMeta(page.id, newMeta); + invalidatePageCache(); + + // Trigger parent refresh to get updated category_paths + if (onMetaUpdated) { + onMetaUpdated(); + } + } catch (error) { + console.error('Failed to update page meta:', error); + toast.error(translate('Failed to update categories')); + } }; const handleToggleVisibility = async (e?: React.MouseEvent) => { @@ -516,6 +524,8 @@ draft: ${!page.visible} currentPageId={page.id} currentPageMeta={page.meta} onPageMetaUpdate={handleMetaUpdate} + filterByType="pages" + defaultMetaType="pages" /> {/* Legacy/Standard Parent Picker - Keeping relevant as "Page Hierarchy" vs "Category Taxonomy" */} diff --git a/packages/ui/src/components/PageCard.tsx b/packages/ui/src/components/PageCard.tsx index 86318900..88c093bf 100644 --- a/packages/ui/src/components/PageCard.tsx +++ b/packages/ui/src/components/PageCard.tsx @@ -11,6 +11,8 @@ interface PageCardProps extends Omit { variant?: 'grid' | 'feed'; responsive?: any; showContent?: boolean; + showHeader?: boolean; + overlayMode?: 'hover' | 'always'; authorAvatarUrl?: string | null; created_at?: string; apiUrl?: string; @@ -35,6 +37,8 @@ const PageCard: React.FC = ({ variant = 'grid', responsive, showContent = true, + showHeader = true, + overlayMode = 'hover', apiUrl, versionCount }) => { @@ -69,16 +73,18 @@ const PageCard: React.FC = ({ className="group relative overflow-hidden bg-card transition-all duration-300 cursor-pointer w-full border rounded-lg mb-4" onClick={handleCardClick} > -
- -
+ {showHeader && ( +
+ +
+ )}
{isPlaying && isExternalVideo ? ( @@ -126,28 +132,30 @@ const PageCard: React.FC = ({ )}
-
-
-

{title}

-
- - {description && ( -
- + {showContent && ( +
+
+

{title}

- )} -
- - + {description && ( +
+ +
+ )} + +
+ + +
-
+ )}
); } @@ -208,7 +216,7 @@ const PageCard: React.FC = ({ )} {showContent && ( -
+