feat: centralize popup texts in new admin tab /admin/popups
- New admin page for shared popup texts (success, waiting list, error, Instagram hint) - Removed popup fields from MC and Open Day admin editors - All SignupModals now read from centralized popups config - Stored as "popups" section in DB with fallback defaults
This commit is contained in:
@@ -11,6 +11,7 @@ import type { SiteContent, MasterClassItem, MasterClassSlot } from "@/types";
|
||||
interface MasterClassesProps {
|
||||
data: SiteContent["masterClasses"];
|
||||
regCounts?: Record<string, number>;
|
||||
popups?: SiteContent["popups"];
|
||||
}
|
||||
|
||||
const MONTHS_RU = [
|
||||
@@ -217,7 +218,7 @@ function MasterClassCard({
|
||||
);
|
||||
}
|
||||
|
||||
export function MasterClasses({ data, regCounts = {} }: MasterClassesProps) {
|
||||
export function MasterClasses({ data, regCounts = {}, popups }: MasterClassesProps) {
|
||||
const [signupTitle, setSignupTitle] = useState<string | null>(null);
|
||||
|
||||
const upcoming = useMemo(() => {
|
||||
@@ -278,8 +279,10 @@ export function MasterClasses({ data, regCounts = {} }: MasterClassesProps) {
|
||||
subtitle={signupTitle ?? ""}
|
||||
endpoint="/api/master-class-register"
|
||||
extraBody={{ masterClassTitle: signupTitle }}
|
||||
successMessage={data.successMessage}
|
||||
waitingMessage={data.waitingListText}
|
||||
successMessage={popups?.successMessage}
|
||||
waitingMessage={popups?.waitingListText}
|
||||
errorMessage={popups?.errorMessage}
|
||||
instagramHint={popups?.instagramHint}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -6,12 +6,14 @@ import { SectionHeading } from "@/components/ui/SectionHeading";
|
||||
import { Reveal } from "@/components/ui/Reveal";
|
||||
import { SignupModal } from "@/components/ui/SignupModal";
|
||||
import type { OpenDayEvent, OpenDayClass } from "@/lib/openDay";
|
||||
import type { SiteContent } from "@/types";
|
||||
|
||||
interface OpenDayProps {
|
||||
data: {
|
||||
event: OpenDayEvent;
|
||||
classes: OpenDayClass[];
|
||||
};
|
||||
popups?: SiteContent["popups"];
|
||||
}
|
||||
|
||||
function formatDateRu(dateStr: string): string {
|
||||
@@ -23,7 +25,7 @@ function formatDateRu(dateStr: string): string {
|
||||
});
|
||||
}
|
||||
|
||||
export function OpenDay({ data }: OpenDayProps) {
|
||||
export function OpenDay({ data, popups }: OpenDayProps) {
|
||||
const { event, classes } = data;
|
||||
const [signup, setSignup] = useState<{ classId: number; label: string } | null>(null);
|
||||
|
||||
@@ -132,8 +134,10 @@ export function OpenDay({ data }: OpenDayProps) {
|
||||
subtitle={signup.label}
|
||||
endpoint="/api/open-day-register"
|
||||
extraBody={{ classId: signup.classId, eventId: event.id }}
|
||||
successMessage={event.successMessage}
|
||||
waitingMessage={event.waitingListText}
|
||||
successMessage={popups?.successMessage}
|
||||
waitingMessage={popups?.waitingListText}
|
||||
errorMessage={popups?.errorMessage}
|
||||
instagramHint={popups?.instagramHint}
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
|
||||
@@ -18,6 +18,10 @@ interface SignupModalProps {
|
||||
successMessage?: string;
|
||||
/** Custom waiting list message */
|
||||
waitingMessage?: string;
|
||||
/** Custom error message */
|
||||
errorMessage?: string;
|
||||
/** Custom Instagram hint text */
|
||||
instagramHint?: string;
|
||||
/** Callback with API response data on success */
|
||||
onSuccess?: (data: Record<string, unknown>) => void;
|
||||
}
|
||||
@@ -31,6 +35,8 @@ export function SignupModal({
|
||||
extraBody,
|
||||
successMessage,
|
||||
waitingMessage,
|
||||
errorMessage,
|
||||
instagramHint,
|
||||
onSuccess,
|
||||
}: SignupModalProps) {
|
||||
const [name, setName] = useState("");
|
||||
@@ -167,7 +173,7 @@ export function SignupModal({
|
||||
className="mt-3 inline-flex items-center gap-1.5 text-sm text-pink-400 hover:text-pink-300"
|
||||
>
|
||||
<Instagram size={14} />
|
||||
По вопросам пишите в Instagram
|
||||
{instagramHint || "По вопросам пишите в Instagram"}
|
||||
</a>
|
||||
</>
|
||||
) : (
|
||||
@@ -190,7 +196,7 @@ export function SignupModal({
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white">Что-то пошло не так</h3>
|
||||
<p className="mt-2 text-sm text-neutral-400">
|
||||
Не удалось отправить заявку. Свяжитесь с нами через Instagram — мы запишем вас!
|
||||
{errorMessage || "Не удалось отправить заявку. Свяжитесь с нами через Instagram — мы запишем вас!"}
|
||||
</p>
|
||||
<button
|
||||
onClick={openInstagramDM}
|
||||
|
||||
Reference in New Issue
Block a user