1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

feat-webgarages-121 (#129)

### Description

Closes #121

### Please confirm

- [x] I am the legal owner or represent the legal owner of all work submitted (including LLM-generated code, if any)
- [x] I consent to my changes being added to this FOSS project
- [x] I have confirmed that this does not add new errors or warnings with `utils/clippy.sh`
- [ ] This PR used LLMs to generate some or all of the code changes

Reviewed-on: https://git.ngram.ca/OpenJam/rc-servers/pulls/129
This commit is contained in:
NG (Graham)
2026-06-15 01:02:52 +00:00
committed by NGnius
parent a222745841
commit d2626bb47f
40 changed files with 4012 additions and 282 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -11,144 +11,19 @@
<meta property="og:type" content="website" />
<meta property="og:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="og:title" content="Dashboard - Openjam" />
<meta property="og:description" content="Create an account for third-party Robocraft servers" />
<meta property="og:description" content="View your account for third-party Robocraft servers" />
<meta property="og:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<!-- Twitter -->
<meta property="twitter:card" content="summary" />
<meta property="twitter:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="twitter:title" content="Dashboard - Openjam" />
<meta property="twitter:description" content="Create an account for third-party Robocraft servers" />
<meta property="twitter:description" content="View your account for third-party Robocraft servers" />
<meta property="twitter:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<style>
body {
background-color: lightgrey;
padding: 0;
margin: 0;
}
.form-stripe {
position: relative;
min-width: 300px;
max-width: 90%;
height: auto;
min-height: 100%;
margin: 0 auto;
background-color: grey;
padding: 0 0 25px 0;
box-shadow: 0px 0px 50px 5px grey;
}
.form-header-right {
position: relative;
width: 25%;
text-align: right;
margin: 0 0 0 auto;
box-sizing: border-box;
padding: 0 25px;
}
.form-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: dimgrey;
color: black;
padding: 25px;
}
.form-padded {
padding: 0 25px;
}
h1, h2, h3, h4, h5 {
text-align: center;
}
a { text-decoration-line: none; }
a:link { color: darkgrey; }
a:hover { color: white; }
a:visited { color: lightgrey; }
a:active { color: white; }
form {
padding-top: 25px;
padding-left: 25px;
padding-right: 25px;
padding-bottom: 250px;
}
.form-error {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: orange;
}
.form-error-message {
padding: 25px;
margin: 0 auto;
width: 95%;
}
.form-text-block {
width: 80%;
margin: 0 auto;
}
.access-grid {
width: 80%;
display: grid;
margin: 0 auto;
padding: 5px;
grid-template-columns: auto auto auto auto;
gap: 5px;
}
.access-box {
background-color: dimgrey;
color: black;
padding: 5px 0;
text-align: center;
}
.access-box-title {
padding: 5px;
margin: 0 auto;
}
.access-box-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: black;
color: lightgrey;
padding: 5px;
}
.box-details {
text-align: left;
display: grid;
grid-template-columns: auto auto;
gap: 2px;
padding: 5px;
}
.box-details-key {
padding: 0 5px;
background-color: black;
color: lightgrey;
text-align: left;
}
.box-details-value {
padding: 0 5px;
background-color: lightgrey;
color: black;
text-align: left;
}
footer {
position: relative;
width: 100%
margin: 0 auto;
background-color: black;
}
.footer {
width: 95%;
color: lightgrey;
box-sizing: border-box;
padding: 25px;
}
</style>
{{> stylesheet}}
</head>
<body>
<div class="form-stripe">
@@ -200,7 +75,7 @@
<div class="box-details-key">Total</div> <!-- TODO -->
<div class="box-details-value">{{form.debug.user_id}}/{{form.debug.user_id}}</div>
</div>
<a href="#"> <!-- TODO -->
<a href="/garages/list">
<div class="access-box-banner">
View My Garages
</div>

View File

@@ -0,0 +1,79 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Primary Meta Tags -->
<title>Garages - Openjam</title>
<meta name="title" content="Garage{{#if form.garage}} #{{form.garage.slot}}{{/if}} Import - Openjam" />
<meta name="description" content="User garage import for third-party Robocraft servers" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="og:title" content="Garage Import - Openjam" />
<meta property="og:description" content="Import a vehicle into your garage for third-party Robocraft servers" />
<meta property="og:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<!-- Twitter -->
<meta property="twitter:card" content="summary" />
<meta property="twitter:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="twitter:title" content="Garage Import - Openjam" />
<meta property="twitter:description" content="Import a vehicle into your garages for third-party Robocraft servers" />
<meta property="twitter:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico">
{{> stylesheet}}
</head>
<body>
<div class="form-stripe">
<div class="form-header-right">
Welcome {{form.display_name}}! |
<a href="/">Home</a>
</div>
<h1 class="form-banner">{{form.display_name}} Garage {{#if form.garage}}#{{form.garage.slot}}{{/if}} Import</h1>
{{#if error}}
<div class="form-error">
<p class="form-error-message">{{error}}</p>
</div>
{{/if}}
{{#if form.success}}
<div class="form-success">
<p class="form-success-message">{{form.success}}</p>
</div>
{{/if}}
<form method="post" enctype="multipart/form-data" action="/garages/import">
<div class="access-list">
{{#if form.garage}}
<input type="hidden" id="garage_id" name="garage_id" value="{{form.garage.garage_id}}"/>
{{else}}
<input type="hidden" id="garage_id" name="garage_id" value="-1"/>
{{/if}}
<div class="access-row-box">
<label>Import with</label>
<select id="plugin" name="plugin" required>
{{#each form.importers}}
<option value="{{this}}" {{#if (eq ../form.selected_importer this)}}selected{{/if}}>{{this}}</option>
{{/each}}
</select>
</div>
<div class="access-row-box">
<input type="file" id="files" name="files" required {{#if form.garage}} {{else}}multiple{{/if}} />
</div>
<div class="access-row-box">
<input type="submit" value="{{#if form.garage}}Override garage slot {{form.garage.slot}}{{else}}Import{{/if}}" />
</div>
</div>
</form>
<footer>
<div class="footer">
{{version}}
| <a href="{{source_url}}#readme">About</a>
| <a href="https://liberapay.com/NGram">Support Me</a>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,91 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Primary Meta Tags -->
<title>Garage {{form.garage.slot}} - Openjam</title>
<meta name="title" content="Garages - Openjam" />
<meta name="description" content="User garage slot for third-party Robocraft servers" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="og:title" content="Garage - Openjam" />
<meta property="og:description" content="View a garage for third-party Robocraft servers" />
<meta property="og:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<!-- Twitter -->
<meta property="twitter:card" content="summary" />
<meta property="twitter:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="twitter:title" content="Garages - Openjam" />
<meta property="twitter:description" content="View a garage for third-party Robocraft servers" />
<meta property="twitter:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico">
{{> stylesheet}}
</head>
<body>
<div class="form-stripe">
<div class="form-header-right">
Welcome {{form.display_name}}! |
<a href="/">Home</a>
</div>
<h1 class="form-banner">{{form.display_name}} Garage #{{form.garage.slot}}</h1>
{{#if error}}
<div class="form-error">
<p class="form-error-message">{{error}}</p>
</div>
{{/if}}
<div class="access-list">
<div class="access-row-box">
<div class="access-grid">
<div class="access-box">
<a href="/garages/{{form.garage.garage_id}}/import">
<div class="access-box-banner">
Import
</div>
</a>
</div>
{{#each form.exporters}}
<div class="access-box">
<a href="/garages/{{../form.garage.garage_id}}/export?plugin={{this}}">
<div class="access-box-banner">
Export to <span class="export-plugin">{{this}}</span>
</div>
</a>
</div>
{{/each}}
<div class="access-box">
<a href="/garages/list">
<div class="access-box-banner">
Back to list
</div>
</a>
</div>
</div>
</div>
<div class="access-row-box">
<!--<h4 class="access-box-title">{{form.garage.name}}</h4>-->
<div class="box-details">
<div class="box-details-key">Name</div>
<div class="box-details-value">{{form.garage.name}}</div>
<div class="box-details-key">Slot</div>
<div class="box-details-value">{{form.garage.slot}}</div>
<div class="box-details-key">Database ID</div>
<div class="box-details-value">{{form.garage.garage_id}}</div>
</div>
</div>
</div>
<footer>
<div class="footer">
{{version}}
| <a href="{{source_url}}#readme">About</a>
| <a href="https://liberapay.com/NGram">Support Me</a>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- Primary Meta Tags -->
<title>Garages - Openjam</title>
<meta name="title" content="Garages - Openjam" />
<meta name="description" content="User garages for third-party Robocraft servers" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="og:title" content="Garages - Openjam" />
<meta property="og:description" content="View your garages for third-party Robocraft servers" />
<meta property="og:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<!-- Twitter -->
<meta property="twitter:card" content="summary" />
<meta property="twitter:url" content="https://git.ngram.ca/OpenJam/rc-servers" />
<meta property="twitter:title" content="Garages - Openjam" />
<meta property="twitter:description" content="View your garages for third-party Robocraft servers" />
<meta property="twitter:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico">
{{> stylesheet}}
</head>
<body>
<div class="form-stripe">
<div class="form-header-right">
Welcome {{form.display_name}}! |
<a href="/">Home</a>
</div>
<h1 class="form-banner">{{form.display_name}} Garages</h1>
{{#if error}}
<div class="form-error">
<p class="form-error-message">{{error}}</p>
</div>
{{/if}}
<div class="access-list">
<div class="access-row-box">
<div class="access-grid">
<div class="access-box">
<a href="/garages/import">
<div class="access-box-banner">
Import
</div>
</a>
</div>
<div class="access-box">
<a href="/garages/export">
<div class="access-box-banner">
Export
</div>
</a>
</div>
<div class="access-box">
<a href="/garages/selected">
<div class="access-box-banner">
Currently Selected
</div>
</a>
</div>
<div class="access-box">
<a href="http://127.0.0.1:8012">
<div class="access-box-banner">
Factory
</div>
</a>
</div>
</div>
</div>
{{#each form.garages}}
<div class="access-row-box">
<!--<h4 class="access-box-title">{{this.name}}</h4>-->
<div class="box-details">
<div class="box-details-key">Name</div>
<div class="box-details-value">{{this.name}}</div>
<div class="box-details-key">CPU</div>
<div class="box-details-value">{{this.cpu}}/{{this.max_cpu}}</div>
<div class="box-details-key">Slot</div>
<div class="box-details-value">{{this.slot}}</div>
<div class="box-details-key">Database ID</div>
<div class="box-details-value">{{this.garage_id}}</div>
<div class="box-details-key">Creation</div>
<div class="box-details-value"><time datetime="{{this.creation_time_iso}}">{{this.creation_time_iso}}</time></div>
</div>
<a href="/garages/{{this.garage_id}}/info">
<div class="access-box-banner">
View Details
</div>
</a>
</div>
{{/each}}
</div>
<footer>
<div class="footer">
{{version}}
| <a href="{{source_url}}#readme">About</a>
| <a href="https://liberapay.com/NGram">Support Me</a>
</div>
</footer>
</div>
</body>
</html>

View File

@@ -22,132 +22,7 @@
<meta property="twitter:image" content="https://git.ngram.ca/OpenJam/rc-servers/raw/branch/main/assets/robocraft/favicon.jpg" />
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<style>
body {
background-color: lightgrey;
padding: 0;
margin: 0;
}
.form-stripe {
position: relative;
min-width: 300px;
max-width: 90%;
height: auto;
min-height: 100%;
margin: 0 auto;
background-color: grey;
padding: 0 0 25px 0;
box-shadow: 0px 0px 50px 5px grey;
}
.form-header-right {
position: relative;
width: 25%;
text-align: right;
margin: 0 0 0 auto;
box-sizing: border-box;
padding: 0 25px;
}
.form-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: dimgrey;
color: black;
padding: 25px;
}
.form-padded {
padding: 0 25px;
}
h1, h2, h3, h4, h5 {
text-align: center;
}
a { text-decoration-line: none; }
a:link { color: darkgrey; }
a:hover { color: white; }
a:visited { color: lightgrey; }
a:active { color: white; }
form {
padding-top: 25px;
padding-left: 25px;
padding-right: 25px;
padding-bottom: 250px;
}
.form-error {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: orange;
}
.form-error-message {
padding: 25px;
margin: 0 auto;
width: 95%;
}
.form-text-block {
width: 80%;
margin: 0 auto;
}
.access-grid {
width: 80%;
display: grid;
margin: 0 auto;
padding: 5px;
grid-template-columns: auto auto auto auto;
gap: 5px;
}
.access-box {
background-color: dimgrey;
color: black;
padding: 5px;
text-align: center;
}
.access-box-title {
padding: 5px;
margin: 0 auto;
}
.access-box-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: black;
color: lightgrey;
padding: 5px;
}
.box-details {
text-align: left;
display: grid;
grid-template-columns: auto auto;
gap: 2px;
padding: 5px;
}
.box-details-key {
padding: 0 5px;
background-color: black;
color: lightgrey;
text-align: left;
}
.box-details-value {
padding: 0 5px;
background-color: lightgrey;
color: black;
text-align: left;
}
footer {
position: relative;
width: 100%
margin: 0 auto;
background-color: black;
}
.footer {
width: 95%;
color: lightgrey;
box-sizing: border-box;
padding: 25px;
}
</style>
{{> stylesheet}}
</head>
<body>
<div class="form-stripe">

View File

@@ -0,0 +1,158 @@
<!-- stylesheet.html.hbs start -->
<style>
body {
background-color: lightgrey;
padding: 0;
margin: 0;
}
.form-stripe {
position: relative;
min-width: 300px;
max-width: 90%;
height: auto;
min-height: 100%;
margin: 0 auto;
background-color: grey;
padding: 0 0 25px 0;
box-shadow: 0px 0px 50px 5px grey;
}
.form-header-right {
position: relative;
width: 25%;
text-align: right;
margin: 0 0 0 auto;
box-sizing: border-box;
padding: 0 25px;
}
.form-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: dimgrey;
color: black;
padding: 25px;
}
.form-padded {
padding: 0 25px;
}
h1, h2, h3, h4, h5 {
text-align: center;
}
a { text-decoration-line: none; }
a:link { color: darkgrey; }
a:hover { color: white; }
a:visited { color: lightgrey; }
a:active { color: white; }
form {
padding-top: 25px;
padding-left: 25px;
padding-right: 25px;
padding-bottom: 250px;
}
.form-error {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: orange;
}
.form-error-message {
padding: 25px;
margin: 0 auto;
width: 95%;
}
.form-success {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: chartreuse;
}
.form-success-message {
padding: 25px;
margin: 0 auto;
width: 95%;
}
.form-text-block {
width: 80%;
margin: 0 auto;
}
.access-grid {
width: 80%;
display: grid;
margin: 0 auto;
padding: 5px;
grid-template-columns: auto auto auto auto;
gap: 5px;
}
.access-list {
width: 80%;
display: flex;
padding: 5px;
margin: 0 auto;
flex-direction: column;
gap: 5px;
}
.access-box {
background-color: dimgrey;
color: black;
padding: 5px 0;
text-align: center;
}
.access-row-box {
background-color: dimgrey;
color: black;
padding: 5px 0;
text-align: center;
width: 100%;
}
.access-box-title {
padding: 5px;
margin: 0 auto;
}
.access-box-banner {
position: relative;
width: 100%;
margin: 0 auto;
box-sizing: border-box;
background-color: black;
color: lightgrey;
padding: 5px;
}
.box-details {
text-align: left;
display: grid;
grid-template-columns: auto auto;
gap: 2px;
padding: 5px;
}
.box-details-key {
padding: 0 5px;
background-color: black;
color: lightgrey;
text-align: left;
}
.box-details-value {
padding: 0 5px;
background-color: lightgrey;
color: black;
text-align: left;
}
.export-plugin {
color: white;
}
footer {
position: relative;
width: 100%
margin: 0 auto;
background-color: black;
}
.footer {
width: 95%;
color: lightgrey;
box-sizing: border-box;
padding: 25px;
}
</style>
<!-- stylesheet.html.hbs end -->