display user kinds verbatim

This commit is contained in:
Yisroel Baum 2026-08-14 09:54:43 +03:00
parent 2101ab50d2
commit 74feb38300
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
5 changed files with 28 additions and 50 deletions

View file

@ -139,7 +139,7 @@ describe('set scheduling', () => {
cy.get('h1').should('have.text', 'Schedule Bible') cy.get('h1').should('have.text', 'Schedule Bible')
cy.get('#schedule-level option').then(($options) => { cy.get('#schedule-level option').then(($options) => {
expect([...$options].map((option) => option.textContent?.trim())).to.deep.equal( expect([...$options].map((option) => option.textContent?.trim())).to.deep.equal(
['Choose a level', 'Book (2)', 'Portion (2)', 'Chapter_sections-v2 (2)'], ['Choose a level', 'book (2)', 'portion (2)', 'Chapter_sections-v2 (2)'],
) )
}) })
cy.get('#schedule-level').select('3') cy.get('#schedule-level').select('3')
@ -155,6 +155,7 @@ describe('set scheduling', () => {
.should('contain.text', 'Genesis / Creation / Chapter 1') .should('contain.text', 'Genesis / Creation / Chapter 1')
.find('.assignment-kind') .find('.assignment-kind')
.should('have.text', 'Chapter_sections-v2') .should('have.text', 'Chapter_sections-v2')
.and('have.css', 'text-transform', 'none')
cy.get('[data-schedule-date="2026-08-11"]') cy.get('[data-schedule-date="2026-08-11"]')
.should('contain.text', 'Rest day') .should('contain.text', 'Rest day')
.and('not.contain.text', 'Chapter 1') .and('not.contain.text', 'Chapter 1')
@ -208,7 +209,10 @@ describe('set scheduling', () => {
cy.wait('@me') cy.wait('@me')
cy.wait('@schedule') cy.wait('@schedule')
cy.get('h1').should('have.text', 'Bible schedule') cy.get('h1').should('have.text', 'Bible schedule')
cy.get('.eyebrow').should('have.text', 'Chapter_sections-v2 plan') cy.get('.eyebrow')
.should('have.text', 'Chapter_sections-v2 plan')
.find('.schedule-kind')
.should('have.css', 'text-transform', 'none')
cy.contains('2 Chapter_sections-v2 assignments across 3 days').should('be.visible') cy.contains('2 Chapter_sections-v2 assignments across 3 days').should('be.visible')
cy.intercept('GET', '**/api/schedules/74', { cy.intercept('GET', '**/api/schedules/74', {
@ -253,7 +257,9 @@ describe('set scheduling', () => {
cy.get('ul[aria-label="Your schedules"]') cy.get('ul[aria-label="Your schedules"]')
.should('contain.text', 'Bible') .should('contain.text', 'Bible')
.and('contain.text', '2 assignments') .and('contain.text', '2 assignments')
cy.get('.schedule-card__heading p').should('have.text', 'Chapter_sections-v2') cy.get('.schedule-card__heading p')
.should('have.text', 'Chapter_sections-v2')
.and('have.css', 'text-transform', 'none')
cy.contains('a', 'Bible').should('have.attr', 'href', '/schedules/73') cy.contains('a', 'Bible').should('have.attr', 'href', '/schedules/73')
}) })
}) })

View file

@ -87,7 +87,7 @@ defineProps<{
font-size: 0.62rem; font-size: 0.62rem;
font-weight: 800; font-weight: 800;
letter-spacing: 0.1em; letter-spacing: 0.1em;
text-transform: uppercase; text-transform: none;
} }
@media (max-width: 37.5rem) { @media (max-width: 37.5rem) {

View file

@ -26,12 +26,7 @@ const form = reactive({
const fieldErrors = ref<ScheduleFieldErrors>({}) const fieldErrors = ref<ScheduleFieldErrors>({})
const levels = computed(() => const levels = computed(() =>
(layout.value?.levels ?? []) (layout.value?.levels ?? []).filter((level) => level.elementCount > 0),
.filter((level) => level.elementCount > 0)
.map((level) => ({
...level,
label: humanizeKind(level.kind),
})),
) )
const scheduleFormSchema = z const scheduleFormSchema = z
@ -111,12 +106,6 @@ async function retry(): Promise<void> {
await setLayoutStore.fetchSetLayout(currentSetId.value) await setLayoutStore.fetchSetLayout(currentSetId.value)
} }
} }
function humanizeKind(kind: string): string {
const words = kind.replaceAll(/[_-]+/g, ' ')
return words.charAt(0).toUpperCase() + words.slice(1)
}
</script> </script>
<template> <template>
@ -163,7 +152,7 @@ function humanizeKind(kind: string): string {
> >
<option :value="null">Choose a level</option> <option :value="null">Choose a level</option>
<option v-for="level in levels" :key="level.id" :value="level.id"> <option v-for="level in levels" :key="level.id" :value="level.id">
{{ level.label }} ({{ level.elementCount }}) {{ level.kind }} ({{ level.elementCount }})
</option> </option>
</select> </select>
<p v-if="fieldErrors.levelId" id="schedule-level-error" class="field-error"> <p v-if="fieldErrors.levelId" id="schedule-level-error" class="field-error">

View file

@ -15,12 +15,6 @@ onMounted(async () => {
await Promise.all([setsStore.fetchSets(), schedulesStore.fetchSchedules()]) await Promise.all([setsStore.fetchSets(), schedulesStore.fetchSchedules()])
}) })
function humanizeKind(kind: string): string {
const words = kind.replaceAll(/[_-]+/g, ' ')
return words.charAt(0).toUpperCase() + words.slice(1)
}
function formatDate(value: string): string { function formatDate(value: string): string {
return new Intl.DateTimeFormat('en', { return new Intl.DateTimeFormat('en', {
dateStyle: 'medium', dateStyle: 'medium',
@ -73,7 +67,7 @@ function formatDate(value: string): string {
> >
<article class="schedule-card"> <article class="schedule-card">
<div class="schedule-card__heading"> <div class="schedule-card__heading">
<p>{{ humanizeKind(schedule.elementKind) }}</p> <p class="schedule-card__kind">{{ schedule.elementKind }}</p>
<span>{{ schedule.assignmentCount }} assignments</span> <span>{{ schedule.assignmentCount }} assignments</span>
</div> </div>
<h3>{{ schedule.set.name }}</h3> <h3>{{ schedule.set.name }}</h3>
@ -310,6 +304,10 @@ h1 {
margin: 0; margin: 0;
} }
.schedule-card__kind {
text-transform: none;
}
.schedule-card h3 { .schedule-card h3 {
margin: 2rem 0 0; margin: 2rem 0 0;
font-family: Georgia, 'Times New Roman', serif; font-family: Georgia, 'Times New Roman', serif;

View file

@ -39,28 +39,6 @@ function formatDate(value: string): string {
timeZone: 'UTC', timeZone: 'UTC',
}).format(new Date(`${value}T00:00:00Z`)) }).format(new Date(`${value}T00:00:00Z`))
} }
function humanizeKind(kind: string): string {
const words = kind.replaceAll(/[_-]+/g, ' ')
return words.charAt(0).toUpperCase() + words.slice(1)
}
function pluralKind(kind: string, count: number): string {
if (count === 1) {
return kind
}
if (kind.endsWith('y')) {
return `${kind.slice(0, -1)}ies`
}
if (kind.endsWith('s')) {
return kind
}
return `${kind}s`
}
</script> </script>
<template> <template>
@ -87,11 +65,14 @@ function pluralKind(kind: string, count: number): string {
<template v-else-if="activeSchedule !== null"> <template v-else-if="activeSchedule !== null">
<header class="schedule-introduction"> <header class="schedule-introduction">
<p class="eyebrow">{{ humanizeKind(activeSchedule.elementKind) }} plan</p> <p class="eyebrow">
<span class="schedule-kind">{{ activeSchedule.elementKind }}</span> plan
</p>
<h1>{{ activeSchedule.set.name }} schedule</h1> <h1>{{ activeSchedule.set.name }} schedule</h1>
<p class="schedule-summary"> <p class="schedule-summary">
{{ activeSchedule.assignmentCount }} {{ activeSchedule.assignmentCount }}
{{ pluralKind(activeSchedule.elementKind, activeSchedule.assignmentCount) }} across {{ activeSchedule.elementKind }}
{{ activeSchedule.assignmentCount === 1 ? 'assignment' : 'assignments' }} across
{{ activeSchedule.days.length }} {{ activeSchedule.days.length }}
{{ activeSchedule.days.length === 1 ? 'day' : 'days' }} {{ activeSchedule.days.length === 1 ? 'day' : 'days' }}
</p> </p>
@ -119,7 +100,7 @@ function pluralKind(kind: string, count: number): string {
<ul v-else class="assignment-list"> <ul v-else class="assignment-list">
<li v-for="assignment in day.assignments" :key="assignment.id"> <li v-for="assignment in day.assignments" :key="assignment.id">
<span class="assignment-path">{{ assignment.element.path.join(' / ') }}</span> <span class="assignment-path">{{ assignment.element.path.join(' / ') }}</span>
<span class="assignment-kind">{{ humanizeKind(assignment.element.kind) }}</span> <span class="assignment-kind">{{ assignment.element.kind }}</span>
</li> </li>
</ul> </ul>
</li> </li>
@ -173,6 +154,10 @@ function pluralKind(kind: string, count: number): string {
text-transform: uppercase; text-transform: uppercase;
} }
.schedule-kind {
text-transform: none;
}
h1 { h1 {
margin: 0; margin: 0;
font-family: Georgia, 'Times New Roman', serif; font-family: Georgia, 'Times New Roman', serif;
@ -265,7 +250,7 @@ h1 {
font-size: 0.62rem; font-size: 0.62rem;
font-weight: 800; font-weight: 800;
letter-spacing: 0.1em; letter-spacing: 0.1em;
text-transform: uppercase; text-transform: none;
} }
.page-state { .page-state {