added transaction log, UX scaffolding

This commit is contained in:
evilchili
2024-02-08 01:14:35 -08:00
parent 2dcaa3fac6
commit da6255a86a
15 changed files with 460 additions and 73 deletions
+112
View File
@@ -0,0 +1,112 @@
body {
width: 100%;
padding: 0;
margin: 0;
}
#content {
margin: 1rem auto;
max-width:1280px;
}
a {
text-decoration: none;
color: #000055;
}
a:visited, a:active {
color: #000055;
}
ul.nav {
background: #e7e7e7;
margin: 0;
padding: 0.5rem;
list-style-type: none;
margin-bottom: 0.5rem;
}
ul.nav li {
display: inline;
text-align: center;
background: #FFF;
padding: 0 0.5rem;
}
#character_sheet {
width:50%;
display: block;
}
#character_sheet .statblock {
width: 100%;
margin-bottom:3rem;
display: grid;
grid-template-columns: auto 250px;
grid-gap: 1rem;
}
#character_sheet .banner {
display: grid;
grid-template-columns: 64px 1fr;
grid-gap: 1rem;
}
#character_sheet .banner #portrait {
width: 64px;
height: 64px;
background: #e7e7e7;
}
#character_sheet h1 {
margin: 0;
}
#character_sheet .sidebar {
min-height: 300px;
}
#character_sheet input,
#character_sheet select,
#character_sheet textarea {
font-weight: bold;
border: 0;
}
.stats .cards {
margin-top: 1rem;
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-auto-rows: auto;
grid-gap: 1rem;
}
.sidebar .cards {
margin-top: 1rem;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-gap: 1rem;
text-align: center;
}
.cards .card {
border: 2px solid #e7e7e7;
border-radius: 4px;
padding: .5rem;
}
.card .label {
text-align: center;
text-transform: uppercase;
}
.card input {
font-size: 1.25em;
text-align: center;
padding: 0;
margin: 0;
}
@@ -0,0 +1,31 @@
function proficiency() {
return parseInt(document.getElementById('proficiency_bonus').innerHTML);
}
function bonus(stat) {
return parseInt(document.getElementById(stat + '_bonus').innerHTML);
}
function setStatBonus(stat) {
var score = document.getElementById(stat).value;
var bonus = Math.floor((score - 10) / 2);
document.getElementById(stat + '_bonus').innerHTML = bonus;
}
function setProficiencyBonus() {
var score = document.getElementById('level').value;
var bonus = Math.ceil(1 + (0.25 * score));
document.getElementById('proficiency_bonus').innerHTML = bonus;
}
function setSpellSaveDC() {
var score = 8 + proficiency() + bonus('wis');
document.getElementById('spell_save_dc').innerHTML = score;
}
(function () {
const stats = ['str', 'dex', 'con', 'int', 'wis', 'cha'];
stats.forEach(setStatBonus);
setProficiencyBonus();
setSpellSaveDC();
})();
View File
+15 -1
View File
@@ -2,12 +2,26 @@
<html lang="en">
<head>
<title>{{ c.config.project_name }}{% block title %}{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="og:provider_name" content="{{ c.config.project_name }}">
<link rel='stylesheet' href="{{c.routes.static}}/styles.css" />
{% for resource in c.resources %}
<link rel='preload' href="{{c.routes.static}}/{{resource['uri']}}" as="{{resource['type']}}"/>
{% if resource['type'] == 'style' %}
<link rel='stylesheet' href="{{c.routes.static}}/{{resource['uri']}}" />
{% endif %}
{% endfor %}
{% block headers %}{% endblock %}
</head>
<body>
<div id='content'>
{% block content %}{% endblock %}
</div>
{% block debug %}{% endblock %}
{% for resource in c.resources %}
{% if resource['type'] == 'script' %}
<script type="text/javascript" src="{{c.routes.static}}/{{resource['uri']}}"></script>
{% endif %}
{% endfor %}
</body>
</html>
+55 -11
View File
@@ -5,27 +5,71 @@
{{ build_list(c) }}
<div style='float:left;'>
<h1>{{ c['record'].name }}</h1>
<div id='character_sheet'>
<form name="character_sheet" method="post" novalidate class="form">
{{ c.form.csrf_token }}
<ul>
<div class='banner'>
<div><img id='portrait' /></div>
<div>
<h1>{{ c.record.name }}</h1>
{{ c.form.ancestry }} {{ c.record.character_class|join(' / ') }} &nbsp; Level {{ c.form.level }}
</div>
</div>
<div class='statblock'>
<div class='stats'>
<div class='cards'>
{% for stat in ['str', 'dex', 'con', 'int', 'wis', 'cha'] %}
<div class='card'>
<div class='label'>{{ c.form[stat].label }}</div>
{{ c.form[stat] }}
<div id='{{stat}}_bonus'></div>
</div>
{% endfor %}
<div class='card'>
<div class='label'>AC</div>
{{ c.form.armor_class }}
</div>
</div>
<ul>
<li>Initiative: <span id='initiative'>3</span></li>
<li>Proficiency Bonus: <span id='proficiency_bonus'></span></li>
<li>Spell Save DC: <span id='spell_save_dc'></span></li>
<li>Saving Throws: <span id='saving_throws'>{{ c.record.saving_throws |join(', ') }}</span></li>
<li>Skills: <span id='skills'>{{ c.record.skills |join(', ') }}</span></li>
{% for field in c.form %}
{% if field.name not in ['save', 'delete'] %}
{% if field.name in ['proficiencies', 'speed', 'passive_perception', 'passive_insight', 'passive_investigation'] %}
<li>{{ field.label }}: {{ field }} {{ field.errors|join(',') }}</li>
{% endif %}
{% endfor %}
</ul>
{{ c.form.save }} &nbsp; {{ c.form.delete }}
</form>
</ul>
</div>
<div class='sidebar'>
<div class='cards'>
<div class='card'>
<div class='label'>HP</div>
{{ c.form.max_hit_points }} / {{ c.form.hit_points }}
</div>
<div class='card'>
<div class='label'>TEMP HP</div>
{{ c.form.temp_hit_points }}
</div>
</div>
</div>
</div>
<hr>
{{ c.form.save }} &nbsp; {{ c.form.delete }}
</div>
{{ c.form.csrf_token }}
</form>
{% endblock %}
{% block debug %}
<div style='clear:both;display:block;'>
<h2>Debug</h2>
<pre>
<code>
{{ c }}
</pre>
</code>
{% endblock %}
+4 -6
View File
@@ -1,10 +1,8 @@
{% macro build_list(c) %}
<div style='float:left; min-height: 90%; margin-right:5em;'>
<ul>
<li><a href="{{ c.routes.sheet }}">Create a Character</a></li>
<ul class='nav'>
<li><a href="{{ c.routes.sheet }}">Create a Character</a></li>
{% for rec in c.all_records %}
<li><a href="{{ c.routes.sheet }}/{{ rec.uri }}">{{ rec.uri }}</a></li>
<li><a href="{{ c.routes.sheet }}/{{ rec.uri }}">{{ rec.name }}</a></li>
{% endfor %}
</ul>
</div>
</ul>
{% endmacro %}