From f4593cd70611a5946306f7942a9e1201ce5a430d Mon Sep 17 00:00:00 2001 From: elpatron Date: Tue, 7 Oct 2025 09:32:06 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Social-Media-Badges=20f=C3=BCr=20TikTok?= =?UTF-8?q?=20und=20Instagram=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Neue RPC-Route fΓΌr Social-Media-URLs aus .env (social.ts) - Social-Media-Badges auf der Startseite mit attraktiven Buttons - Social-Media-Icons im Footer aller Seiten - Social-Media-Links in allen E-Mail-Templates - URLs aus .env: TIKTOK_PROFILE und INSTAGRAM_PROFILE --- .env.example | 4 ++- src/client/app.tsx | 40 ++++++++++++++++++++++- src/client/components/profile-landing.tsx | 36 ++++++++++++++++++++ src/server/lib/email-templates.ts | 20 ++++++++++++ src/server/rpc/index.ts | 2 ++ src/server/rpc/social.ts | 13 ++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/server/rpc/social.ts diff --git a/.env.example b/.env.example index 27913bd..8b17c4c 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,9 @@ RESEND_API_KEY=your_resend_api_key_here EMAIL_FROM=noreply@yourdomain.com ADMIN_EMAIL=admin@yourdomain.com -# Frontend URL (for E-Mail Links) +# Social media profiles +TIKTOK_PROFILE=https://www.tiktok.com/@ +INSTAGRAM_PROFILE=https://www.instagram.com/ # Cancellation Policy (in hours) MIN_STORNO_TIMESPAN=24 diff --git a/src/client/app.tsx b/src/client/app.tsx index fc28bd5..f7bf3b2 100644 --- a/src/client/app.tsx +++ b/src/client/app.tsx @@ -1,4 +1,6 @@ import { useState, useEffect } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { queryClient } from "@/client/rpc-client"; import { useAuth } from "@/client/components/auth-provider"; import { LoginForm } from "@/client/components/login-form"; import { UserProfile } from "@/client/components/user-profile"; @@ -19,6 +21,12 @@ function App() { const { user, isLoading, isOwner } = useAuth(); const [activeTab, setActiveTab] = useState<"profile-landing" | "booking" | "admin-treatments" | "admin-bookings" | "admin-calendar" | "admin-availability" | "admin-gallery" | "admin-reviews" | "profile" | "legal">("profile-landing"); const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); + + const { data: socialMedia } = useQuery( + queryClient.social.getSocialMedia.queryOptions() + ); + + const hasSocialMedia = (socialMedia as any)?.tiktokProfile || (socialMedia as any)?.instagramProfile; // Prevent background scroll when menu is open useEffect(() => { @@ -377,7 +385,37 @@ function App() {
-

© 2025 Stargirlnails Kiel. Professional nail design & care with 🩷 and passion in Kiel πŸŒ‡.

+

© 2025 Stargirlnails Kiel. Professional nail design & care with 🩷 and passion in Kiel πŸŒ‡.

+ {hasSocialMedia && ( +
+ {(socialMedia as any)?.instagramProfile && ( + + + + + + )} + {(socialMedia as any)?.tiktokProfile && ( + + + + + + )} +
+ )}
diff --git a/src/client/components/profile-landing.tsx b/src/client/components/profile-landing.tsx index c64974d..1430fec 100644 --- a/src/client/components/profile-landing.tsx +++ b/src/client/components/profile-landing.tsx @@ -57,6 +57,10 @@ export function ProfileLanding({ onNavigateToBooking }: ProfileLandingProps) { queryClient.recurringAvailability.live.listRules.experimental_liveOptions() ); + const { data: socialMedia } = useQuery( + queryClient.social.getSocialMedia.queryOptions() + ); + // Calculate next 7 days for opening hours const getNext7Days = () => { const days: Date[] = []; @@ -90,6 +94,38 @@ export function ProfileLanding({ onNavigateToBooking }: ProfileLandingProps) { + {/* Social Media Badges */} + {((socialMedia as any)?.tiktokProfile || (socialMedia as any)?.instagramProfile) && ( +
+ {(socialMedia as any)?.instagramProfile && ( + + + + + Instagram + + )} + {(socialMedia as any)?.tiktokProfile && ( + + + + + TikTok + + )} +
+ )} + {/* Featured Section: Erstes Foto (Reihenfolge 0) */} {featuredPhoto && (
diff --git a/src/server/lib/email-templates.ts b/src/server/lib/email-templates.ts index 8b214f9..2fa3d64 100644 --- a/src/server/lib/email-templates.ts +++ b/src/server/lib/email-templates.ts @@ -31,6 +31,9 @@ async function renderBrandedEmail(title: string, bodyHtml: string): Promise @@ -49,6 +52,23 @@ async function renderBrandedEmail(title: string, bodyHtml: string): Promise Zur Website + ${(instagramProfile || tiktokProfile) ? ` +
+

Folge uns auf Social Media:

+
+ ${instagramProfile ? ` + + πŸ“· Instagram + + ` : ''} + ${tiktokProfile ? ` + + 🎡 TikTok + + ` : ''} +
+
+ ` : ''}
© ${new Date().getFullYear()} Stargirlnails Kiel β€’ Professional Nail Care
diff --git a/src/server/rpc/index.ts b/src/server/rpc/index.ts index 1f9b9da..6bb889f 100644 --- a/src/server/rpc/index.ts +++ b/src/server/rpc/index.ts @@ -7,6 +7,7 @@ import { router as cancellation } from "./cancellation.js"; import { router as legal } from "./legal.js"; import { router as gallery } from "./gallery.js"; import { router as reviews } from "./reviews.js"; +import { router as social } from "./social.js"; export const router = { demo, @@ -18,4 +19,5 @@ export const router = { legal, gallery, reviews, + social, }; diff --git a/src/server/rpc/social.ts b/src/server/rpc/social.ts new file mode 100644 index 0000000..b56cd9c --- /dev/null +++ b/src/server/rpc/social.ts @@ -0,0 +1,13 @@ +import { os } from "@orpc/server"; + +const getSocialMedia = os.handler(async () => { + return { + tiktokProfile: process.env.TIKTOK_PROFILE, + instagramProfile: process.env.INSTAGRAM_PROFILE, + }; +}); + +export const router = os.router({ + getSocialMedia, +}); +