demo bug fixes
This commit is contained in:
@@ -112,8 +112,7 @@ const Layout = () => {
|
||||
}, []);
|
||||
|
||||
// Determine standard layout vs full screen for Public pages
|
||||
const isPublic = ['/', '/login', '/estimate'].includes(location.pathname)
|
||||
|| location.pathname.startsWith('/ads/');
|
||||
const isPublic = ['/', '/login'].includes(location.pathname);
|
||||
|
||||
if (isPublic) {
|
||||
return (
|
||||
@@ -155,12 +154,12 @@ const Layout = () => {
|
||||
{ to: "/admin/schedule", icon: Calendar, label: "Team Schedule" },
|
||||
{ to: "/admin/leaderboard", icon: Trophy, label: "Leaderboard" },
|
||||
{ to: "/owner/subcontractor-tasks", icon: HardHat, label: "Subcontractor Tasks" },
|
||||
{ to: "/owner/payments", icon: CreditCard, label: "Payment Management" },
|
||||
{ to: "/owner/people", icon: Users, label: "People" },
|
||||
{ to: "/owner/settings", icon: Settings, label: "Org Settings" },
|
||||
...commonItems,
|
||||
{ to: "/estimate-wizard/admin", icon: Settings, label: "Wizard Admin" },
|
||||
{ to: "/marketing", icon: Megaphone, label: "Ad Engine" },
|
||||
{ to: "/owner/payments", icon: CreditCard, label: "Manage Payments" },
|
||||
{ type: "section", label: "Upcoming Features" },
|
||||
{ to: "/campaignx", icon: Rocket, label: <span>Campaign<span className="text-amber-500">X</span></span> },
|
||||
];
|
||||
@@ -182,11 +181,11 @@ const Layout = () => {
|
||||
},
|
||||
{ to: "/admin/estimates", icon: Calculator, label: "Estimates" },
|
||||
{ to: "/admin/subcontractor-tasks", icon: HardHat, label: "Subcontractor Tasks" },
|
||||
{ to: "/owner/payments", icon: CreditCard, label: "Payment Management" },
|
||||
{ to: "/admin/settings", icon: Settings, label: "Org Settings" },
|
||||
...commonItems,
|
||||
{ to: "/estimate-wizard/admin", icon: Settings, label: "Wizard Admin" },
|
||||
{ to: "/marketing", icon: Megaphone, label: "Ad Engine" },
|
||||
{ to: "/owner/payments", icon: CreditCard, label: "Manage Payments" },
|
||||
{ type: "section", label: "Upcoming Features" },
|
||||
{ to: "/campaignx", icon: Rocket, label: <span>Campaign<span className="text-amber-500">X</span></span> },
|
||||
];
|
||||
|
||||
@@ -9,12 +9,8 @@ export const ThemeProvider = ({ children }) => {
|
||||
if (savedTheme) {
|
||||
return savedTheme;
|
||||
}
|
||||
// Check system preference
|
||||
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
return 'dark';
|
||||
}
|
||||
}
|
||||
return 'light'; // Default to light if no preference
|
||||
return 'dark'; // Default to dark for first-time visitors
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
+21
-5
@@ -3613,9 +3613,9 @@ const MOCK_PROJECTS = [
|
||||
budget: 19600,
|
||||
approvedBudget: 19600,
|
||||
committedCost: 18100,
|
||||
actualCost: 0,
|
||||
spent: 0,
|
||||
variancePercent: -100.0,
|
||||
actualCost: 18100,
|
||||
spent: 18100,
|
||||
variancePercent: -7.7,
|
||||
margin: 0.08,
|
||||
commissionType: 'percent_gross',
|
||||
commissionRate: 10,
|
||||
@@ -3632,6 +3632,22 @@ const MOCK_PROJECTS = [
|
||||
{ name: 'City of Plano', category: 'Permits', allocated: 600, committed: 600, actual: 0 },
|
||||
{ name: 'Reserve Fund', category: 'Contingency', allocated: 1500, committed: 0, actual: 0 },
|
||||
],
|
||||
expenses: [
|
||||
{ id: 'exp_017_1', type: 'material', name: 'Owens Corning', category: 'Materials', allocated: 10500, actual: 10500, paid: true, paymentRequests: [
|
||||
{ id: 'req_017_1_1', requestDate: '2026-04-02', requestedAmount: 10500, amountPaid: 10500, paymentDate: '2026-04-04' }
|
||||
] },
|
||||
{ id: 'exp_017_2', type: 'labor', name: 'Plano Roofing Crew C', category: 'Labor', allocated: 7000, actual: 7000, paid: true, paymentRequests: [
|
||||
{ id: 'req_017_2_1', requestDate: '2026-04-22', requestedAmount: 7000, amountPaid: 7000, paymentDate: '2026-04-24' }
|
||||
] },
|
||||
{ id: 'exp_017_3', type: 'other', name: 'City of Plano', category: 'Permits', allocated: 600, actual: 600, paid: true, paymentRequests: [
|
||||
{ id: 'req_017_3_1', requestDate: '2026-04-10', requestedAmount: 600, amountPaid: 600, paymentDate: '2026-04-10' }
|
||||
] }
|
||||
],
|
||||
paymentsReceived: [
|
||||
{ id: 'rcv_017_1', from: 'Adriana Voss', method: 'Check', amount: 5880, date: '2026-03-28', refNumber: 'CHK-2017-01', memo: 'Deposit — 30%' },
|
||||
{ id: 'rcv_017_2', from: 'Farmers Insurance', method: 'ACH', amount: 7840, date: '2026-04-25', refNumber: 'ACH-2017-02', memo: 'Progress payment — 40%' },
|
||||
{ id: 'rcv_017_3', from: 'Farmers Insurance', method: 'ACH', amount: 5880, date: '2026-04-28', refNumber: 'ACH-2017-03', memo: 'Final payment — 30%' },
|
||||
],
|
||||
changeOrders: [
|
||||
{ id: 'CO-017-01', title: 'Supplemental — Ice & Water Barrier', amount: 1800, status: 'approved', description: 'Insurance adjuster agreed to add ice/water shield on all valleys and eaves.' },
|
||||
],
|
||||
@@ -3640,8 +3656,8 @@ const MOCK_PROJECTS = [
|
||||
issueLog: [],
|
||||
paymentSchedule: [
|
||||
{ id: 'ps_017_1', milestone: 'Deposit — 30%', amount: 5880, dueDate: '2026-03-28', status: 'paid', paidDate: '2026-03-28' },
|
||||
{ id: 'ps_017_2', milestone: 'Progress — 40%', amount: 7840, dueDate: '2026-04-25', status: 'pending' },
|
||||
{ id: 'ps_017_3', milestone: 'Final — 30%', amount: 5880, dueDate: '2026-04-28', status: 'pending' },
|
||||
{ id: 'ps_017_2', milestone: 'Progress — 40%', amount: 7840, dueDate: '2026-04-25', status: 'paid', paidDate: '2026-04-25' },
|
||||
{ id: 'ps_017_3', milestone: 'Final — 30%', amount: 5880, dueDate: '2026-04-28', status: 'paid', paidDate: '2026-04-28' },
|
||||
],
|
||||
invoices: [],
|
||||
milestones: [
|
||||
|
||||
@@ -79,9 +79,6 @@ const DemoCheckout = () => {
|
||||
<Row label="CVC" value="123" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="flex items-center gap-1.5 text-[11px] text-emerald-600 dark:text-emerald-400 mt-2">
|
||||
<CheckCircle2 size={12} /> Test card pre-filled for the demo — just press Pay.
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={handlePay}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
* closing the spec's loop (§5). Front-end demo only — no real platform or backend.
|
||||
*/
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useSearchParams, useNavigate, useLocation } from 'react-router-dom';
|
||||
import {
|
||||
ShieldCheck, CheckCircle2, ArrowRight, Loader2, Megaphone, Lock, Phone,
|
||||
ShieldCheck, CheckCircle2, ArrowRight, ArrowLeft, Loader2, Megaphone, Lock, Phone,
|
||||
} from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import { BLUEPRINT_BY_ID, BLUEPRINTS } from './data/blueprints.js';
|
||||
@@ -54,6 +54,11 @@ const inputCls =
|
||||
|
||||
export default function PublicAdLanding() {
|
||||
const [params] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
// Only show the "Back" control when this page was reached via in-app navigation
|
||||
// (i.e. a preview opened from the Ad Engine) — a real ad click lands with no app history.
|
||||
const cameFromApp = location.key !== 'default';
|
||||
|
||||
const blueprint = BLUEPRINT_BY_ID[params.get('c')] || BLUEPRINTS[0];
|
||||
const platformId = getPlatform(params.get('src')) ? params.get('src') : 'meta';
|
||||
@@ -113,6 +118,14 @@ export default function PublicAdLanding() {
|
||||
<p className="text-[11px] text-zinc-400 mt-4 flex items-center justify-center gap-1">
|
||||
<ShieldCheck size={12} /> Your information is kept private and used only to contact you about this request.
|
||||
</p>
|
||||
{cameFromApp && (
|
||||
<button
|
||||
onClick={() => navigate(-1)}
|
||||
className="mt-6 inline-flex items-center gap-1.5 text-sm font-semibold text-zinc-600 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-white transition-colors"
|
||||
>
|
||||
<ArrowLeft size={16} /> Back to Ad Engine
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -120,6 +133,18 @@ export default function PublicAdLanding() {
|
||||
|
||||
return (
|
||||
<div className="min-h-[100dvh] w-full bg-zinc-50 dark:bg-[#09090b]">
|
||||
{/* Back to Ad Engine — only when opened as a preview from inside the CRM */}
|
||||
{cameFromApp && (
|
||||
<div className="max-w-2xl mx-auto px-4 pt-4">
|
||||
<button
|
||||
onClick={() => navigate(-1)}
|
||||
className="inline-flex items-center gap-1.5 text-sm font-semibold text-zinc-600 dark:text-zinc-300 hover:text-zinc-900 dark:hover:text-white transition-colors"
|
||||
>
|
||||
<ArrowLeft size={16} /> Back to Ad Engine
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Sponsored banner — simulates the ad context */}
|
||||
<div className="w-full bg-zinc-900 text-white/80 text-[11px] py-1.5 px-4 flex items-center justify-center gap-1.5">
|
||||
<Megaphone size={12} />
|
||||
|
||||
Reference in New Issue
Block a user