Integrate session note and tag editing and center progress controls
This commit is contained in:
+2
-2
@@ -15,10 +15,10 @@
|
||||
<link href="/static/css/tailwind.css" rel="stylesheet">
|
||||
|
||||
<link href="/static/css/style.css" rel="stylesheet">
|
||||
<link href="/static/css/workout.css?v=1" rel="stylesheet">
|
||||
<link href="/static/css/workout.css?v=2" rel="stylesheet">
|
||||
<script src="/static/js/htmx.min.js" defer></script>
|
||||
<script src="/static/js/hyperscript.min.js" defer></script>
|
||||
<link rel="stylesheet" href="/static/css/forecast.css?v=2">
|
||||
<link rel="stylesheet" href="/static/css/forecast.css?v=3">
|
||||
<script src="/static/js/forecast.js?v=2" defer></script>
|
||||
</head>
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<div class="progress-heading">
|
||||
<div class="progress-title">
|
||||
<h4>{{ title }}</h4>
|
||||
<div hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=latest_workout_id, topset_id=latest_topset_id) }}"
|
||||
hx-trigger="load" hx-target="this" hx-swap="innerHTML"></div>
|
||||
</div>
|
||||
<button class="progress-action" title="Show Progress Graph"
|
||||
hx-get="{{ url_for('get_exercise_progress_for_user', person_id=person_id, exercise_id=exercise_id, epoch=selected_epoch, forecast='true' if forecast_enabled else 'false', forecast_weeks=forecast_weeks, forecast_reps=forecast_target_reps, min_date=min_date, max_date=max_date) }}"
|
||||
hx-target="#exercise-history-container" hx-swap="outerHTML">Graph</button>
|
||||
</div>
|
||||
<div class="progress-badges" aria-label="Progress achievements" hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=latest_workout_id, topset_id=latest_topset_id) }}"
|
||||
hx-trigger="load" hx-target="this" hx-swap="innerHTML"></div>
|
||||
{% if best_fit_formula and not forecast_enabled %}
|
||||
<h2 class="text-xs font-semibold text-blue-200 mb-4 text-center">
|
||||
{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<section id="workout-note-{{ workout_id }}" class="workout-card workout-note-card"
|
||||
hx-target="this" hx-swap="outerHTML">
|
||||
{% if is_edit|default(false) %}
|
||||
<form class="workout-note-editor"
|
||||
hx-put="{{ url_for('notes.update_workout_note', person_id=person_id, workout_id=workout_id, view='session') }}"
|
||||
hx-disabled-elt="find button"
|
||||
_="on htmx:responseError remove .hidden from #note-error-{{ workout_id }}">
|
||||
<label for="session-note-input-{{ workout_id }}">Session notes</label>
|
||||
<textarea id="session-note-input-{{ workout_id }}" name="note" rows="5"
|
||||
placeholder="Cues, energy, how it felt…"
|
||||
_="init call me.focus() end">{{ note or '' }}</textarea>
|
||||
<p id="note-error-{{ workout_id }}" class="workout-editor-error hidden" role="alert">Could not save your note. Please try again.</p>
|
||||
<div class="workout-editor-actions">
|
||||
<button type="button" class="workout-button"
|
||||
hx-get="{{ url_for('notes.get_workout_note', person_id=person_id, workout_id=workout_id, view='session') }}">Cancel</button>
|
||||
<button type="submit" class="workout-add-button">Save note</button>
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<button type="button" class="workout-note-trigger"
|
||||
hx-get="{{ url_for('notes.get_workout_note_edit_form', person_id=person_id, workout_id=workout_id, view='session') }}"
|
||||
aria-label="{{ 'Edit session notes' if note else 'Add session notes' }}">
|
||||
<span class="workout-inline-heading">Session notes <span class="workout-inline-action">{{ 'Edit' if note else '+ Add' }}</span></span>
|
||||
{% if note %}<span class="workout-note-preview">{% for line in note.split('\n') %}{{ line }}{% if not loop.last %}<br>{% endif %}{% endfor %}</span>
|
||||
{% else %}<span class="workout-subtle">Cues, energy, how it felt</span>{% endif %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</section>
|
||||
@@ -64,8 +64,6 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
<div class="progress-heading">
|
||||
<div class="progress-title">
|
||||
<h4>{{ title }}</h4>
|
||||
<div hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=latest_workout_id, topset_id=latest_topset_id) }}"
|
||||
hx-trigger="load" hx-target="this" hx-swap="innerHTML"></div>
|
||||
</div>
|
||||
<div class="progress-actions">
|
||||
<button class="progress-action" title="History and forecast tables"
|
||||
@@ -78,6 +76,8 @@ M{% for value, position in lower_points %}{{ (((position * vb_width) + margin) |
|
||||
hx-target="#svg-plot-{{ unique_id }}" hx-swap="outerHTML">Forecast {{ 'on' if forecast_enabled else 'off' }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-badges" aria-label="Progress achievements" hx-get="{{ url_for('workout.get_topset_achievements', person_id=person_id, workout_id=latest_workout_id, topset_id=latest_topset_id) }}"
|
||||
hx-trigger="load" hx-target="this" hx-swap="innerHTML"></div>
|
||||
<h2 class="text-xs font-semibold text-blue-200 mb-1 text-center">
|
||||
{% if best_fit_formula and not forecast_enabled %}
|
||||
{{ best_fit_formula.kg_per_week }} kg/week, {{ best_fit_formula.kg_per_month }} kg/month
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<div id="workout-tag-editor-{{ workout_id }}" class="workout-tag-editor">
|
||||
<form hx-post="{{ url_for('tags.add_tag_to_workout', workout_id=workout_id, view='session') }}"
|
||||
hx-trigger="change" hx-target="#workout-tag-editor-{{ workout_id }}" hx-swap="outerHTML"
|
||||
hx-disabled-elt="#workout-tag-editor-{{ workout_id }} input, #workout-tag-editor-{{ workout_id }} button"
|
||||
_="on htmx:responseError remove .hidden from #tag-error-{{ workout_id }}">
|
||||
<fieldset>
|
||||
<legend class="workout-subtle">Select tags for this session</legend>
|
||||
<div class="workout-tag-choices">
|
||||
{% for tag in tags %}
|
||||
<label class="workout-tag-choice">
|
||||
<input id="workout-{{ workout_id }}-tag-{{ tag.tag_id }}" type="checkbox" name="tag_id" value="{{ tag.tag_id }}" {% if tag.is_selected %}checked{% endif %}>
|
||||
<span>{{ tag.tag_name }}</span>
|
||||
</label>
|
||||
{% else %}<p class="workout-subtle">Create your first tag below.</p>{% endfor %}
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
<form class="workout-tag-create"
|
||||
hx-post="{{ url_for('tags.create_new_tag_for_workout', workout_id=workout_id, view='session') }}"
|
||||
hx-target="#workout-tag-editor-{{ workout_id }}" hx-swap="outerHTML"
|
||||
hx-disabled-elt="#workout-tag-editor-{{ workout_id }} input, #workout-tag-editor-{{ workout_id }} button"
|
||||
_="on htmx:responseError remove .hidden from #tag-error-{{ workout_id }}">
|
||||
<label for="new-workout-tag-{{ workout_id }}" class="sr-only">New tag name</label>
|
||||
<input id="new-workout-tag-{{ workout_id }}" type="text" name="tag_name" placeholder="New tag…" required>
|
||||
<button type="submit" class="workout-button">Add tag</button>
|
||||
</form>
|
||||
<p id="tag-error-{{ workout_id }}" class="workout-editor-error hidden" role="alert">Could not save tags. Please try again.</p>
|
||||
</div>
|
||||
@@ -1,73 +1,4 @@
|
||||
<div class="flex">
|
||||
<div id="tag-wrapper-w-{{ workout_id }}">
|
||||
{{ render_partial('partials/workout_tags_list.html', tags=tags)}}
|
||||
</div>
|
||||
<span id="tag-form-show-w-{{ workout_id }}" class="cursor-pointer" _="on click
|
||||
remove .hidden from #tag-form-w-{{ workout_id }}
|
||||
then remove .hidden from #tag-form-hide-w-{{ workout_id }}
|
||||
then add .hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="w-6 h-6" data-darkreader-inline-stroke="" style="--darkreader-inline-stroke: currentColor;">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<span id="tag-form-hide-w-{{ workout_id }}" _="on click
|
||||
add .hidden to #tag-form-w-{{ workout_id }}
|
||||
then remove .hidden from #tag-form-show-w-{{ workout_id }}
|
||||
then add .hidden" class="cursor-pointer hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
class="w-6 h-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12h-15" />
|
||||
</svg>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
<div id="tag-form-w-{{ workout_id }}" class="hidden pt-2 pb-3">
|
||||
|
||||
<span class="text-base font-normal text-gray-500">Add tag to workout</span>
|
||||
|
||||
<div class="flex pt-2 flex-col sm:flex-row pb-2">
|
||||
|
||||
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
|
||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-state">
|
||||
Tag
|
||||
</label>
|
||||
<div class="relative">
|
||||
<div class="w-full">
|
||||
{{ render_partial('partials/custom_select.html',
|
||||
name='tag_id',
|
||||
options=tags,
|
||||
multiple=true,
|
||||
search=true,
|
||||
placeholder='Select tags',
|
||||
hx_post=url_for('tags.add_tag_to_workout', workout_id=workout_id),
|
||||
hx_target='#tag-wrapper-w-' + workout_id|string)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full md:w-1/2 px-3 mb-6 md:mb-0">
|
||||
<label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2">
|
||||
New tag name
|
||||
</label>
|
||||
<div class="flex">
|
||||
<input
|
||||
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
|
||||
type="text" name="tag_name">
|
||||
|
||||
<button type="submit" hx-post="{{ url_for('tags.create_new_tag_for_workout', workout_id=workout_id) }}"
|
||||
hx-include="[name='tag_name']" hx-target="#tag-wrapper-w-{{ workout_id }}"
|
||||
class="p-2.5 ml-2 text-sm font-medium text-white bg-blue-700 rounded-lg border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
|
||||
stroke="currentColor" class="w-6 h-6" data-darkreader-inline-stroke=""
|
||||
style="--darkreader-inline-stroke: currentColor;">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"></path>
|
||||
</svg>
|
||||
<span class="sr-only">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<section class="workout-card workout-tags-card" aria-labelledby="workout-tags-heading-{{ workout_id }}">
|
||||
<h2 id="workout-tags-heading-{{ workout_id }}">Tags</h2>
|
||||
{{ render_partial('partials/workout_tag_editor.html', person_id=person_id, workout_id=workout_id, tags=tags) }}
|
||||
</section>
|
||||
|
||||
+5
-20
@@ -46,14 +46,9 @@
|
||||
<h1>{{ person_name }}<span> / Workout</span></h1>
|
||||
{{ render_partial('partials/start_date.html', person_id=person_id, workout_id=workout_id, start_date=start_date) }}
|
||||
</div>
|
||||
<details class="workout-menu">
|
||||
<summary class="workout-button">Session options <span aria-hidden="true">···</span></summary>
|
||||
<div class="workout-menu-content">
|
||||
<button type="button" class="workout-delete"
|
||||
hx-get="{{ url_for('workout.delete_workout', person_id=person_id, workout_id=workout_id) }}"
|
||||
hx-confirm="Are you sure you wish to delete this workout?" hx-push-url="true" hx-target="#container">Delete workout</button>
|
||||
</div>
|
||||
</details>
|
||||
<button type="button" class="workout-button workout-delete"
|
||||
hx-get="{{ url_for('workout.delete_workout', person_id=person_id, workout_id=workout_id) }}"
|
||||
hx-confirm="Are you sure you wish to delete this workout?" hx-push-url="true" hx-target="#container">Delete workout</button>
|
||||
</header>
|
||||
|
||||
<div class="workout-layout">
|
||||
@@ -96,18 +91,8 @@
|
||||
</details>
|
||||
</div>
|
||||
</details>
|
||||
<details class="workout-card workout-disclosure" {% if note %}open{% endif %}>
|
||||
<summary>Session notes <span class="workout-subtle">Cues, energy, how it felt</span></summary>
|
||||
<div class="workout-disclosure-body">
|
||||
{{ render_partial('partials/workout_note.html', person_id=person_id, workout_id=workout_id, note=note or '') }}
|
||||
</div>
|
||||
</details>
|
||||
<details class="workout-card workout-disclosure">
|
||||
<summary>Tags <span class="workout-subtle">Organize this session</span></summary>
|
||||
<div class="workout-disclosure-body">
|
||||
{{ render_partial('partials/workout_tags.html', person_id=person_id, workout_id=workout_id, tags=tags) }}
|
||||
</div>
|
||||
</details>
|
||||
{{ render_partial('partials/session_note.html', person_id=person_id, workout_id=workout_id, note=note or '') }}
|
||||
{{ render_partial('partials/workout_tags.html', person_id=person_id, workout_id=workout_id, tags=tags) }}
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user