Initial commit for LaunchPad app

This commit is contained in:
2025-09-10 14:56:26 +03:00
commit 655e20a476
10 changed files with 433 additions and 0 deletions

42
templates/app_form.html Normal file
View File

@@ -0,0 +1,42 @@
{% extends "base.html" %}
{% block title %}{{ 'Edit App' if data else 'Add App' }} LaunchPad Admin{% endblock %}
{% block content %}
<h1>{{ 'Edit App' if data else 'Add App' }}</h1>
<form method="post" class="form" enctype="multipart/form-data">
<label>Name
<input type="text" name="name" value="{{ (data.name if data else '') | default('') }}" required />
</label>
<label>Image URL (https) optional if you upload a file
<input type="url" name="image" value="{{ (data.image if data else '') | default('') }}" />
</label>
<label>Or upload image
<input type="file" name="image_file" accept="image/*" />
</label>
{% if data and data.image %}
<div>
<small>Current image:</small><br>
<img src="{{ data.image }}" alt="{{ data.name }}" class="icon" style="width:64px;height:64px;object-fit:cover;border-radius:8px;"/>
</div>
{% endif %}
<label>App URL (https)
<input type="url" name="url" value="{{ (data.url if data else '') | default('') }}" required />
</label>
<label>Priority
<input type="number" name="priority" value="{{ (data.priority if data else 0) | default(0) }}" />
</label>
<label class="checkbox">
<input type="checkbox" name="enabled" {% if not data or data.enabled %}checked{% endif %}/> Enabled
</label>
<div class="form-actions">
<a class="btn" href="{{ url_for('apps_list') }}">Cancel</a>
<button class="btn primary" type="submit">Save</button>
</div>
</form>
{% endblock %}

38
templates/apps_list.html Normal file
View File

@@ -0,0 +1,38 @@
{% extends "base.html" %}
{% block title %}Apps LaunchPad Admin{% endblock %}
{% block content %}
<div class="header-row">
<h1>Apps</h1>
<a class="btn" href="{{ url_for('app_create') }}">+ Add App</a>
</div>
{% if apps %}
<table class="table">
<thead>
<tr>
<th>ID</th><th>Icon</th><th>Name</th><th>URL</th><th>Enabled</th><th>Created</th><th>Actions</th>
</tr>
</thead>
<tbody>
{% for a in apps %}
<tr>
<td>{{ a.id }}</td>
<td>{% if a.image %}<img src="{{ a.image }}" alt="{{ a.name }}" class="icon"/>{% else %}-{% endif %}</td>
<td>{{ a.name }}</td>
<td><a href="{{ a.url }}" target="_blank" rel="noopener">{{ a.url }}</a></td>
<td>{{ 'Yes' if a.enabled else 'No' }}</td>
<td>{{ a.created_at }}</td>
<td class="actions">
<a class="btn small" href="{{ url_for('app_edit', app_id=a.id) }}">Edit</a>
<form method="post" action="{{ url_for('app_delete', app_id=a.id) }}" onsubmit="return confirm('Delete this app?')" style="display:inline-block">
<button class="btn danger small" type="submit">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No apps yet. Click “Add App” to create your first one.</p>
{% endif %}
{% endblock %}

33
templates/base.html Normal file
View File

@@ -0,0 +1,33 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{% block title %}LaunchPad Admin{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<header class="topbar">
<div class="brand">LaunchPad Admin</div>
<nav>
{% if session.get('user') %}
<a href="{{ url_for('apps_list') }}">Home</a>
<a href="{{ url_for('logout') }}">Logout</a>
{% endif %}
</nav>
</header>
<main class="container">
{% with messages = get_flashed_messages(with_categories=True) %}
{% if messages %}
<div class="flash">
{% for cat, msg in messages %}
<div class="flash-item {{ cat }}">{{ msg }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</body>
</html>

14
templates/login.html Normal file
View File

@@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block title %}Login LaunchPad Admin{% endblock %}
{% block content %}
<h1>Login</h1>
<form method="post" class="form">
<label>Username
<input type="text" name="username" required autofocus />
</label>
<label>Password
<input type="password" name="password" required />
</label>
<button type="submit">Login</button>
</form>
{% endblock %}