Major additions: - Web-based setup wizard (setup.php, setup_wizard.php, setup-wizard.js) - Production Docker configuration (docker-compose.prod.yml, .env.production) - Database initialization SQL files (deploy/init_settings.sql) - Template builder system with drag-and-drop UI - Advanced features (OAuth, CDN, enhanced analytics, monetization) - Comprehensive documentation (deployment guides, quick start, feature docs) - Design system with accessibility and responsive layout - Deployment automation scripts (deploy.ps1, generate-secrets.ps1) Setup wizard allows customization of: - Platform name and branding - Domain configuration - Membership tiers and pricing - Admin credentials - Feature toggles Database includes 270+ tables for complete video streaming platform with advanced features for analytics, moderation, template building, and monetization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
378 lines
8.6 KiB
Smarty
378 lines
8.6 KiB
Smarty
{* Template Manager - List View *}
|
|
|
|
<div class="template-manager-container">
|
|
<div class="tm-header">
|
|
<h1>My Templates</h1>
|
|
<a href="/f_modules/m_backend/template_manager.php?action=new" class="btn btn-primary">
|
|
<i class="icon-plus"></i> Create New Template
|
|
</a>
|
|
</div>
|
|
|
|
{if $message}
|
|
<div class="alert alert-{$message_type}">
|
|
{$message}
|
|
</div>
|
|
{/if}
|
|
|
|
{if $templates|@count > 0}
|
|
<div class="tm-grid">
|
|
{foreach $templates as $template}
|
|
<div class="tm-card {if $template.is_active}active{/if}">
|
|
<div class="tm-card-preview">
|
|
{if $template.preview_image}
|
|
<img src="{$template.preview_image}" alt="{$template.template_name}" />
|
|
{else}
|
|
<div class="tm-preview-placeholder">
|
|
<i class="icon-layout"></i>
|
|
<span>{$template.template_type}</span>
|
|
</div>
|
|
{/if}
|
|
|
|
{if $template.is_active}
|
|
<span class="tm-badge tm-badge-active">Active</span>
|
|
{/if}
|
|
</div>
|
|
|
|
<div class="tm-card-content">
|
|
<h3 class="tm-card-title">{$template.template_name}</h3>
|
|
|
|
<div class="tm-card-meta">
|
|
<span class="tm-meta-item">
|
|
<i class="icon-type"></i>
|
|
{$template.template_type|replace:'_':' '|ucwords}
|
|
</span>
|
|
<span class="tm-meta-item">
|
|
<i class="icon-eye"></i>
|
|
{$template.views} views
|
|
</span>
|
|
<span class="tm-meta-item">
|
|
<i class="icon-clock"></i>
|
|
{$template.updated_at|date_format:"%b %d, %Y"}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tm-card-actions">
|
|
<a href="/f_modules/m_backend/template_manager.php?action=edit&id={$template.template_id}"
|
|
class="btn btn-sm btn-secondary">
|
|
<i class="icon-edit"></i> Edit
|
|
</a>
|
|
|
|
<button class="btn btn-sm btn-secondary dropdown-toggle" data-toggle="dropdown">
|
|
<i class="icon-more-vertical"></i>
|
|
</button>
|
|
|
|
<div class="dropdown-menu">
|
|
<a href="/f_modules/m_frontend/templatebuilder_ajax.php?action=preview&template_id={$template.template_id}"
|
|
target="_blank" class="dropdown-item">
|
|
<i class="icon-eye"></i> Preview
|
|
</a>
|
|
|
|
<a href="/f_modules/m_backend/template_manager.php?action=duplicate&id={$template.template_id}"
|
|
class="dropdown-item">
|
|
<i class="icon-copy"></i> Duplicate
|
|
</a>
|
|
|
|
<a href="/f_modules/m_backend/template_manager.php?action=toggle_active&id={$template.template_id}&is_active={if $template.is_active}0{else}1{/if}"
|
|
class="dropdown-item">
|
|
<i class="icon-{if $template.is_active}eye-off{else}eye{/if}"></i>
|
|
{if $template.is_active}Deactivate{else}Activate{/if}
|
|
</a>
|
|
|
|
<div class="dropdown-divider"></div>
|
|
|
|
<a href="/f_modules/m_backend/template_manager.php?action=delete&id={$template.template_id}"
|
|
class="dropdown-item text-danger"
|
|
onclick="return confirm('Are you sure you want to delete this template?')">
|
|
<i class="icon-trash"></i> Delete
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/foreach}
|
|
</div>
|
|
|
|
{else}
|
|
<div class="tm-empty">
|
|
<i class="icon-layout"></i>
|
|
<h3>No templates yet</h3>
|
|
<p>Create your first custom template to get started</p>
|
|
<a href="/f_modules/m_backend/template_manager.php?action=new" class="btn btn-primary">
|
|
<i class="icon-plus"></i> Create Template
|
|
</a>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.template-manager-container {
|
|
padding: 30px;
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.tm-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.tm-header h1 {
|
|
margin: 0;
|
|
font-size: 28px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tm-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
|
gap: 24px;
|
|
}
|
|
|
|
.tm-card {
|
|
background: white;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.tm-card:hover {
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.tm-card.active {
|
|
border-color: #10b981;
|
|
}
|
|
|
|
.tm-card-preview {
|
|
height: 200px;
|
|
background: #f3f4f6;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.tm-card-preview img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.tm-preview-placeholder {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #9ca3af;
|
|
}
|
|
|
|
.tm-preview-placeholder i {
|
|
font-size: 48px;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.tm-badge {
|
|
position: absolute;
|
|
top: 12px;
|
|
right: 12px;
|
|
padding: 4px 12px;
|
|
border-radius: 20px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tm-badge-active {
|
|
background: #10b981;
|
|
color: white;
|
|
}
|
|
|
|
.tm-card-content {
|
|
padding: 16px;
|
|
}
|
|
|
|
.tm-card-title {
|
|
margin: 0 0 12px;
|
|
font-size: 18px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tm-card-meta {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
}
|
|
|
|
.tm-meta-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: 13px;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.tm-meta-item i {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.tm-card-actions {
|
|
padding: 12px 16px;
|
|
border-top: 1px solid #e5e7eb;
|
|
display: flex;
|
|
gap: 8px;
|
|
position: relative;
|
|
}
|
|
|
|
.tm-empty {
|
|
text-align: center;
|
|
padding: 80px 40px;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.tm-empty i {
|
|
font-size: 64px;
|
|
margin-bottom: 16px;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.tm-empty h3 {
|
|
margin: 0 0 8px;
|
|
font-size: 24px;
|
|
color: #111827;
|
|
}
|
|
|
|
.tm-empty p {
|
|
margin: 0 0 24px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.alert {
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.alert-success {
|
|
background: #d1fae5;
|
|
color: #065f46;
|
|
border: 1px solid #10b981;
|
|
}
|
|
|
|
.alert-error {
|
|
background: #fee2e2;
|
|
color: #991b1b;
|
|
border: 1px solid #ef4444;
|
|
}
|
|
|
|
.dropdown-menu {
|
|
display: none;
|
|
position: absolute;
|
|
right: 0;
|
|
top: 100%;
|
|
background: white;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 6px;
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
min-width: 180px;
|
|
z-index: 10;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.dropdown-toggle:focus + .dropdown-menu,
|
|
.dropdown-toggle:active + .dropdown-menu,
|
|
.dropdown-menu:hover {
|
|
display: block;
|
|
}
|
|
|
|
.dropdown-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 16px;
|
|
color: #374151;
|
|
text-decoration: none;
|
|
font-size: 14px;
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.dropdown-item:hover {
|
|
background: #f3f4f6;
|
|
}
|
|
|
|
.dropdown-item.text-danger {
|
|
color: #ef4444;
|
|
}
|
|
|
|
.dropdown-divider {
|
|
height: 1px;
|
|
background: #e5e7eb;
|
|
margin: 4px 0;
|
|
}
|
|
|
|
.btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 8px 16px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.btn-primary {
|
|
background: #3b82f6;
|
|
color: white;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background: #2563eb;
|
|
}
|
|
|
|
.btn-secondary {
|
|
background: #f3f4f6;
|
|
color: #374151;
|
|
border: 1px solid #e5e7eb;
|
|
}
|
|
|
|
.btn-secondary:hover {
|
|
background: #e5e7eb;
|
|
}
|
|
|
|
.btn-sm {
|
|
padding: 6px 12px;
|
|
font-size: 13px;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// Simple dropdown toggle
|
|
document.querySelectorAll('.dropdown-toggle').forEach(toggle => {
|
|
toggle.addEventListener('click', function(e) {
|
|
e.stopPropagation();
|
|
const menu = this.nextElementSibling;
|
|
|
|
// Close all other dropdowns
|
|
document.querySelectorAll('.dropdown-menu').forEach(m => {
|
|
if (m !== menu) m.style.display = 'none';
|
|
});
|
|
|
|
// Toggle current
|
|
menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
|
|
});
|
|
});
|
|
|
|
// Close dropdowns when clicking outside
|
|
document.addEventListener('click', () => {
|
|
document.querySelectorAll('.dropdown-menu').forEach(m => {
|
|
m.style.display = 'none';
|
|
});
|
|
});
|
|
</script>
|