1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00
Files
ojrc/assets/templates/rc_factory_web/index.html.hbs
MaxSignal 5fd4acdf62 add factory web frontend (#77)
### Description

This PR adds a web frontend for factory.
Please let me know if you think the directory names or API endpoints should be changed.
For example, I personally think there are better names than rc_factory_api, and there may be better API names than webui...

### Game

Robocraft

### Please confirm

- [x] I am the legal owner or represent the owner of all work submitted
- [x] I consent to my submission being added to this FOSS project
- [x] This PR used LLMs to generate some or all of the code changes

Reviewed-on: https://git.ngram.ca/OpenJam/rc-servers/pulls/77
Reviewed-by: NGnius <ngniusness@gmail.com>
Co-authored-by: MaxSignal <kastera58@gmail.com>
Co-committed-by: MaxSignal <kastera58@gmail.com>
2026-01-17 20:00:14 +00:00

283 lines
6.6 KiB
Handlebars

<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Factory</title>
<link rel="icon" type="image/x-icon" href="/robocraft/favicon">
<style>
:root{
--bg: #1b1b1b;
--top: #3a3a3a;
--panel: #2a2a2a;
--text: #eaeaea;
--muted: #b9b9b9;
--orange: #ff8f2a;
--orange2: #e67600;
--border: #1a1a1a;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}
.topbar{
width: 100%;
background: var(--top);
border-bottom: 1px solid #2b2b2b;
padding: 12px 8px;
}
.controls{
max-width: none;
width: 100%;
margin: 0;
display: flex;
justify-content: flex-end;
}
.content{
max-width: none;
width: 100%;
margin: 0;
padding: 24px 8px 8px;
}
.stack{
display: grid;
gap: 10px;
min-width: min(720px, 100%);
}
.row{
display: flex;
gap: 10px;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
}
.search{
width: min(420px, 60vw);
padding: 10px 14px;
border-radius: 0;
border: 1px solid #000;
background: linear-gradient(#0f0f0f, #000);
color: var(--text);
outline: none;
font-size: 16px;
}
.search::placeholder{ color: #9a9a9a; }
select{
padding: 9px 34px 9px 12px;
border-radius: 0;
border: 1px solid #000;
background: linear-gradient(#1a1a1a, #000);
color: var(--text);
font-size: 14px;
outline: none;
}
.btn{
padding: 10px 16px;
border-radius: 0;
border: 0;
background: #444;
color: var(--text);
cursor: pointer;
font-weight: 700;
letter-spacing: .02em;
text-transform: uppercase;
}
.btn.primary{ background: var(--orange); }
.btn.primary:hover{ background: var(--orange2); }
.btn:disabled{ opacity: .45; cursor: not-allowed; }
.pager{
display: flex;
justify-content: center;
gap: 6px;
margin: 30px 0;
}
.pager .btn{
width: 110px;
height: 48px;
background: var(--orange);
}
.pager .btn:hover{ background: var(--orange2); }
.pager .btn:disabled{ background: #5a3a1f; opacity: .7; }
.status{
text-align: center;
color: var(--muted);
margin-top: 6px;
font-size: 13px;
min-height: 18px;
}
.grid{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 12px;
margin-top: 16px;
}
.card{
background: var(--panel);
border: 1px solid var(--border);
border-radius: 0;
padding: 10px;
}
.thumb{
width: 100%;
aspect-ratio: 216 / 116;
object-fit: cover;
background: #101010;
border-radius: 0;
display: block;
}
.muted{ color: var(--muted); font-size: 12px; }
.card button{
margin-top: 10px;
width: 100%;
background: #4a4a4a;
border-radius: 0;
text-transform: none;
letter-spacing: 0;
}
.card button:hover{ background: #5a5a5a; }
dialog{
width: min(980px, 92vw);
border: 1px solid #111;
border-radius: 0;
background: #111;
color: var(--text);
padding: 0;
}
dialog::backdrop{ background: rgba(0,0,0,.65); }
.dlg-head{
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
border-bottom: 1px solid #222;
background: #141414;
}
.dlg-title{
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 70vw;
}
.dlg-body{ padding: 12px 14px; }
pre{
margin: 0;
white-space: pre-wrap;
word-break: break-word;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
font-size: 12px;
color: #d9d9d9;
}
footer{
margin-top: 8px;
padding: 14px 8px;
border-top: 1px solid #222;
background: #141414;
}
.footer{
text-align: center;
color: var(--muted);
font-size: 12px;
line-height: 1.6;
}
.footer a{
color: var(--text);
text-decoration: none;
}
.footer a:hover{
text-decoration: underline;
}
</style>
</head>
<body>
<div class="topbar">
<div class="controls">
<div class="stack">
<div class="row">
<input id="q" class="search" type="text" placeholder="Search..." />
<select id="searchField">
<option value="0">ALL</option>
<option value="1">PLAYER</option>
<option value="2">NAME</option>
</select>
<button id="btnSearch" class="btn primary">Search</button>
</div>
<div class="row">
<select id="order">
<option value="0">SUGGESTED</option>
<option value="1">COMBAT RATING</option>
<option value="2">COSMETIC RATING</option>
<option value="3">ADDED DATE</option>
<option value="4">MOST BOUGHT</option>
</select>
<select id="tier">
<option value="">ANY TIERS</option>
<option value="1">TIER 1</option>
<option value="2">TIER 2</option>
<option value="3">TIER 3</option>
<option value="4">TIER 4</option>
<option value="5">TIER 5</option>
<option value="M">TIER M</option>
</select>
</div>
</div>
</div>
</div>
<div class="content">
<div class="pager">
<button id="btnPrevTop" class="btn" disabled>PREV</button>
<button id="btnNextTop" class="btn">NEXT</button>
</div>
<div id="status" class="status"></div>
<div id="grid" class="grid"></div>
<div class="pager">
<button id="btnPrevBottom" class="btn" disabled>PREV</button>
<button id="btnNextBottom" class="btn">NEXT</button>
</div>
</div>
<dialog id="dlg">
<div class="dlg-head">
<div id="dlgTitle" class="dlg-title"></div>
<button id="dlgClose" class="btn">Close</button>
</div>
<div class="dlg-body">
<pre id="detail"></pre>
</div>
</dialog>
<script src="/app.js"></script>
<footer>
<div class="footer">
{{version}}
| <a href="{{source_url}}#readme">About</a>
| <a href="https://liberapay.com/NGram">Support Me</a>
</div>
</footer>
</body>
</html>