Move the new-project form into the dashboard grid as a tile
It now sits last in .dashboard__grid, styled like a project-card (dashed border to read as an action rather than a project) instead of as a separate form below the grid. Relabel it 'Create a project' and add a 'Name' placeholder to the input. Also drop the now-redundant 'no projects yet' empty-state message -- the grid always renders since the create tile lives inside it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ Each user owns **projects**, and each project holds ordered **cards**.
|
||||
| 8 | Passwordless login — magic-link by default, password login behind a toggle | ✅ done |
|
||||
| 9 | Per-project card statuses ("To do" / "Doing" / "Done"); status chip, new cards start with none | ✅ done |
|
||||
| 10 | Project view — full-width, tabbed: alphabetical "All tasks" list + "Kanban" board, per-column drag ordering | ✅ done |
|
||||
| 11 | Persistent left sidebar (Dashboard link + project dropdown); dashboard = grid of project tiles + new-project form | ✅ done |
|
||||
| 11 | Persistent left sidebar (Dashboard link + project dropdown); dashboard = grid of project tiles + a "Create a project" tile | ✅ done |
|
||||
| 12 | Passwordless-only auth — registration and password login removed; a magic link is the sole way in, and creates the account if needed | ✅ done |
|
||||
| 13 | Global inbox — cards can have no project; moved into the sidebar, drag in/out of any project's kanban columns | ✅ done |
|
||||
| 14 | New-project form moved to the dashboard; sidebar project list is now a switcher dropdown; Kanban is a project's default tab | ✅ done |
|
||||
|
||||
+4
-3
@@ -58,9 +58,10 @@ it also works as a project switcher from anywhere. `<RouterView
|
||||
projects always does a fresh load.
|
||||
|
||||
`/` redirects to `/dashboard` (`DashboardView.vue`): a full-width grid linking
|
||||
to each project (title + card count), then a **new-project form** directly
|
||||
below it (creating one stays on the dashboard; the grid and the sidebar
|
||||
dropdown both pick it up via the shared `projects` store). Signed-out routes
|
||||
to each project (title + card count), with a **"Create a project" tile**
|
||||
styled to match sitting last in the same grid (creating one stays on the
|
||||
dashboard; the grid and the sidebar dropdown both pick it up via the shared
|
||||
`projects` store). Signed-out routes
|
||||
(`/login`, `/verify-email`) render without the sidebar.
|
||||
|
||||
## Inbox
|
||||
|
||||
+19
-1
@@ -360,6 +360,25 @@ h1 {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.project-card--new {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.project-card--new label {
|
||||
display: grid;
|
||||
gap: 0.3rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.project-card--new input {
|
||||
padding: 0.55rem 0.7rem;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/* --- project detail: cards ------------------------------------------ */
|
||||
|
||||
.cards {
|
||||
@@ -743,7 +762,6 @@ h1 {
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
|
||||
.form--new-project,
|
||||
.form--new-card {
|
||||
margin-top: 1.5rem;
|
||||
padding-top: 1.25rem;
|
||||
|
||||
@@ -43,10 +43,6 @@ async function onCreate() {
|
||||
<div class="dashboard">
|
||||
<p v-if="loadError" class="form-error">{{ loadError }}</p>
|
||||
<p v-else-if="projects.loading && !projects.loaded" class="muted">Loading…</p>
|
||||
<p v-else-if="projects.projects.length === 0" class="muted">
|
||||
No projects yet — create one below. Anything uncategorised lives in the
|
||||
inbox, in the sidebar.
|
||||
</p>
|
||||
|
||||
<div v-else class="dashboard__grid">
|
||||
<RouterLink
|
||||
@@ -60,28 +56,28 @@ async function onCreate() {
|
||||
{{ project.card_count }} card{{ project.card_count === 1 ? '' : 's' }}
|
||||
</span>
|
||||
</RouterLink>
|
||||
|
||||
<form class="project-card project-card--new" @submit.prevent="onCreate">
|
||||
<label>
|
||||
<span class="project-card__title">Create a project</span>
|
||||
<input v-model="title" type="text" maxlength="255" placeholder="Name" required :disabled="atLimit" />
|
||||
<small v-if="createError?.fieldError('title')" class="field-error">
|
||||
{{ createError.fieldError('title') }}
|
||||
</small>
|
||||
</label>
|
||||
|
||||
<p v-if="createError && Object.keys(createError.details).length === 0" class="form-error">
|
||||
{{ createError.message }}
|
||||
</p>
|
||||
|
||||
<button type="submit" :disabled="submitting || atLimit">
|
||||
{{ submitting ? 'Creating…' : 'Create project' }}
|
||||
</button>
|
||||
|
||||
<p v-if="atLimit" class="hint">
|
||||
You have reached the maximum of {{ MAX_PROJECTS }} projects.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form class="form form--new-project" @submit.prevent="onCreate">
|
||||
<label>
|
||||
<span>New project title</span>
|
||||
<input v-model="title" type="text" maxlength="255" required :disabled="atLimit" />
|
||||
<small v-if="createError?.fieldError('title')" class="field-error">
|
||||
{{ createError.fieldError('title') }}
|
||||
</small>
|
||||
</label>
|
||||
|
||||
<p v-if="createError && Object.keys(createError.details).length === 0" class="form-error">
|
||||
{{ createError.message }}
|
||||
</p>
|
||||
|
||||
<button type="submit" :disabled="submitting || atLimit">
|
||||
{{ submitting ? 'Creating…' : 'Create project' }}
|
||||
</button>
|
||||
|
||||
<p v-if="atLimit" class="hint">
|
||||
You have reached the maximum of {{ MAX_PROJECTS }} projects.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user