- Add JavaScript to load user profile from /api/auth/me endpoint - Save access_token to localStorage/sessionStorage on login - Update user menu to show actual user name and email - Toggle Sign in/Sign out based on authentication state - Add IDs to user menu elements for dynamic updates
1142 lines
50 KiB
HTML
1142 lines
50 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>GB Slides</title>
|
||
<link rel="stylesheet" href="slides.css" />
|
||
</head>
|
||
<body>
|
||
<div class="slides-container">
|
||
<!-- Sidebar: Slide Thumbnails -->
|
||
<aside class="slides-sidebar" id="slides-sidebar">
|
||
<div class="sidebar-header">
|
||
<h2>Slides</h2>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="toggleSidebar()"
|
||
title="Toggle Sidebar"
|
||
>
|
||
<svg
|
||
width="20"
|
||
height="20"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<div class="sidebar-search">
|
||
<input
|
||
type="text"
|
||
placeholder="Search presentations..."
|
||
id="search-input"
|
||
oninput="searchPresentations(this.value)"
|
||
/>
|
||
<svg
|
||
class="search-icon"
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<circle cx="11" cy="11" r="8"></circle>
|
||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||
</svg>
|
||
</div>
|
||
|
||
<div class="slide-thumbnails" id="slide-thumbnails">
|
||
<!-- Thumbnails rendered dynamically -->
|
||
</div>
|
||
|
||
<div class="sidebar-actions">
|
||
<button class="btn-add-slide" onclick="addSlide()">
|
||
<svg
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
<span>Add Slide</span>
|
||
</button>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Main Content Area -->
|
||
<main class="slides-main">
|
||
<!-- Toolbar -->
|
||
<div class="slides-toolbar">
|
||
<div class="toolbar-left">
|
||
<button
|
||
class="btn-icon"
|
||
onclick="toggleSidebar()"
|
||
title="Toggle Sidebar"
|
||
>
|
||
<svg
|
||
width="20"
|
||
height="20"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
ry="2"
|
||
></rect>
|
||
<line x1="9" y1="3" x2="9" y2="21"></line>
|
||
</svg>
|
||
</button>
|
||
<input
|
||
type="text"
|
||
class="presentation-name-input"
|
||
id="presentation-name"
|
||
value="Untitled Presentation"
|
||
onchange="renamePresentation(this.value)"
|
||
/>
|
||
</div>
|
||
|
||
<div class="toolbar-center">
|
||
<!-- Insert Tools -->
|
||
<div class="toolbar-group">
|
||
<button
|
||
class="btn-icon"
|
||
onclick="addTextBox()"
|
||
title="Add Text"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<polyline
|
||
points="4 7 4 4 20 4 20 7"
|
||
></polyline>
|
||
<line x1="9" y1="20" x2="15" y2="20"></line>
|
||
<line x1="12" y1="4" x2="12" y2="20"></line>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="showImageModal()"
|
||
title="Add Image"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
ry="2"
|
||
></rect>
|
||
<circle cx="8.5" cy="8.5" r="1.5"></circle>
|
||
<polyline
|
||
points="21 15 16 10 5 21"
|
||
></polyline>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="showShapeModal()"
|
||
title="Add Shape"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
></rect>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="showChartModal()"
|
||
title="Add Chart"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line
|
||
x1="18"
|
||
y1="20"
|
||
x2="18"
|
||
y2="10"
|
||
></line>
|
||
<line x1="12" y1="20" x2="12" y2="4"></line>
|
||
<line x1="6" y1="20" x2="6" y2="14"></line>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="addTable()"
|
||
title="Add Table"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
></rect>
|
||
<line x1="3" y1="9" x2="21" y2="9"></line>
|
||
<line x1="3" y1="15" x2="21" y2="15"></line>
|
||
<line x1="9" y1="3" x2="9" y2="21"></line>
|
||
<line x1="15" y1="3" x2="15" y2="21"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<span class="toolbar-divider"></span>
|
||
|
||
<!-- Text Formatting -->
|
||
<div class="toolbar-group">
|
||
<select
|
||
class="toolbar-select font-family"
|
||
id="font-family"
|
||
onchange="setFontFamily(this.value)"
|
||
>
|
||
<option value="Inter">Inter</option>
|
||
<option value="Arial">Arial</option>
|
||
<option value="Helvetica">Helvetica</option>
|
||
<option value="Georgia">Georgia</option>
|
||
<option value="Times New Roman">
|
||
Times New Roman
|
||
</option>
|
||
<option value="Courier New">Courier New</option>
|
||
</select>
|
||
<select
|
||
class="toolbar-select font-size"
|
||
id="font-size"
|
||
onchange="setFontSize(this.value)"
|
||
>
|
||
<option value="12">12</option>
|
||
<option value="14">14</option>
|
||
<option value="16">16</option>
|
||
<option value="18">18</option>
|
||
<option value="20">20</option>
|
||
<option value="24" selected>24</option>
|
||
<option value="28">28</option>
|
||
<option value="32">32</option>
|
||
<option value="36">36</option>
|
||
<option value="48">48</option>
|
||
<option value="64">64</option>
|
||
<option value="72">72</option>
|
||
</select>
|
||
</div>
|
||
|
||
<span class="toolbar-divider"></span>
|
||
|
||
<!-- Text Style -->
|
||
<div class="toolbar-group">
|
||
<button
|
||
class="btn-icon"
|
||
id="btn-bold"
|
||
onclick="toggleBold()"
|
||
title="Bold (Ctrl+B)"
|
||
>
|
||
<strong>B</strong>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
id="btn-italic"
|
||
onclick="toggleItalic()"
|
||
title="Italic (Ctrl+I)"
|
||
>
|
||
<em>I</em>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
id="btn-underline"
|
||
onclick="toggleUnderline()"
|
||
title="Underline (Ctrl+U)"
|
||
>
|
||
<u>U</u>
|
||
</button>
|
||
</div>
|
||
|
||
<span class="toolbar-divider"></span>
|
||
|
||
<!-- Colors -->
|
||
<div class="toolbar-group">
|
||
<div class="color-btn" title="Text Color">
|
||
<span style="font-weight: bold">A</span>
|
||
<span
|
||
class="color-indicator"
|
||
id="text-color-indicator"
|
||
style="background: #000000"
|
||
></span>
|
||
<input
|
||
type="color"
|
||
class="color-input"
|
||
id="text-color"
|
||
value="#000000"
|
||
onchange="setTextColor(this.value)"
|
||
/>
|
||
</div>
|
||
<div class="color-btn" title="Fill Color">
|
||
<svg
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="currentColor"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
></rect>
|
||
</svg>
|
||
<span
|
||
class="color-indicator"
|
||
id="fill-color-indicator"
|
||
style="background: #3b82f6"
|
||
></span>
|
||
<input
|
||
type="color"
|
||
class="color-input"
|
||
id="fill-color"
|
||
value="#3b82f6"
|
||
onchange="setFillColor(this.value)"
|
||
/>
|
||
</div>
|
||
<div class="color-btn" title="Stroke Color">
|
||
<svg
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="3"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
></rect>
|
||
</svg>
|
||
<span
|
||
class="color-indicator"
|
||
id="stroke-color-indicator"
|
||
style="background: #1e293b"
|
||
></span>
|
||
<input
|
||
type="color"
|
||
class="color-input"
|
||
id="stroke-color"
|
||
value="#1e293b"
|
||
onchange="setStrokeColor(this.value)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<span class="toolbar-divider"></span>
|
||
|
||
<!-- Alignment -->
|
||
<div class="toolbar-group">
|
||
<button
|
||
class="btn-icon"
|
||
onclick="setTextAlign('left')"
|
||
title="Align Left"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="17" y1="10" x2="3" y2="10"></line>
|
||
<line x1="21" y1="6" x2="3" y2="6"></line>
|
||
<line x1="21" y1="14" x2="3" y2="14"></line>
|
||
<line x1="17" y1="18" x2="3" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="setTextAlign('center')"
|
||
title="Align Center"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="18" y1="10" x2="6" y2="10"></line>
|
||
<line x1="21" y1="6" x2="3" y2="6"></line>
|
||
<line x1="21" y1="14" x2="3" y2="14"></line>
|
||
<line x1="18" y1="18" x2="6" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="setTextAlign('right')"
|
||
title="Align Right"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="21" y1="10" x2="7" y2="10"></line>
|
||
<line x1="21" y1="6" x2="3" y2="6"></line>
|
||
<line x1="21" y1="14" x2="3" y2="14"></line>
|
||
<line x1="21" y1="18" x2="7" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
|
||
<span class="toolbar-divider"></span>
|
||
|
||
<!-- Layer Order -->
|
||
<div class="toolbar-group">
|
||
<button
|
||
class="btn-icon"
|
||
onclick="bringForward()"
|
||
title="Bring Forward"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="8"
|
||
y="8"
|
||
width="13"
|
||
height="13"
|
||
rx="2"
|
||
></rect>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="13"
|
||
height="13"
|
||
rx="2"
|
||
fill="currentColor"
|
||
opacity="0.3"
|
||
></rect>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="sendBackward()"
|
||
title="Send Backward"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="13"
|
||
height="13"
|
||
rx="2"
|
||
></rect>
|
||
<rect
|
||
x="8"
|
||
y="8"
|
||
width="13"
|
||
height="13"
|
||
rx="2"
|
||
fill="currentColor"
|
||
opacity="0.3"
|
||
></rect>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toolbar-right">
|
||
<div class="collaborators" id="collaborators"></div>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="showThemeModal()"
|
||
title="Themes"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<path d="M12 2a10 10 0 0 1 0 20"></path>
|
||
<line x1="2" y1="12" x2="22" y2="12"></line>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="startPresentation()"
|
||
title="Present (F5)"
|
||
>
|
||
<svg
|
||
width="18"
|
||
height="18"
|
||
viewBox="0 0 24 24"
|
||
fill="currentColor"
|
||
>
|
||
<polygon points="5 3 19 12 5 21 5 3"></polygon>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="btn-primary"
|
||
onclick="savePresentation()"
|
||
>
|
||
<svg
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<path
|
||
d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"
|
||
></path>
|
||
<polyline
|
||
points="17 21 17 13 7 13 7 21"
|
||
></polyline>
|
||
<polyline points="7 3 7 8 15 8"></polyline>
|
||
</svg>
|
||
<span>Save</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Slide Canvas Area -->
|
||
<div class="slide-canvas-container" id="canvas-container">
|
||
<div class="slide-canvas" id="slide-canvas">
|
||
<!-- Elements rendered here -->
|
||
</div>
|
||
|
||
<!-- Selection handles (shown when element selected) -->
|
||
<div
|
||
class="selection-handles hidden"
|
||
id="selection-handles"
|
||
>
|
||
<div class="handle nw" data-handle="nw"></div>
|
||
<div class="handle n" data-handle="n"></div>
|
||
<div class="handle ne" data-handle="ne"></div>
|
||
<div class="handle w" data-handle="w"></div>
|
||
<div class="handle e" data-handle="e"></div>
|
||
<div class="handle sw" data-handle="sw"></div>
|
||
<div class="handle s" data-handle="s"></div>
|
||
<div class="handle se" data-handle="se"></div>
|
||
<div class="rotate-handle" data-handle="rotate"></div>
|
||
</div>
|
||
|
||
<!-- Cursor indicators for collaborators -->
|
||
<div class="cursor-indicators" id="cursor-indicators"></div>
|
||
</div>
|
||
|
||
<!-- Status Bar -->
|
||
<div class="slides-status-bar">
|
||
<div class="status-left">
|
||
<span
|
||
>Slide <span id="current-slide-num">1</span> of
|
||
<span id="total-slides">1</span></span
|
||
>
|
||
</div>
|
||
<div class="status-center">
|
||
<span id="save-status"></span>
|
||
</div>
|
||
<div class="status-right">
|
||
<span>Zoom:</span>
|
||
<div class="zoom-control">
|
||
<button class="btn-zoom" onclick="zoomOut()">
|
||
−
|
||
</button>
|
||
<span id="zoom-level">100</span>%
|
||
<button class="btn-zoom" onclick="zoomIn()">
|
||
+
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<!-- Properties Panel -->
|
||
<aside class="slides-properties" id="properties-panel">
|
||
<div class="properties-header">
|
||
<h3>Properties</h3>
|
||
<button
|
||
class="btn-icon"
|
||
onclick="toggleProperties()"
|
||
title="Close"
|
||
>
|
||
<svg
|
||
width="16"
|
||
height="16"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<div class="properties-content" id="properties-content">
|
||
<div class="property-group">
|
||
<label>Position</label>
|
||
<div class="property-row">
|
||
<div class="property-input">
|
||
<span>X</span>
|
||
<input
|
||
type="number"
|
||
id="prop-x"
|
||
onchange="updateElementPosition('x', this.value)"
|
||
/>
|
||
</div>
|
||
<div class="property-input">
|
||
<span>Y</span>
|
||
<input
|
||
type="number"
|
||
id="prop-y"
|
||
onchange="updateElementPosition('y', this.value)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="property-group">
|
||
<label>Size</label>
|
||
<div class="property-row">
|
||
<div class="property-input">
|
||
<span>W</span>
|
||
<input
|
||
type="number"
|
||
id="prop-width"
|
||
onchange="updateElementSize('width', this.value)"
|
||
/>
|
||
</div>
|
||
<div class="property-input">
|
||
<span>H</span>
|
||
<input
|
||
type="number"
|
||
id="prop-height"
|
||
onchange="updateElementSize('height', this.value)"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="property-group">
|
||
<label>Rotation</label>
|
||
<div class="property-row">
|
||
<input
|
||
type="range"
|
||
id="prop-rotation"
|
||
min="0"
|
||
max="360"
|
||
value="0"
|
||
oninput="updateElementRotation(this.value)"
|
||
/>
|
||
<span id="rotation-value">0°</span>
|
||
</div>
|
||
</div>
|
||
<div class="property-group">
|
||
<label>Opacity</label>
|
||
<div class="property-row">
|
||
<input
|
||
type="range"
|
||
id="prop-opacity"
|
||
min="0"
|
||
max="100"
|
||
value="100"
|
||
oninput="updateElementOpacity(this.value)"
|
||
/>
|
||
<span id="opacity-value">100%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
|
||
<!-- Context Menu -->
|
||
<div class="context-menu hidden" id="context-menu">
|
||
<div class="context-item" onclick="cutElement()">
|
||
Cut <span class="shortcut">Ctrl+X</span>
|
||
</div>
|
||
<div class="context-item" onclick="copyElement()">
|
||
Copy <span class="shortcut">Ctrl+C</span>
|
||
</div>
|
||
<div class="context-item" onclick="pasteElement()">
|
||
Paste <span class="shortcut">Ctrl+V</span>
|
||
</div>
|
||
<div class="context-divider"></div>
|
||
<div class="context-item" onclick="duplicateElement()">
|
||
Duplicate <span class="shortcut">Ctrl+D</span>
|
||
</div>
|
||
<div class="context-item" onclick="deleteElement()">
|
||
Delete <span class="shortcut">Del</span>
|
||
</div>
|
||
<div class="context-divider"></div>
|
||
<div class="context-item" onclick="bringToFront()">
|
||
Bring to Front
|
||
</div>
|
||
<div class="context-item" onclick="sendToBack()">Send to Back</div>
|
||
<div class="context-divider"></div>
|
||
<div class="context-item" onclick="lockElement()">Lock/Unlock</div>
|
||
</div>
|
||
|
||
<!-- Slide Context Menu -->
|
||
<div class="context-menu hidden" id="slide-context-menu">
|
||
<div class="context-item" onclick="addSlideAfter()">
|
||
Add Slide After
|
||
</div>
|
||
<div class="context-item" onclick="duplicateSlide()">
|
||
Duplicate Slide
|
||
</div>
|
||
<div class="context-divider"></div>
|
||
<div class="context-item" onclick="deleteSlide()">Delete Slide</div>
|
||
<div class="context-divider"></div>
|
||
<div class="context-item" onclick="showSlideBackground()">
|
||
Change Background
|
||
</div>
|
||
<div class="context-item" onclick="showSlideTransition()">
|
||
Transition...
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Theme Modal -->
|
||
<div class="modal hidden" id="theme-modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>Themes</h3>
|
||
<button
|
||
class="btn-close"
|
||
onclick="hideModal('theme-modal')"
|
||
>
|
||
<svg
|
||
width="20"
|
||
height="20"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="theme-grid">
|
||
<div class="theme-item" onclick="applyTheme('default')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: linear-gradient(
|
||
135deg,
|
||
#3b82f6,
|
||
#1e40af
|
||
);
|
||
"
|
||
></div>
|
||
<span>Default</span>
|
||
</div>
|
||
<div class="theme-item" onclick="applyTheme('dark')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: linear-gradient(
|
||
135deg,
|
||
#1e293b,
|
||
#0f172a
|
||
);
|
||
"
|
||
></div>
|
||
<span>Dark</span>
|
||
</div>
|
||
<div class="theme-item" onclick="applyTheme('minimal')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: #ffffff;
|
||
border: 1px solid #e2e8f0;
|
||
"
|
||
></div>
|
||
<span>Minimal</span>
|
||
</div>
|
||
<div class="theme-item" onclick="applyTheme('nature')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: linear-gradient(
|
||
135deg,
|
||
#22c55e,
|
||
#15803d
|
||
);
|
||
"
|
||
></div>
|
||
<span>Nature</span>
|
||
</div>
|
||
<div class="theme-item" onclick="applyTheme('sunset')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: linear-gradient(
|
||
135deg,
|
||
#f97316,
|
||
#dc2626
|
||
);
|
||
"
|
||
></div>
|
||
<span>Sunset</span>
|
||
</div>
|
||
<div class="theme-item" onclick="applyTheme('ocean')">
|
||
<div
|
||
class="theme-preview"
|
||
style="
|
||
background: linear-gradient(
|
||
135deg,
|
||
#06b6d4,
|
||
#0284c7
|
||
);
|
||
"
|
||
></div>
|
||
<span>Ocean</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Shape Modal -->
|
||
<div class="modal hidden" id="shape-modal">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h3>Insert Shape</h3>
|
||
<button
|
||
class="btn-close"
|
||
onclick="hideModal('shape-modal')"
|
||
>
|
||
<svg
|
||
width="20"
|
||
height="20"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="shape-grid">
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('rectangle')"
|
||
title="Rectangle"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="2"
|
||
></rect>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('rounded-rectangle')"
|
||
title="Rounded Rectangle"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<rect
|
||
x="3"
|
||
y="3"
|
||
width="18"
|
||
height="18"
|
||
rx="6"
|
||
></rect>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('ellipse')"
|
||
title="Ellipse"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<ellipse
|
||
cx="12"
|
||
cy="12"
|
||
rx="9"
|
||
ry="9"
|
||
></ellipse>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('triangle')"
|
||
title="Triangle"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<polygon points="12,3 21,21 3,21"></polygon>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('diamond')"
|
||
title="Diamond"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<polygon
|
||
points="12,2 22,12 12,22 2,12"
|
||
></polygon>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('star')"
|
||
title="Star"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<polygon
|
||
points="12,2 15,9 22,9 17,14 19,21 12,17 5,21 7,14 2,9 9,9"
|
||
></polygon>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('arrow-right')"
|
||
title="Arrow Right"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<polygon
|
||
points="2,8 14,8 14,4 22,12 14,20 14,16 2,16"
|
||
></polygon>
|
||
</svg>
|
||
</button>
|
||
<button
|
||
class="shape-btn"
|
||
onclick="addShape('callout')"
|
||
title="Callout"
|
||
>
|
||
<svg
|
||
width="40"
|
||
height="40"
|
||
viewBox="0 0 24 24"
|
||
fill="#3b82f6"
|
||
>
|
||
<path
|
||
d="M3,3 L21,3 L21,15 L12,15 L6,21 L6,15 L3,15 Z"
|
||
></path>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Chart Modal -->
|
||
<div class="modal hidden" id="chart-modal">
|
||
<div class="modal-content modal-large">
|
||
<div class="modal-header">
|
||
<h3>Insert Chart</h3>
|
||
<button
|
||
class="btn-close"
|
||
onclick="hideModal('chart-modal')"
|
||
>
|
||
<svg
|
||
width="20"
|
||
height="20"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="chart-type-selector">
|
||
<button class="chart-type-btn active" data-type="bar">
|
||
<svg
|
||
width="32"
|
||
height="32"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<rect x="3" y="12" width="4" height="9"></rect>
|
||
<rect x="10" y="8" width="4" height="13"></rect>
|
||
<rect x="17" y="4" width="4" height="17"></rect>
|
||
</svg>
|
||
<span>Bar</span>
|
||
</button>
|
||
<button class="chart-type-btn" data-type="line">
|
||
<svg
|
||
width="32"
|
||
height="32"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<polyline
|
||
points="3,17 8,12 13,16 21,6"
|
||
></polyline>
|
||
</svg>
|
||
<span>Line</span>
|
||
</button>
|
||
<button class="chart-type-btn" data-type="pie">
|
||
<svg
|
||
width="32"
|
||
height="32"
|
||
viewBox="0 0 24 24"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
stroke-width="2"
|
||
>
|
||
<circle cx="12" cy="12" r="10"></circle>
|
||
<path
|
||
d="M12,12 L12,2 A10,10 0 0,1 21,16 Z"
|
||
></path>
|
||
</svg>
|
||
<span>Pie</span>
|
||
</button>
|
||
</div>
|
||
<div class="chart-data-input">
|
||
<label>Chart Data (CSV format)</label>
|
||
<textarea
|
||
id="chart-data-input"
|
||
rows="5"
|
||
placeholder="Label,Value
|
||
Q1,100
|
||
Q2,150
|
||
Q3,120
|
||
Q4,200"
|
||
></textarea>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button
|
||
class="btn-secondary"
|
||
onclick="hideModal('chart-modal')"
|
||
>
|
||
Cancel
|
||
</button>
|
||
<button class="btn-primary" onclick="insertChart()">
|
||
Insert Chart
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/suite/slides/slides.js"></script>
|
||
</body>
|
||
</html>
|