Email: Review-Link auf /review/:token umgestellt; Token-Erzeugung konsolidiert. Reviews: Client-Validation hinzugefügt. Verfügbarkeiten: Auto-Update nach Regelanlage. Galerie: Cover-Foto-Flag + Setzen im Admin, sofortige Aktualisierung nach Upload/Löschen/Reihenfolge-Änderung. Startseite: Featured-Foto = Reihenfolge 0, Seitenverhältnis beibehalten, Texte aktualisiert.
This commit is contained in:
@@ -8,12 +8,16 @@ import { AdminBookings } from "@/client/components/admin-bookings";
|
||||
import { AdminCalendar } from "@/client/components/admin-calendar";
|
||||
import { InitialDataLoader } from "@/client/components/initial-data-loader";
|
||||
import { AdminAvailability } from "@/client/components/admin-availability";
|
||||
import { AdminGallery } from "@/client/components/admin-gallery";
|
||||
import { AdminReviews } from "@/client/components/admin-reviews";
|
||||
import BookingStatusPage from "@/client/components/booking-status-page";
|
||||
import ReviewSubmissionPage from "@/client/components/review-submission-page";
|
||||
import LegalPage from "@/client/components/legal-page";
|
||||
import { ProfileLanding } from "@/client/components/profile-landing";
|
||||
|
||||
function App() {
|
||||
const { user, isLoading, isOwner } = useAuth();
|
||||
const [activeTab, setActiveTab] = useState<"booking" | "admin-treatments" | "admin-bookings" | "admin-calendar" | "admin-availability" | "profile" | "legal">("booking");
|
||||
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);
|
||||
|
||||
// Prevent background scroll when menu is open
|
||||
@@ -31,6 +35,14 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle review submission page
|
||||
if (path.startsWith('/review/')) {
|
||||
const token = path.split('/review/')[1];
|
||||
if (token) {
|
||||
return <ReviewSubmissionPage token={token} />;
|
||||
}
|
||||
}
|
||||
|
||||
// Show loading spinner while checking authentication
|
||||
if (isLoading) {
|
||||
return (
|
||||
@@ -48,7 +60,7 @@ function App() {
|
||||
}
|
||||
|
||||
// Show login form if user is not authenticated and trying to access admin features
|
||||
const needsAuth = !user && (activeTab === "admin-treatments" || activeTab === "admin-bookings" || activeTab === "admin-calendar" || activeTab === "admin-availability" || activeTab === "profile");
|
||||
const needsAuth = !user && (activeTab === "admin-treatments" || activeTab === "admin-bookings" || activeTab === "admin-calendar" || activeTab === "admin-availability" || activeTab === "admin-gallery" || activeTab === "admin-reviews" || activeTab === "profile");
|
||||
if (needsAuth) {
|
||||
return <LoginForm />;
|
||||
}
|
||||
@@ -59,12 +71,15 @@ function App() {
|
||||
}
|
||||
|
||||
const tabs = [
|
||||
{ id: "profile-landing", label: "Startseite", icon: "🏠", requiresAuth: false },
|
||||
{ id: "booking", label: "Termin buchen", icon: "📅", requiresAuth: false },
|
||||
{ id: "legal", label: "Impressum/Datenschutz", icon: "📋", requiresAuth: false },
|
||||
{ id: "admin-treatments", label: "Behandlungen verwalten", icon: "💅", requiresAuth: true },
|
||||
{ id: "admin-bookings", label: "Buchungen verwalten", icon: "📋", requiresAuth: true },
|
||||
{ id: "admin-calendar", label: "Kalender", icon: "📆", requiresAuth: true },
|
||||
{ id: "admin-availability", label: "Verfügbarkeiten", icon: "⏰", requiresAuth: true },
|
||||
{ id: "admin-gallery", label: "Photo-Wall", icon: "📸", requiresAuth: true },
|
||||
{ id: "admin-reviews", label: "Bewertungen", icon: "⭐", requiresAuth: true },
|
||||
...(user ? [{ id: "profile", label: "Profil", icon: "👤", requiresAuth: true }] : []),
|
||||
] as const;
|
||||
|
||||
@@ -78,7 +93,7 @@ function App() {
|
||||
<div className="flex justify-between items-center py-6">
|
||||
<div
|
||||
className="flex items-center space-x-3 cursor-pointer hover:opacity-80 transition-opacity"
|
||||
onClick={() => setActiveTab("booking")}
|
||||
onClick={() => setActiveTab("profile-landing")}
|
||||
>
|
||||
<img
|
||||
src="/assets/stargilnails_logo_transparent_112.png"
|
||||
@@ -240,6 +255,10 @@ function App() {
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
{activeTab === "profile-landing" && (
|
||||
<ProfileLanding onNavigateToBooking={() => setActiveTab("booking")} />
|
||||
)}
|
||||
|
||||
{activeTab === "booking" && (
|
||||
<div>
|
||||
<div className="text-center mb-8">
|
||||
@@ -311,6 +330,34 @@ function App() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "admin-gallery" && isOwner && (
|
||||
<div>
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
Photo-Wall verwalten
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600">
|
||||
Lade Fotos hoch und verwalte deine Galerie.
|
||||
</p>
|
||||
</div>
|
||||
<AdminGallery />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "admin-reviews" && isOwner && (
|
||||
<div>
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
||||
Bewertungen verwalten
|
||||
</h2>
|
||||
<p className="text-lg text-gray-600">
|
||||
Prüfe und verwalte Kundenbewertungen.
|
||||
</p>
|
||||
</div>
|
||||
<AdminReviews />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "profile" && user && (
|
||||
<div>
|
||||
<div className="text-center mb-8">
|
||||
|
Reference in New Issue
Block a user