TemplatesPage.tsx5.9 KBView on GitHub
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@/components/ui/accordion';
import templateColors from '@/config/template-colors.json';
import { useState } from 'react';
import { renderTemplateContent } from './template-utils';
import { EMAIL_TEMPLATE_FIXTURES } from './template-fixtures';

/**
 * The templates page — PRESERVED, DELIBERATELY UNREACHABLE.
 *
 * Lifted out of the old onboarding modal before it was deleted, because the
 * layout (template list beside rendered content, with the source emails the
 * template was learned from underneath) is what we want to build the real
 * templates surface on.
 *
 * It is exported but imported by nothing: no route, no menu entry, no link. It
 * stays in the project so it keeps type-checking and stays honest against the
 * components it uses. Wiring it up is a deliberate act, not an accident.
 */
export function TemplatesPage() {
  const [selectedTemplate, setSelectedTemplate] = useState(0);

  return (
    <div className="flex h-full flex-col p-6">
      <div className="mb-4 flex-shrink-0">
        <h2 className="mb-2 text-3xl font-semibold">Templates</h2>
        <p className="text-muted-foreground text-sm">
          Pre-configured email templates with AI variables
        </p>
      </div>

      <div className="grid min-h-0 flex-1 grid-cols-2 gap-6">
        {/* Left column - Template list */}
        <div className="min-h-0 space-y-2 overflow-y-auto">
          {EMAIL_TEMPLATE_FIXTURES.map((template, index) => (
            <button
              key=[redacted]
              onClick={() => setSelectedTemplate(index)}
              className={`w-full rounded-lg border p-3 text-left transition-all ${
                selectedTemplate === index
                  ? 'bg-primary/10 border-primary'
                  : 'bg-muted/30 hover:bg-muted/50 border-transparent'
              }`}
            >
              <p className="text-sm font-medium">{template.name}</p>
            </button>
          ))}
        </div>

        {/* Right column - Template content */}
        <div className="bg-muted/30 min-h-0 space-y-4 overflow-y-auto rounded-lg border p-4">
          <div>
            <h3 className="mb-4 font-semibold">{EMAIL_TEMPLATE_FIXTURES[selectedTemplate].name}</h3>
            <div className="bg-background whitespace-pre-wrap rounded border p-4 font-mono text-sm">
              {renderTemplateContent(EMAIL_TEMPLATE_FIXTURES[selectedTemplate].content)}
            </div>
          </div>

          <div className="space-y-2 border-t pt-4">
            <p className="text-muted-foreground mb-2 text-xs">
              AI Variables like{' '}
              <code
                className={`${templateColors.variableColors.default.background} ${templateColors.variableColors.default.text} rounded px-1 text-xs`}
              >
                {'{first_name}'}
              </code>{' '}
              are automatically filled by Cedar&apos;s AI based on context.
            </p>
            <p className="text-muted-foreground text-xs">
              Special notation{' '}
              <code
                className={`${templateColors.variableColors['@knowledge base'].background} ${templateColors.variableColors['@knowledge base'].text} rounded px-1 text-xs`}
              >
                {'@Knowledge Base'}
              </code>{' '}
              queries your knowledge base for relevant information.
            </p>
            <p className="text-muted-foreground text-xs">
              Calendar integration{' '}
              <code
                className={`${templateColors.variableColors['@calendar'].background} ${templateColors.variableColors['@calendar'].text} rounded px-1 text-xs`}
              >
                {'@Calendar'}
              </code>{' '}
              helps with scheduling and time-based suggestions.
            </p>
          </div>

          {/* Source emails section */}
          <div className="border-t pt-4">
            <p className="mb-3 text-sm font-medium">
              Source: {EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceCount} emails this month
            </p>
            <Accordion type="single" collapsible className="w-full">
              {EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceEmails.map((email) => (
                <AccordionItem key=[redacted] value={`email-${email.id}`} className="border-none">
                  <AccordionTrigger className="bg-muted/50 hover:bg-muted/70 rounded-lg px-3 py-2 text-left text-sm font-normal [&[data-state=open]>div]:mb-2">
                    <div className="flex w-full items-start justify-between pr-4">
                      <div className="min-w-0 flex-1">
                        <p className="truncate font-medium">{email.subject}</p>
                        <p className="text-muted-foreground truncate text-xs">
                          From: {email.from} • {new Date(email.date).toLocaleDateString()}
                        </p>
                      </div>
                    </div>
                  </AccordionTrigger>
                  <AccordionContent className="px-3 pb-3">
                    <div className="bg-background rounded border p-3 text-sm">
                      <p className="text-muted-foreground mb-2 text-xs">Email preview:</p>
                      <p>{email.preview}</p>
                    </div>
                  </AccordionContent>
                </AccordionItem>
              ))}
            </Accordion>
            {EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceCount >
              EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceEmails.length && (
              <p className="text-muted-foreground mt-2 text-xs">
                ...and{' '}
                {EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceCount -
                  EMAIL_TEMPLATE_FIXTURES[selectedTemplate].sourceEmails.length}{' '}
                more emails
              </p>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}