From 4adbe9f2b7d2f1509be96ebcb4eb5010742dd9e2 Mon Sep 17 00:00:00 2001 From: Nathan Vasse Date: Tue, 12 May 2026 14:51:06 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20wire=20CTAs=20into=20head?= =?UTF-8?q?er=20and=20standalone=20file=20preview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UserProfile now renders AnonymousCTA along with a dropdown menu (copy link, language picker) when no user is authenticated, so visitors on a public page can still act on it without the user menu. CustomFilesPreview gains a CONTEXTUAL mode that swaps in the right CTA based on auth state, used by the standalone file preview page which is now wrapped in GlobalLayout to expose the auth context. --- CHANGELOG.md | 4 ++ .../ui/components/user/UserProfile.tsx | 62 +++++++++++++++++-- .../ui/preview/CustomFilesPreview.tsx | 54 ++++++++++++---- .../src/pages/explorer/items/files/[id].tsx | 16 ++++- 4 files changed, 118 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6220a44..2e355e59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ and this project adheres to - 🔥(backend) drop deprecated numchild columns from item +### Added + +- ✨(frontend) add CTA on public link for anonymous and authenticated users + ## [v0.18.0] - 2026-05-04 ### Added diff --git a/src/frontend/apps/drive/src/features/ui/components/user/UserProfile.tsx b/src/frontend/apps/drive/src/features/ui/components/user/UserProfile.tsx index c7af44fd..bb2361f2 100644 --- a/src/frontend/apps/drive/src/features/ui/components/user/UserProfile.tsx +++ b/src/frontend/apps/drive/src/features/ui/components/user/UserProfile.tsx @@ -1,8 +1,20 @@ -import { UserMenu } from "@gouvfr-lasuite/ui-kit"; +import { + DropdownMenu, + Icon, + IconSize, + useDropdownMenu, + UserMenu, +} from "@gouvfr-lasuite/ui-kit"; import { useAuth } from "@/features/auth/Auth"; import { logout } from "@/features/auth/Auth"; -import { LanguagePickerUserMenu } from "@/features/layouts/components/header/Header"; -import { LoginButton } from "@/features/auth/components/LoginButton"; +import { + LanguagePickerUserMenu, + LANGUAGES, +} from "@/features/layouts/components/header/Header"; +import { AnonymousCTA } from "../anonymous-cta/AnonymousCTA"; +import { Button } from "@gouvfr-lasuite/cunningham-react"; +import { useTranslation } from "react-i18next"; +import { useClipboard } from "@/hooks/useCopyToClipboard"; export const UserProfile = () => { const { user } = useAuth(); @@ -16,8 +28,50 @@ export const UserProfile = () => { actions={} /> ) : ( - + <> + + + )} ); }; + +const AnonymousDropdownMenu = () => { + const { isOpen, setIsOpen } = useDropdownMenu(); + const { t, i18n } = useTranslation(); + const copyToClipboard = useClipboard(); + + return ( + , + label: t("anonymous_dropdown_menu.copy_link"), + callback: () => { + copyToClipboard(window.location.href); + }, + }, + { + icon: , + label: t("anonymous_dropdown_menu.languages"), + children: LANGUAGES.map((language) => ({ + label: language.label, + callback: () => { + i18n.changeLanguage(language.value); + }, + })), + }, + ]} + > + - + {mode === CustomFilesPreviewMode.DEFAULT && ( + <> +
+ +
- {shareModal.isOpen && ( - + {shareModal.isOpen && ( + + )} + + )} + + {children} + + {mode === CustomFilesPreviewMode.CONTEXTUAL && ( +
+ {user ? : } +
)} ); diff --git a/src/frontend/apps/drive/src/pages/explorer/items/files/[id].tsx b/src/frontend/apps/drive/src/pages/explorer/items/files/[id].tsx index 1f46c65a..3b7cab05 100644 --- a/src/frontend/apps/drive/src/pages/explorer/items/files/[id].tsx +++ b/src/frontend/apps/drive/src/pages/explorer/items/files/[id].tsx @@ -1,11 +1,15 @@ import { GenericDisclaimer } from "@/features/ui/components/generic-disclaimer/GenericDisclaimer"; import { SpinnerPage } from "@/features/ui/components/spinner/SpinnerPage"; -import { CustomFilesPreview } from "@/features/ui/preview/CustomFilesPreview"; +import { + CustomFilesPreview, + CustomFilesPreviewMode, +} from "@/features/ui/preview/CustomFilesPreview"; import { Icon } from "@gouvfr-lasuite/ui-kit"; import { Button } from "@gouvfr-lasuite/cunningham-react"; import { useRouter } from "next/router"; import { useTranslation } from "react-i18next"; import { useItem } from "@/features/explorer/hooks/useQueries"; +import { GlobalLayout } from "@/features/layouts/components/global/GlobalLayout"; export default function FilePage() { const { t } = useTranslation(); @@ -37,7 +41,15 @@ export default function FilePage() { return (
- +
); } + +FilePage.getLayout = function getLayout(page: React.ReactElement) { + return {page}; +};