<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< meta name = " viewport" content = " width=device-width, initial-scale=1.0" >
< title> ARTEP STUDIO PDP - Projects Display Platform</ title>
< style>
:root {
--yellow : #FFD700;
--dark-bg : #000000;
--window-bg : #111111;
--section-bg : #222222;
--glow : 0 0 15px var ( --yellow) ;
--glow-strong : 0 0 25px var ( --yellow) , 0 0 35px var ( --yellow) ;
--accent : #00ff88;
--danger : #ff4444;
--success : #44ff44;
--code-bg : #0a0a0a;
--card-bg : #1a1a1a;
}
* {
margin : 0;
padding : 0;
box-sizing : border-box;
}
body {
background : var ( --dark-bg) ;
color : var ( --yellow) ;
font-family : 'Consolas' , 'Monaco' , 'Courier New' , monospace;
min-height : 100vh;
overflow : hidden;
background-image :
radial-gradient ( circle at 10% 20%, #1a1a1a 2%, transparent 2%) ,
radial-gradient ( circle at 80% 80%, #1a1a1a 2%, transparent 2%) ,
linear-gradient ( 45deg, transparent 48%, #1a1a1a 49%, #1a1a1a 51%, transparent 52%) ;
background-size : 30px 30px, 40px 40px, 60px 60px;
animation : backgroundShift 20s ease-in-out infinite;
}
@keyframes backgroundShift {
0%, 100% { background-position : 0 0, 0 0, 0 0; }
50% { background-position : 30px 30px, -40px -40px, 60px 60px; }
}
.app-container {
display : flex;
flex-direction : column;
height : 100vh;
}
.main-header {
background : var ( --section-bg) ;
border-bottom : 2px solid var ( --yellow) ;
padding : 15px 30px;
display : flex;
align-items : center;
justify-content : space-between;
min-height : 60px;
z-index : 1000;
}
.logo {
font-size : 2em;
font-weight : bold;
color : var ( --yellow) ;
text-shadow : var ( --glow) ;
display : flex;
align-items : center;
gap : 15px;
}
.logo .subtitle {
font-size : 0.4em;
color : var ( --accent) ;
font-weight : normal;
text-shadow : none;
}
.header-controls {
display : flex;
gap : 15px;
align-items : center;
}
.toggle-btn {
background : var ( --yellow) ;
color : var ( --dark-bg) ;
border : none;
padding : 12px 20px;
border-radius : 25px;
cursor : pointer;
font-weight : bold;
font-size : 14px;
transition : all 0.3s ease;
text-transform : uppercase;
letter-spacing : 1px;
position : relative;
}
.toggle-btn:hover {
transform : translateY ( -2px) ;
box-shadow : var ( --glow) ;
}
.toggle-btn.active {
background : var ( --accent) ;
box-shadow : var ( --glow-strong) ;
}
.content-area {
flex : 1;
display : flex;
overflow : hidden;
padding : 15px;
gap : 15px;
}
.dashboard-view {
flex : 1;
display : flex;
flex-direction : column;
height : 100%;
}
.search-bar {
background : var ( --section-bg) ;
border : 2px solid var ( --yellow) ;
border-radius : 8px;
padding : 15px;
margin-bottom : 20px;
display : flex;
gap : 15px;
}
.search-input {
flex : 1;
padding : 12px;
background : var ( --code-bg) ;
border : 2px solid var ( --accent) ;
border-radius : 8px;
color : var ( --accent) ;
font-family : inherit;
font-size : 14px;
}
.webapps-grid {
display : grid;
grid-template-columns : repeat ( auto-fill, minmax ( 320px, 1fr) ) ;
gap : 25px;
overflow-y : auto;
padding : 10px;
flex : 1;
}
.webapp-card {
background : var ( --card-bg) ;
border : 2px solid var ( --yellow) ;
border-radius : 12px;
padding : 25px;
transition : all 0.3s ease;
cursor : pointer;
height : fit-content;
}
.webapp-card:hover {
transform : translateY ( -5px) ;
box-shadow : var ( --glow-strong) ;
}
.webapp-card h3 {
color : var ( --accent) ;
margin-bottom : 12px;
font-size : 1.3em;
}
.webapp-card p {
color : #ccc;
font-size : 0.95em;
margin-bottom : 18px;
min-height : 70px;
line-height : 1.5;
}
.webapp-card .category {
background : var ( --yellow) ;
color : var ( --dark-bg) ;
padding : 6px 12px;
border-radius : 20px;
font-size : 0.85em;
display : inline-block;
margin-bottom : 12px;
}
.webapp-card .date {
font-size : 0.75em;
color : #888;
}
.window-container {
display : flex;
flex : 1;
gap : 15px;
height : calc ( 100vh - 120px) ;
}
.stretchy-window {
background : var ( --window-bg) ;
border : 2px solid var ( --yellow) ;
border-radius : 12px;
display : flex;
flex-direction : column;
min-width : 300px;
resize : both;
overflow : hidden;
transition : all 0.3s ease;
}
.stretchy-window.collapsed {
width : 0 !important ;
min-width : 0;
border : none;
opacity : 0;
padding : 0;
}
.window-header {
background : var ( --section-bg) ;
padding : 15px 20px;
border-bottom : 2px solid var ( --yellow) ;
display : flex;
justify-content : space-between;
align-items : center;
font-weight : bold;
font-size : 16px;
cursor : move;
min-height : 50px;
}
.window-controls {
display : flex;
gap : 10px;
}
.window-btn {
background : none;
border : 1px solid var ( --yellow) ;
color : var ( --yellow) ;
padding : 5px 10px;
border-radius : 6px;
cursor : pointer;
font-size : 12px;
transition : all 0.3s ease;
}
.window-btn:hover {
background : var ( --yellow) ;
color : var ( --dark-bg) ;
}
.window-content {
flex : 1;
padding : 20px;
overflow-y : auto;
scrollbar-width : thin;
scrollbar-color : var ( --yellow) var ( --dark-bg) ;
}
.window-content::-webkit-scrollbar {
width : 8px;
}
.window-content::-webkit-scrollbar-track {
background : var ( --dark-bg) ;
}
.window-content::-webkit-scrollbar-thumb {
background : var ( --yellow) ;
border-radius : 4px;
}
.editor-panel {
flex : 1;
min-width : 400px;
}
.preview-panel {
flex : 1;
min-width : 400px;
}
.form-field {
margin : 18px 0;
}
.form-field label {
display : block;
color : var ( --yellow) ;
font-weight : bold;
margin-bottom : 10px;
font-size : 14px;
text-transform : uppercase;
}
.form-field input,
.form-field textarea,
.form-field select {
width : 100%;
padding : 12px;
background : var ( --code-bg) ;
border : 2px solid var ( --yellow) ;
border-radius : 8px;
color : var ( --yellow) ;
font-family : inherit;
font-size : 14px;
box-sizing : border-box;
}
.form-field input:focus,
.form-field textarea:focus,
.form-field select:focus {
outline : none;
box-shadow : var ( --glow) ;
}
.code-editor {
width : 100%;
height : 300px;
background : var ( --code-bg) ;
border : 2px solid var ( --yellow) ;
border-radius : 8px;
padding : 15px;
color : var ( --yellow) ;
font-family : 'Consolas' , 'Monaco' , 'Courier New' , monospace;
font-size : 14px;
line-height : 1.5;
resize : vertical;
overflow : auto;
white-space : pre;
tab-size : 2;
}
.preview-frame {
width : 100%;
height : 400px;
background : white;
border : 2px solid var ( --accent) ;
border-radius : 8px;
}
.btn {
background : var ( --yellow) ;
color : var ( --dark-bg) ;
border : none;
padding : 12px 20px;
border-radius : 25px;
cursor : pointer;
font-weight : bold;
font-size : 14px;
transition : all 0.3s ease;
text-transform : uppercase;
letter-spacing : 1px;
}
.btn:hover {
transform : translateY ( -2px) ;
box-shadow : var ( --glow) ;
}
.btn.accent {
background : var ( --accent) ;
}
.btn.danger {
background : var ( --danger) ;
color : #ffffff;
}
.btn.success {
background : var ( --success) ;
}
.btn.small {
padding : 8px 15px;
font-size : 12px;
}
.action-buttons {
display : flex;
gap : 12px;
margin : 25px 0;
flex-wrap : wrap;
}
.tab-container {
display : flex;
gap : 10px;
margin-bottom : 20px;
}
.tab-btn {
background : var ( --section-bg) ;
color : var ( --yellow) ;
border : 2px solid var ( --yellow) ;
padding : 10px 20px;
border-radius : 25px;
cursor : pointer;
font-weight : bold;
transition : all 0.3s ease;
}
.tab-btn.active {
background : var ( --yellow) ;
color : var ( --dark-bg) ;
}
.tab-content {
display : none;
}
.tab-content.active {
display : block;
}
.notification {
position : fixed;
top : 30px;
right : 30px;
background : var ( --yellow) ;
color : var ( --dark-bg) ;
padding : 20px 30px;
border-radius : 12px;
font-weight : bold;
z-index : 10000;
box-shadow : var ( --glow-strong) ;
transform : translateX ( 400px) ;
transition : transform 0.3s ease;
font-size : 16px;
max-width : 400px;
}
.notification.show {
transform : translateX ( 0) ;
}
.notification.error {
background : var ( --danger) ;
color : #ffffff;
}
.notification.success {
background : var ( --success) ;
color : var ( --dark-bg) ;
}
.modal {
display : none;
position : fixed;
top : 0;
left : 0;
right : 0;
bottom : 0;
background : rgba ( 0, 0, 0, 0.9) ;
z-index : 10000;
overflow-y : auto;
}
.modal-content {
max-width : 900px;
margin : 30px auto;
background : var ( --window-bg) ;
border : 3px solid var ( --yellow) ;
border-radius : 20px;
padding : 30px;
}
.modal-header {
display : flex;
justify-content : space-between;
align-items : center;
margin-bottom : 30px;
}
.modal-header h2 {
color : var ( --yellow) ;
margin : 0;
}
.admin-panel {
background : var ( --section-bg) ;
border : 2px solid var ( --danger) ;
border-radius : 12px;
padding : 25px;
margin-bottom : 25px;
}
.admin-panel h4 {
color : var ( --danger) ;
margin-top : 0;
margin-bottom : 20px;
font-size : 1.3em;
}
@media ( max-width : 1200px) {
.window-container {
flex-direction : column;
}
.stretchy-window {
width : 100% !important ;
height : 400px;
}
}
@media ( max-width : 768px) {
.main-header {
padding : 10px 15px;
flex-direction : column;
gap : 10px;
}
.logo {
font-size : 1.5em;
}
.header-controls {
gap : 10px;
flex-wrap : wrap;
}
.toggle-btn {
padding : 8px 12px;
font-size : 12px;
}
.webapps-grid {
grid-template-columns : 1fr;
}
.content-area {
padding : 10px;
gap : 10px;
}
}
</ style>
</ head>
< body>
< div class = " app-container" >
< div class = " main-header" >
< div class = " logo" >
🎨 ARTEP STUDIO PDP
< div class = " subtitle" > Projects Display Platform</ div>
</ div>
< div class = " header-controls" >
< button class = " toggle-btn active" onclick = " showView ( 'dashboard' ) " > 🏠 DASHBOARD</ button>
< button class = " toggle-btn" onclick = " showView ( 'editor' ) " > ⚡ CREATE APP</ button>
< button class = " toggle-btn" onclick = " adminAccess ( ) " style = " opacity : 0.3; " > 🔐 ADMIN</ button>
</ div>
</ div>
< div class = " content-area" >
< div class = " dashboard-view" id = " dashboard-view" >
< div class = " search-bar" >
< input type = " text" class = " search-input" id = " search-input" placeholder = " Search WebApps..." oninput = " searchWebApps()" >
< button class = " btn accent" onclick = " searchWebApps ( ) " > 🔍 SEARCH</ button>
</ div>
< div class = " webapps-grid" id = " webapps-grid" > </ div>
</ div>
< div class = " dashboard-view collapsed" id = " editor-view" >
< div class = " window-container" >
< div class = " stretchy-window editor-panel" >
< div class = " window-header" >
< span> ⚡ Create New WebApp</ span>
< div class = " window-controls" >
< button class = " window-btn" onclick = " clearEditor ( ) " > 🗑️</ button>
< button class = " window-btn" onclick = " showView ( 'dashboard' ) " > ✖️</ button>
</ div>
</ div>
< div class = " window-content" >
< div class = " form-field" >
< label> WebApp Title:</ label>
< input type = " text" id = " app-title" placeholder = " Enter title" oninput = " autoSave()" >
</ div>
< div class = " form-field" >
< label> Category:</ label>
< select id = " app-category" oninput = " autoSave()" >
< option value = " landing-page" > Landing Page</ option>
< option value = " dashboard" > Dashboard</ option>
< option value = " ecommerce" > E-commerce</ option>
< option value = " portfolio" > Portfolio</ option>
< option value = " game" > Game</ option>
< option value = " utility" > Utility</ option>
< option value = " other" > Other</ option>
</ select>
</ div>
< div class = " form-field" >
< label> Description:</ label>
< textarea id = " app-description" rows = " 3" placeholder = " Description" oninput = " autoSave()" > </ textarea>
</ div>
< div class = " tab-container" >
< button class = " tab-btn active" onclick = " switchTab ( 'code' ) " > 💻 Code</ button>
< button class = " tab-btn" onclick = " switchTab ( 'embed' ) " > 🔗 Embed</ button>
< button class = " tab-btn" onclick = " switchTab ( 'canva' ) " > 🎨 Canva</ button>
</ div>
< div id = " code-tab" class = " tab-content active" >
< div class = " form-field" >
< label> Code:</ label>
< textarea class = " code-editor" id = " code-editor" oninput = " autoSave()" > </ textarea>
</ div>
</ div>
< div id = " embed-tab" class = " tab-content" >
< div class = " form-field" >
< label> URL:</ label>
< input type = " url" id = " embed-url" oninput = " autoSave()" >
</ div>
< div class = " form-field" >
< label> Height:</ label>
< input type = " number" id = " embed-height" value = " 600" oninput = " autoSave()" >
</ div>
</ div>
< div id = " canva-tab" class = " tab-content" >
< div class = " form-field" >
< label> Canva URL:</ label>
< input type = " url" id = " canva-url" oninput = " autoSave()" >
</ div>
< div class = " form-field" >
< label> Height:</ label>
< input type = " number" id = " canva-height" value = " 800" oninput = " autoSave()" >
</ div>
</ div>
< div class = " action-buttons" >
< button class = " btn success" onclick = " saveWebApp ( ) " > 💾 Save</ button>
< button class = " btn accent" onclick = " previewContent ( ) " > 👁️ Preview</ button>
< button class = " btn" onclick = " loadTemplate ( ) " > 📄 Template</ button>
</ div>
</ div>
</ div>
< div class = " stretchy-window preview-panel collapsed" id = " preview-panel" >
< div class = " window-header" >
< span> 🖥️ Preview</ span>
< div class = " window-controls" >
< button class = " window-btn" onclick = " togglePreview ( ) " > 👁️</ button>
< button class = " window-btn" onclick = " showView ( 'dashboard' ) " > ✖️</ button>
</ div>
</ div>
< div class = " window-content" >
< iframe class = " preview-frame" id = " preview-frame" sandbox = " allow-scripts allow-same-origin allow-forms allow-popups" > </ iframe>
</ div>
</ div>
</ div>
</ div>
</ div>
</ div>
< div class = " modal" id = " admin-modal" >
< div class = " modal-content" >
< div class = " modal-header" >
< h2> 🔐 Admin Panel</ h2>
< button class = " btn danger" onclick = " closeAdmin ( ) " > ✖️ Close</ button>
</ div>
< div class = " admin-panel" >
< h4> Settings</ h4>
< div class = " form-field" >
< label> Password:</ label>
< input type = " password" id = " admin-password" >
</ div>
< div class = " form-field" >
< label> Title:</ label>
< input type = " text" id = " platform-title" value = " ARTEP STUDIO PDP" >
</ div>
< div class = " form-field" >
< label> Subtitle:</ label>
< input type = " text" id = " platform-subtitle" value = " Projects Display Platform" >
</ div>
< div style = " display : flex; gap : 15px; margin-top : 20px; " >
< button class = " btn success" onclick = " saveAdminSettings ( ) " > 💾 Save</ button>
< button class = " btn" onclick = " exportData ( ) " > 📤 Export</ button>
< button class = " btn danger" onclick = " clearAllData ( ) " > 🗑️ Clear</ button>
</ div>
</ div>
< div class = " admin-panel" >
< h4> Dev Notes</ h4>
< textarea id = " dev-notes" rows = " 8" > </ textarea>
< button class = " btn success" style = " margin-top : 20px; " onclick = " saveDevNotes ( ) " > 💾 Save Notes</ button>
</ div>
</ div>
</ div>
< div class = " modal" id = " view-modal" >
< div class = " modal-content" >
< div class = " modal-header" >
< h2 id = " view-app-title" > Preview</ h2>
< button class = " btn danger" onclick = " closeViewModal ( ) " > ✖️ Close</ button>
</ div>
< div class = " window-content" >
< iframe class = " preview-frame" id = " view-frame" style = " height : 70vh; " > </ iframe>
< div style = " margin-top : 20px; text-align : center; " >
< p> URL: < span id = " app-url" style = " color : var ( --accent) ; " > </ span> </ p>
</ div>
</ div>
</ div>
</ div>
< script>
let webApps = JSON . parse ( localStorage. getItem ( 'artepWebApps' ) ) || [ ] ;
let adminSettings = JSON . parse ( localStorage. getItem ( 'artepAdminSettings' ) ) || {
title : 'ARTEP STUDIO PDP' ,
subtitle : 'Projects Display Platform' ,
devNotes : ''
} ;
let autoSaveTimeout;
document. addEventListener ( 'DOMContentLoaded' , ( ) => {
updatePlatformTitle ( ) ;
loadWebApps ( ) ;
loadAutoSave ( ) ;
} ) ;
function showView ( view ) {
const dashboardView = document. getElementById ( 'dashboard-view' ) ;
const editorView = document. getElementById ( 'editor-view' ) ;
const buttons = document. querySelectorAll ( '.toggle-btn' ) ;
buttons. forEach ( btn => btn. classList. remove ( 'active' ) ) ;
if ( view === 'dashboard' ) {
dashboardView. classList. remove ( 'collapsed' ) ;
editorView. classList. add ( 'collapsed' ) ;
buttons[ 0 ] . classList. add ( 'active' ) ;
loadWebApps ( ) ;
} else {
dashboardView. classList. add ( 'collapsed' ) ;
editorView. classList. remove ( 'collapsed' ) ;
buttons[ 1 ] . classList. add ( 'active' ) ;
}
}
function switchTab ( tabName ) {
document. querySelectorAll ( '.tab-btn, .tab-content' ) . forEach ( el => el. classList. remove ( 'active' ) ) ;
event. target. classList. add ( 'active' ) ;
document. getElementById ( ` ${tabName}-tab`).classList.add('active');
}
function updatePlatformTitle() {
document.querySelector('.logo').innerHTML = `🎨 ${adminSettings.title}<div class="subtitle">${adminSettings.subtitle}
Created: ${new Date(app.date).toLocaleDateString()}</div> </div>
` ) . join ( '' ) ; } function autoSave ( ) { clearTimeout ( autoSaveTimeout
) ; autoSaveTimeout
= setTimeout ( ( ) => { localStorage
. setItem ( 'editorState' , JSON . stringify ( { title : document
. getElementById ( 'app-title' ) . value
, category : document
. getElementById ( 'app-category' ) . value
, description : document
. getElementById ( 'app-description' ) . value
, code : document
. getElementById ( 'code-editor' ) . value
, embedUrl : document
. getElementById ( 'embed-url' ) . value
, embedHeight : document
. getElementById ( 'embed-height' ) . value
, canvaUrl : document
. getElementById ( 'canva-url' ) . value
, canvaHeight : document
. getElementById ( 'canva-height' ) . value
} ) ) ; } , 500 ) ; } function loadAutoSave ( ) { const saved
= JSON . parse ( localStorage
. getItem ( 'editorState' ) ) ; if ( saved
) { document
. getElementById ( 'app-title' ) . value
= saved
. title
|| '' ; document
. getElementById ( 'app-category' ) . value
= saved
. category
|| 'landing-page' ; document
. getElementById ( 'app-description' ) . value
= saved
. description
|| '' ; document
. getElementById ( 'code-editor' ) . value
= saved
. code
|| '' ; document
. getElementById ( 'embed-url' ) . value
= saved
. embedUrl
|| '' ; document
. getElementById ( 'embed-height' ) . value
= saved
. embedHeight
|| 600 ; document
. getElementById ( 'canva-url' ) . value
= saved
. canvaUrl
|| '' ; document
. getElementById ( 'canva-height' ) . value
= saved
. canvaHeight
|| 800 ; } } function previewContent ( ) { const previewPanel
= document
. getElementById ( 'preview-panel' ) ; previewPanel
. classList
. remove ( 'collapsed' ) ; const iframe
= document
. getElementById ( 'preview-frame' ) ; let content
= '' ; if ( document
. querySelector ( '.tab-btn.active' ) . textContent
. includes ( 'Code' ) ) { content
= document
. getElementById ( 'code-editor' ) . value
; } else if ( document
. querySelector ( '.tab-btn.active' ) . textContent
. includes ( 'Embed' ) ) { const url
= document
. getElementById ( 'embed-url' ) . value
; const height
= document
. getElementById ( 'embed-height' ) . value
|| 600 ; content
= ` <iframe src="${url}" style="width:100%;height:${height}px;border:none;"></iframe> ` ; } else { const url
= document
. getElementById ( 'canva-url' ) . value
; const height
= document
. getElementById ( 'canva-height' ) . value
|| 800 ; content
= ` <iframe src="${url}" style="width:100%;height:${height}px;border:none;"></iframe> ` ; } iframe
. srcdoc
= content
; } function saveWebApp ( ) { const title
= document
. getElementById ( 'app-title' ) . value
; if ( ! title
) { showNotification ( 'Please enter a title' , 'error' ) ; return ; } const newApp
= { id : Date
. now ( ) . toString ( ) , title : title
, category : document
. getElementById ( 'app-category' ) . value
, description : document
. getElementById ( 'app-description' ) . value
, code : document
. getElementById ( 'code-editor' ) . value
, embedUrl : document
. getElementById ( 'embed-url' ) . value
, embedHeight : document
. getElementById ( 'embed-height' ) . value
, canvaUrl : document
. getElementById ( 'canva-url' ) . value
, canvaHeight : document
. getElementById ( 'canva-height' ) . value
, date : new Date ( ) . toISOString ( ) } ; webApps
. push ( newApp
) ; localStorage
. setItem ( 'artepWebApps' , JSON . stringify ( webApps
) ) ; showNotification ( 'WebApp saved!' , 'success' ) ; localStorage
. removeItem ( 'editorState' ) ; clearEditor ( ) ; showView ( 'dashboard' ) ; } function viewWebApp ( id ) { const app
= webApps
. find ( a => a
. id
=== id
) ; if ( ! app
) return ; const iframe
= document
. getElementById ( 'view-frame' ) ; let content
= '' ; if ( app
. code
) { content
= app
. code
; } else if ( app
. embedUrl
) { content
= ` <iframe src="${app.embedUrl}" style="width:100%;height:${app.embedHeight || 600}px;border:none;"></iframe> ` ; } else if ( app
. canvaUrl
) { content
= ` <iframe src="${app.canvaUrl}" style="width:100%;height:${app.canvaHeight || 800}px;border:none;"></iframe> ` ; } iframe
. srcdoc
= content
; document
. getElementById ( 'view-app-title' ) . textContent
= app
. title
; document
. getElementById ( 'app-url' ) . textContent
= ` ${window.location.href}#${id} ` ; document
. getElementById ( 'view-modal' ) . style
. display
= 'block' ; } function adminAccess ( ) { document
. getElementById ( 'admin-modal' ) . style
. display
= 'block' ; } function closeAdmin ( ) { document
. getElementById ( 'admin-modal' ) . style
. display
= 'none' ; } function saveAdminSettings ( ) { const password
= document
. getElementById ( 'admin-password' ) . value
; if ( password
!== '7203' ) { showNotification ( 'Invalid password' , 'error' ) ; return ; } adminSettings
. title
= document
. getElementById ( 'platform-title' ) . value
; adminSettings
. subtitle
= document
. getElementById ( 'platform-subtitle' ) . value
; localStorage
. setItem ( 'artepAdminSettings' , JSON . stringify ( adminSettings
) ) ; updatePlatformTitle ( ) ; showNotification ( 'Settings saved!' , 'success' ) ; } function showNotification ( text
, type
= '' ) { document
. querySelectorAll ( '.notification' ) . forEach ( n => n
. remove ( ) ) ; const notification
= document
. createElement ( 'div' ) ; notification
. className
= ` notification ${type} show`; notification.textContent = text; document.body.appendChild(notification); setTimeout(() => { notification.classList.remove('show'); setTimeout(() => notification.remove(), 300); }, 3000); } function clearEditor() { document.getElementById('app-title').value = ''; document.getElementById('app-category').value = 'landing-page'; document.getElementById('app-description').value = ''; document.getElementById('code-editor').value = ''; document.getElementById('embed-url').value = ''; document.getElementById('embed-height').value = '600'; document.getElementById('canva-url').value = ''; document.getElementById('canva-height').value = '800'; localStorage.removeItem('editorState'); } function loadTemplate() { document.getElementById('code-editor').value = `
Welcome to My WebApp
This is a sample WebApp created with ARTEP STUDIO PDP
Click Me
`; autoSave(); showNotification('Template loaded!', 'success'); } function closeViewModal() { document.getElementById('view-modal').style.display = 'none'; } function exportData() { const password = document.getElementById('admin-password').value; if(password !== '7203') { showNotification('Invalid password', 'error'); return; } const data = { webApps: webApps, settings: adminSettings }; const blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `artep-backup-${new Date().toISOString().split('T')[0]}.json ` ; document. body. appendChild ( a) ; a. click ( ) ; document. body. removeChild ( a) ; showNotification ( 'Data exported!' , 'success' ) ; } function clearAllData ( ) { const password = document. getElementById ( 'admin-password' ) . value; if ( password !== '7203' ) { showNotification ( 'Invalid password' , 'error' ) ; return ; } if ( confirm ( 'Clear ALL data?' ) ) { localStorage. clear ( ) ; webApps = [ ] ; adminSettings = { title : 'ARTEP STUDIO PDP' , subtitle : 'Projects Display Platform' } ; location. reload ( ) ; } } function saveDevNotes ( ) { const password = document. getElementById ( 'admin-password' ) . value; if ( password !== '7203' ) { showNotification ( 'Invalid password' , 'error' ) ; return ; } adminSettings. devNotes = document. getElementById ( 'dev-notes' ) . value; localStorage. setItem ( 'artepAdminSettings' , JSON . stringify ( adminSettings) ) ; showNotification ( 'Notes saved!' , 'success' ) ; } function searchWebApps ( ) { const searchTerm = document. getElementById ( 'search-input' ) . value. toLowerCase ( ) ; const filtered = webApps. filter ( app => app. title. toLowerCase ( ) . includes ( searchTerm) || app. category. toLowerCase ( ) . includes ( searchTerm) || ( app. description && app. description. toLowerCase ( ) . includes ( searchTerm) ) ) ; const grid = document. getElementById ( 'webapps-grid' ) ; if ( filtered. length === 0 ) { grid. innerHTML = '<div class="webapp-card" style="text-align: center; grid-column: 1 / -1;">No WebApps found</div>' ; return ; } grid. innerHTML = filtered. map ( app => ` <div class="webapp-card" onclick="viewWebApp('${app.id}')">
${app.category}</div> <h3>${app.title}