# Task Fix: Quotation Template JSON Viewer Overflow & Sheet Refactor

## Status

Planned Fix

## Objective

Fix the Quotation Template settings page layout overflow caused by rendering a full PDFME JSON schema inline.

The page should no longer render large JSON content directly in the main content area. Instead, each template version should expose a compact `View JSON` action that opens a scrollable Sheet viewer.

This fix improves:

* page readability
* button visibility
* layout stability
* JSON review experience
* future maintainability for large PDFME templates

---

## Problem

Current page:

```txt
/dashboard/crm/settings/templates
```

renders full JSON schema inline.

Observed issue:

* full JSON expands vertically and horizontally
* content overflows the visible page
* buttons/actions become hard to find
* page is difficult to operate
* JSON block dominates the whole settings page

Current pattern is likely similar to:

```tsx
<pre>{JSON.stringify(schemaJson, null, 2)}</pre>
```

or:

```tsx
<code>{JSON.stringify(version.schemaJson, null, 2)}</code>
```

This should be removed from the main page layout.

---

## Screenshot Context

Current UI shows:

```txt
Quotation Templates
Template Configuration Center
ALLA Quotation Standard
Version 1.0
Large inline JSON block
```

The large inline JSON causes the page to become visually noisy and may hide or push important actions away from the viewport.

---

## Mandatory Review

Review before implementation:

```txt
src/app/dashboard/crm/settings/templates/**
src/features/crm/document-templates/**
src/features/crm/quotations/**
src/components/ui/sheet.tsx
src/components/ui/button.tsx
```

Also search for inline JSON rendering:

```bash
rg "JSON.stringify|schemaJson|schema_json|<pre|<code" src/app/dashboard/crm/settings/templates src/features/crm/document-templates src/features/crm/quotations
```

---

## Required UX Change

Replace inline JSON rendering with a Sheet-based viewer.

Main page should display only compact information.

Each template version card/row should show:

```txt
Version
File path
Mapping count
Table column count
Active status
View JSON button
```

When user clicks:

```txt
View JSON
```

Open a right-side Sheet.

Sheet should show:

```txt
Title: Template Schema JSON
Description: version + file path
Actions: Copy JSON
Content: formatted JSON in a scrollable code block
```

---

## Scope 1: Remove Inline JSON From Main Page

Find the current inline JSON block and remove it from normal page flow.

Do not render full JSON directly inside:

```txt
Card
Accordion
Tabs
Main page content
```

Replace it with a compact action button.

Incorrect:

```tsx
<pre className="...">
  {JSON.stringify(schemaJson, null, 2)}
</pre>
```

Correct:

```tsx
<TemplateJsonSheet
  version={version.version}
  filePath={version.filePath}
  schemaJson={version.schemaJson}
/>
```

---

## Scope 2: Create Template JSON Sheet Component

Create component:

```txt
src/features/crm/document-templates/components/template-json-sheet.tsx
```

If the feature folder differs, place it near the current template settings components.

Component props:

```ts
type TemplateJsonSheetProps = {
  version: string;
  filePath?: string | null;
  schemaJson: unknown;
  triggerLabel?: string;
};
```

Required behavior:

* client component
* uses shadcn `Sheet`
* trigger button opens Sheet
* formats JSON with `JSON.stringify(schemaJson ?? {}, null, 2)`
* displays JSON inside scrollable area
* includes copy-to-clipboard button
* handles invalid or empty JSON safely
* does not crash if schemaJson is null

---

## Scope 3: Sheet Layout Rules

Use:

```tsx
<SheetContent side="right" className="w-full sm:max-w-4xl">
```

or if project layout requires:

```tsx
<SheetContent side="right" className="w-full max-w-[90vw] sm:max-w-5xl">
```

JSON block should use:

```txt
max-h-[calc(100vh-180px)]
overflow-auto
rounded-lg
border
bg-muted
p-4
font-mono
text-xs
whitespace-pre
```

Important:

* JSON scrolls inside Sheet
* main page does not grow because of JSON
* horizontal JSON overflow is contained inside Sheet
* Sheet remains usable on smaller screens

---

## Scope 4: Copy JSON Action

Add:

```txt
Copy JSON
```

Behavior:

* copy formatted JSON to clipboard
* show success toast if toast utility exists
* if no toast utility exists, copy silently or use existing notification pattern

Recommended:

```tsx
await navigator.clipboard.writeText(formattedJson);
toast.success('Copied JSON');
```

Rules:

* do not import a new toast library if project already has one
* use existing toast/sonner convention

---

## Scope 5: Compact Version Card UI

Refactor version display.

Instead of showing JSON inline, display a compact card section like:

```txt
Version 1.0
src/pdfme_template/ALLA_template_pdfme_fainal3.json

Mappings: 12
Table Columns: 24
Status: Active

[View JSON]
```

If mapping counts are already available, use them.

If not available, show only safe existing metadata.

Do not introduce extra server queries unless necessary.

---

## Scope 6: Empty / Missing JSON State

If `schemaJson` is missing:

Sheet should show:

```txt
No schema JSON available.
```

or:

```json
{}
```

Do not throw runtime error.

---

## Scope 7: Optional JSON Summary

If easy, add small metadata before the button:

```txt
Pages: n
Schemas: n
PDFME Version: x
```

Possible calculation:

```ts
const pageCount = Array.isArray(schemaJson?.schemas)
  ? schemaJson.schemas.length
  : 0;
```

This is optional and should not block the fix.

---

## Scope 8: Accessibility

Requirements:

* button label must be clear
* Sheet title must exist
* code block should be selectable
* copy button should have visible text, not icon only
* no hidden overflow on the whole page

---

## Scope 9: Do Not Change Template Data Model

This is UI-only.

Do not change:

```txt
crm_document_templates
crm_document_template_versions
crm_document_template_mappings
crm_document_template_table_columns
PDFME schema format
template seed behavior
template upload behavior
quotation PDF generation
```

---

## Suggested Component Example

```tsx
'use client';

import { useMemo } from 'react';
import { Copy, Eye } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger
} from '@/components/ui/sheet';

type TemplateJsonSheetProps = {
  version: string;
  filePath?: string | null;
  schemaJson: unknown;
  triggerLabel?: string;
};

export function TemplateJsonSheet({
  version,
  filePath,
  schemaJson,
  triggerLabel = 'View JSON'
}: TemplateJsonSheetProps) {
  const formattedJson = useMemo(() => {
    try {
      return JSON.stringify(schemaJson ?? {}, null, 2);
    } catch {
      return '{}';
    }
  }, [schemaJson]);

  const handleCopy = async () => {
    await navigator.clipboard.writeText(formattedJson);
    toast.success('Copied JSON');
  };

  return (
    <Sheet>
      <SheetTrigger asChild>
        <Button variant='outline' size='sm'>
          <Eye className='mr-2 h-4 w-4' />
          {triggerLabel}
        </Button>
      </SheetTrigger>

      <SheetContent side='right' className='w-full sm:max-w-4xl'>
        <SheetHeader>
          <SheetTitle>Template Schema JSON</SheetTitle>
          <SheetDescription>
            Version {version}
            {filePath ? ` · ${filePath}` : ''}
          </SheetDescription>
        </SheetHeader>

        <div className='mt-4 flex items-center justify-end'>
          <Button variant='outline' size='sm' onClick={handleCopy}>
            <Copy className='mr-2 h-4 w-4' />
            Copy JSON
          </Button>
        </div>

        <pre className='mt-4 max-h-[calc(100vh-180px)] overflow-auto rounded-lg border bg-muted p-4 font-mono text-xs whitespace-pre'>
          <code>{formattedJson}</code>
        </pre>
      </SheetContent>
    </Sheet>
  );
}
```

Adjust import paths and formatting to match the project style.

---

## Scope 10: Page-Level Overflow Guard

Review parent containers.

Ensure the templates page does not use layout classes that create viewport overflow unexpectedly.

Recommended:

```txt
space-y-6
overflow-hidden only when intentional
min-w-0 on flex/grid children
```

If cards contain long paths, use:

```txt
truncate
break-all
```

For file paths:

```tsx
<p className="break-all text-sm text-muted-foreground">
  {filePath}
</p>
```

---

## Verification

Run:

```bash
npm exec tsc --noEmit
npm run build
```

Manual verification:

```txt
Open /dashboard/crm/settings/templates
Page no longer shows full JSON inline
Page does not overflow because of JSON
Template version card remains compact
View JSON button is visible
Click View JSON
Sheet opens from right side
JSON displays formatted
JSON scrolls inside Sheet
Copy JSON works
Close Sheet
No regression in quotation PDF preview/download
```

Search verification:

```bash
rg "JSON.stringify|<pre|schemaJson|schema_json" src/app/dashboard/crm/settings/templates src/features/crm/document-templates src/features/crm/quotations
```

Allowed:

```txt
TemplateJsonSheet
intentional JSON formatting inside Sheet
server-side schema serialization
```

Not allowed:

```txt
inline full JSON rendering on main settings page
```

---

## Definition of Done

Task is complete when:

* Quotation Template settings page no longer renders full JSON inline
* JSON schema opens only through Sheet
* Sheet has independent scroll area
* Copy JSON action works
* Page actions remain visible
* Layout overflow is fixed
* TypeScript passes
* Build passes

Result:

```txt
Quotation Template JSON Viewer = Refactored
Template Settings Layout = Stable
Admin UX = Improved
```
