99 CheckCircle ,
1010 Clock ,
1111 Edit2 ,
12+ Eye ,
13+ Layers ,
1214 Mail ,
1315 Plus ,
1416 Save ,
@@ -95,10 +97,13 @@ const triggerInfo: Record<
9597 } ,
9698} ;
9799
100+ type ViewMode = "sequences" | "template" ;
101+
98102export default function EmailsAdminPage ( ) {
99103 const params = useParams ( ) ;
100104 const challengeId = params . id as string ;
101105
106+ const [ viewMode , setViewMode ] = useState < ViewMode > ( "sequences" ) ;
102107 const [ selectedEmailId , setSelectedEmailId ] = useState < string | null > ( null ) ;
103108 const [ isCreateOpen , setIsCreateOpen ] = useState ( false ) ;
104109 const [ isEditing , setIsEditing ] = useState ( false ) ;
@@ -123,6 +128,8 @@ export default function EmailsAdminPage() {
123128 challengeId : challengeId as Id < "challenges" > ,
124129 } ) ;
125130
131+ const templatePreview = useQuery ( api . queries . emailSequences . getEmailTemplatePreview ) ;
132+
126133 const selectedEmail = useQuery (
127134 api . queries . emailSequences . getById ,
128135 selectedEmailId ? { emailSequenceId : selectedEmailId as Id < "emailSequences" > } : "skip"
@@ -261,7 +268,130 @@ export default function EmailsAdminPage() {
261268 }
262269
263270 return (
264- < div className = "flex h-[calc(100vh-140px)] gap-4" >
271+ < div className = "flex h-[calc(100vh-140px)] flex-col gap-3" >
272+ { /* View Mode Toggle */ }
273+ < div className = "flex items-center gap-2" >
274+ < button
275+ onClick = { ( ) => setViewMode ( "sequences" ) }
276+ className = { cn (
277+ "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors" ,
278+ viewMode === "sequences"
279+ ? "bg-amber-500/15 text-amber-400"
280+ : "text-zinc-500 hover:bg-zinc-800 hover:text-zinc-300"
281+ ) }
282+ >
283+ < Layers className = "h-3.5 w-3.5" />
284+ Email Sequences
285+ </ button >
286+ < button
287+ onClick = { ( ) => setViewMode ( "template" ) }
288+ className = { cn (
289+ "flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors" ,
290+ viewMode === "template"
291+ ? "bg-amber-500/15 text-amber-400"
292+ : "text-zinc-500 hover:bg-zinc-800 hover:text-zinc-300"
293+ ) }
294+ >
295+ < Eye className = "h-3.5 w-3.5" />
296+ Email Template
297+ </ button >
298+ </ div >
299+
300+ { /* Template Preview Mode */ }
301+ { viewMode === "template" ? (
302+ < div className = "flex flex-1 gap-4 overflow-hidden" >
303+ { /* Info Panel */ }
304+ < div className = "flex w-1/3 flex-col gap-3" >
305+ < div className = "rounded border border-zinc-800 bg-zinc-900 p-4" >
306+ < div className = "mb-3 flex items-center gap-2" >
307+ < div className = "flex h-8 w-8 items-center justify-center rounded bg-amber-500/15" >
308+ < Mail className = "h-4 w-4 text-amber-400" />
309+ </ div >
310+ < div >
311+ < h3 className = "text-sm font-medium text-zinc-100" > Base Email Template</ h3 >
312+ < p className = "text-[10px] text-zinc-500" > Used across all transactional emails</ p >
313+ </ div >
314+ </ div >
315+ < p className = "text-xs leading-relaxed text-zinc-400" >
316+ This is the shared email template that wraps all transactional emails sent from March Fitness, including invite emails, welcome emails, and weekly recaps.
317+ </ p >
318+ </ div >
319+
320+ < div className = "rounded border border-zinc-800 bg-zinc-900 p-4" >
321+ < h4 className = "mb-2 text-[10px] font-medium uppercase tracking-wider text-zinc-500" >
322+ Template Components
323+ </ h4 >
324+ < div className = "space-y-2" >
325+ < div className = "rounded border border-zinc-800 bg-zinc-800/50 px-3 py-2" >
326+ < div className = "text-xs font-medium text-zinc-300" > Brand Header</ div >
327+ < div className = "text-[10px] text-zinc-500" > Wordmark + indigo-fuchsia gradient divider</ div >
328+ </ div >
329+ < div className = "rounded border border-zinc-800 bg-zinc-800/50 px-3 py-2" >
330+ < div className = "text-xs font-medium text-zinc-300" > Dark Card</ div >
331+ < div className = "text-[10px] text-zinc-500" > Title, subtitle, content, callouts, and CTA buttons</ div >
332+ </ div >
333+ < div className = "rounded border border-zinc-800 bg-zinc-800/50 px-3 py-2" >
334+ < div className = "text-xs font-medium text-zinc-300" > Footer</ div >
335+ < div className = "text-[10px] text-zinc-500" > Context line + march.fit wordmark link</ div >
336+ </ div >
337+ </ div >
338+ </ div >
339+
340+ < div className = "rounded border border-zinc-800 bg-zinc-900 p-4" >
341+ < h4 className = "mb-2 text-[10px] font-medium uppercase tracking-wider text-zinc-500" >
342+ Used In
343+ </ h4 >
344+ < div className = "space-y-1.5" >
345+ { [
346+ { name : "Invite Emails" , desc : "Sent when users invite friends" } ,
347+ { name : "Welcome Email" , desc : "Auto-sent on challenge signup" } ,
348+ { name : "Weekly Recaps" , desc : "Sent after each week" } ,
349+ { name : "Challenge Complete" , desc : "Sent when challenge ends" } ,
350+ ] . map ( ( item ) => (
351+ < div key = { item . name } className = "flex items-center gap-2 rounded bg-zinc-800/50 px-3 py-1.5" >
352+ < CheckCircle className = "h-3 w-3 flex-shrink-0 text-emerald-400" />
353+ < div >
354+ < div className = "text-xs text-zinc-300" > { item . name } </ div >
355+ < div className = "text-[10px] text-zinc-500" > { item . desc } </ div >
356+ </ div >
357+ </ div >
358+ ) ) }
359+ </ div >
360+ </ div >
361+ </ div >
362+
363+ { /* Template Preview */ }
364+ < div className = "flex flex-1 flex-col overflow-hidden rounded border border-zinc-800 bg-zinc-900" >
365+ < div className = "flex items-center justify-between border-b border-zinc-800 px-3 py-2" >
366+ < div className = "flex items-center gap-2" >
367+ < h2 className = "text-sm font-medium text-zinc-100" > Template Preview</ h2 >
368+ < span className = "rounded bg-emerald-500/20 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400" >
369+ Active
370+ </ span >
371+ </ div >
372+ < div className = "text-[10px] text-zinc-500" >
373+ All emails use this layout
374+ </ div >
375+ </ div >
376+ < div className = "flex-1 overflow-hidden bg-[#09090b]" >
377+ { templatePreview ? (
378+ < iframe
379+ srcDoc = { templatePreview . html }
380+ className = "h-full w-full border-0"
381+ title = "Email Template Preview"
382+ sandbox = ""
383+ />
384+ ) : (
385+ < div className = "flex h-full items-center justify-center text-zinc-500" >
386+ Loading template...
387+ </ div >
388+ ) }
389+ </ div >
390+ </ div >
391+ </ div >
392+ ) : (
393+ /* Email Sequences Mode */
394+ < div className = "flex flex-1 gap-4 overflow-hidden" >
265395 { /* Left Column - Email List */ }
266396 < div className = "flex w-1/2 flex-col" >
267397 { /* Header */ }
@@ -781,6 +911,8 @@ export default function EmailsAdminPage() {
781911 </ div >
782912 ) }
783913 </ div >
914+ </ div >
915+ ) }
784916 </ div >
785917 ) ;
786918}
0 commit comments