work on adding editor

This commit is contained in:
Tuomas Katajisto 2025-11-30 21:33:22 +02:00
parent 62e1efc3b5
commit c1340c42dc
4 changed files with 149 additions and 6 deletions

View File

@ -6,11 +6,10 @@ add_navbar :: (builder: *String_Builder) {
navbar : string = #string DONE navbar : string = #string DONE
<nav> <nav>
<div class="brand">%</div> <div class="brand"><a href="/">%</a></div>
<div class="nav-actions"> <div class="nav-actions">
<a href="index.html" class="active">Collection</a> <a href="/" class="active">Collection</a>
<a href="cookbook.html">Cookbooks</a> <a href="/editor">Editor</a>
<a href="atelier.html">Atelier</a>
</div> </div>
</nav> </nav>
DONE DONE

94
pages/editor.jai Normal file
View File

@ -0,0 +1,94 @@
get_editor_page :: (req: Request) -> string {
builder : String_Builder;
print_to_builder(*builder, start)
}
start : string = #string DONE
<form hx-post="/api/recipe/save" hx-trigger="submit">
<nav>
<div class="brand">OMAKASE <span class="mono" style="margin-left: 10px; color: var(--gold);">// EDITOR</span></div>
<div>
<a href="recipe.html" style="margin-right: 20px; color: var(--grey); text-decoration: none;">DELETE</a>
<!-- This button submits the form via HTMX -->
<button type="submit" class="save-btn">SAVE ASSET</button>
</div>
</nav>
DONE
page : string = #string DONE
<div class="editor-container">
<div style="grid-column: 1 / -1;">
<div class="drop-zone">
<span style="font-size: 2rem;">+</span>
<span class="mono">DRAG HERO IMAGE HERE</span>
<!-- Hidden file input would go here -->
</div>
<input type="text" name="title" class="input-title" value="Bavette Steak w/ Chimichurri" placeholder="Recipe Title">
<div class="mono">UUID: 8f92-29a1-....</div>
</div>
<div>
<div class="mono" style="margin-bottom: 1rem; border-bottom: 2px solid var(--ink);">Complications</div>
<div style="display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid #eee; align-items: center;">
<span style="color: red; cursor: pointer;">&times;</span>
<input type="text" name="comp_1_name" class="input-comp" value="Grass-fed Bavette">
<input type="text" name="comp_1_qty" class="mono" value="600g" style="width: 60px; text-align: right;">
</div>
<!-- ... existing items ... -->
<!-- Triggers the drawer (Client Side) -->
<button type="button" class="add-btn" onclick="openDrawer()">+ Add Component</button>
</div>
<div>
<div class="mono" style="margin-bottom: 1rem; border-bottom: 2px solid var(--ink);">Execution</div>
<div style="display: flex; gap: 1rem; margin-bottom: 2rem;">
<div class="mono" style="font-size: 1.5rem; color: var(--gold);">01</div>
<textarea name="step_1" class="input-step" rows="3">Remove Bavette from fridge 45 mins prior. Salt heavily.</textarea>
</div>
<!-- ... existing items ... -->
<button type="button" class="add-btn">+ Add Step</button>
</div>
</div>
</form>
<!-- COMPONENT DRAWER -->
<div class="overlay" id="overlay" onclick="closeDrawer()"></div>
<div class="drawer" id="drawer">
<h3 style="margin-bottom: 1rem;">Assets <span class="htmx-indicator mono" style="font-size: 0.6rem; color: var(--gold);">SEARCHING...</span></h3>
<!-- HTMX SEARCH INPUT -->
<input type="text"
class="drawer-search"
placeholder="Search atoms..."
name="q"
hx-get="/api/components/search"
hx-trigger="keyup changed delay:500ms"
hx-target="#drawer-results">
<!-- Results container targeted by HTMX -->
<ul id="drawer-results" class="drawer-list">
<!-- Initial state or empty -->
<li class="drawer-item">
<span>Asparagus (Green)</span>
<span class="mono">VEG</span>
</li>
<!-- ... -->
</ul>
<button class="save-btn" style="width: 100%; text-align: center;">Create New Atom</button>
</div>
<script>
function openDrawer() {
document.getElementById('drawer').classList.add('open');
document.getElementById('overlay').classList.add('visible');
}
function closeDrawer() {
document.getElementById('drawer').classList.remove('open');
document.getElementById('overlay').classList.remove('visible');
}
</script>
DONE

View File

@ -4,6 +4,7 @@
#load "pages/index.jai"; #load "pages/index.jai";
#load "pages/recipe.jai"; #load "pages/recipe.jai";
#load "pages/editor.jai";
init_server :: () { init_server :: () {
init_data(); init_data();
@ -13,10 +14,10 @@ handler :: (req: Request, res: *Response) {
if req.route == { if req.route == {
case "/"; case "/";
serve_page(res, get_main_page()); serve_page(res, get_main_page());
return;
case "/recipe"; case "/recipe";
serve_page(res, get_recipe_page(req)); serve_page(res, get_recipe_page(req));
return; case "/editor";
serve_page(res, get_editor_page(req));
case "/style.css"; case "/style.css";
serve_stylesheet(res); serve_stylesheet(res);
} }

View File

@ -124,4 +124,53 @@ nav { padding: 1rem var(--space); display: flex; justify-content: space-between;
.edit-fab { position: fixed; bottom: 2rem; right: 2rem; width: 60px; height: 60px; border-radius: 50%; background: var(--ink); color: var(--gold); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 10px 30px rgba(0,0,0,0.2); transition: transform 0.2s; z-index: 99; } .edit-fab { position: fixed; bottom: 2rem; right: 2rem; width: 60px; height: 60px; border-radius: 50%; background: var(--ink); color: var(--gold); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 10px 30px rgba(0,0,0,0.2); transition: transform 0.2s; z-index: 99; }
.edit-fab:hover { transform: scale(1.1); } .edit-fab:hover { transform: scale(1.1); }
/* --- INPUTS --- */
input[type="text"], textarea {
background: transparent; border: none; border-bottom: 1px dashed var(--gold-dim);
width: 100%; color: var(--ink); font-family: inherit; padding: 0; margin: 0;
resize: none; outline: none;
}
input[type="text"]:focus, textarea:focus { border-bottom: 1px solid var(--gold); background: rgba(197, 160, 89, 0.05); }
.input-title { font-family: 'Playfair Display', serif; font-size: 4.5rem; line-height: 1; margin-bottom: 1rem; }
.input-step { font-size: 1.15rem; font-weight: 300; line-height: 1.6; }
.input-comp { font-weight: 500; font-size: 1.1rem; }
.editor-container { max-width: 1200px; margin: 4rem auto; padding: 0 var(--space); display: grid; grid-template-columns: 1fr 1.5fr; gap: 5rem; }
.drop-zone {
width: 100%; height: 400px; background: #f0f0f0; border: 2px dashed var(--gold-dim);
display: flex; align-items: center; justify-content: center; flex-direction: column;
margin-bottom: 3rem; cursor: pointer; color: #888;
}
.drop-zone:hover { border-color: var(--gold); color: var(--gold); }
.add-btn {
background: transparent; border: 1px solid var(--gold-dim); color: var(--gold);
width: 100%; padding: 0.5rem; margin-top: 1rem; cursor: pointer;
font-family: 'JetBrains Mono', monospace; text-transform: uppercase; font-size: 0.7rem;
}
.add-btn:hover { border-color: var(--gold); }
/* --- DRAWER --- */
.drawer {
position: fixed; top: 0; right: -400px; width: 400px; height: 100vh;
background: #fff; border-left: 1px solid var(--gold); z-index: 200;
padding: 2rem; box-shadow: -10px 0 30px rgba(0,0,0,0.1);
transition: right 0.3s ease; display: flex; flex-direction: column;
}
.drawer.open { right: 0; }
.drawer-search { border: 1px solid var(--ink) !important; padding: 1rem !important; font-size: 1rem; margin-bottom: 2rem; }
.drawer-list { flex: 1; overflow-y: auto; list-style: none; }
.drawer-item { padding: 1rem 0; border-bottom: 1px solid #eee; cursor: pointer; display: flex; justify-content: space-between; }
.drawer-item:hover { color: var(--gold); }
.overlay { position: fixed; top:0; left:0; width:100%; height:100%; background: rgba(0,0,0,0.2); z-index: 150; display: none; }
.overlay.visible { display: block; }
/* HTMX Loading State for Drawer */
.htmx-indicator { opacity: 0; transition: opacity 0.2s; }
.htmx-request .htmx-indicator { opacity: 1; }
DONE DONE