This commit is contained in:
2025-11-25 16:08:10 -05:00
parent cb0f972a5f
commit 72971f6d3e
19 changed files with 1595 additions and 785 deletions

View File

@@ -0,0 +1,148 @@
<template>
<div class="task-view">
<TaskList
ref="taskListRef"
:deletable="true"
@edit-task="(taskId) => $router.push({ name: 'EditTask', params: { id: taskId } })"
@delete-task="confirmDeleteTask"
/>
<!-- Floating Action Button -->
<button class="fab" @click="createTask" aria-label="Create Task">
<svg width="28" height="28" viewBox="0 0 28 28" fill="none">
<circle cx="14" cy="14" r="14" fill="#667eea" />
<path d="M14 8v12M8 14h12" stroke="#fff" stroke-width="2" stroke-linecap="round" />
</svg>
</button>
<div v-if="showConfirm" class="modal-backdrop">
<div class="modal">
<p>Are you sure you want to delete this task?</p>
<div class="actions">
<button @click="deleteTask">Yes, Delete</button>
<button @click="showConfirm = false">Cancel</button>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import TaskList from './TaskList.vue'
const $router = useRouter()
const showConfirm = ref(false)
const taskToDelete = ref<string | null>(null)
const taskListRef = ref()
function confirmDeleteTask(taskId: string) {
taskToDelete.value = taskId
showConfirm.value = true
}
const deleteTask = async () => {
if (!taskToDelete.value) return
try {
const resp = await fetch(`/api/task/${taskToDelete.value}`, {
method: 'DELETE',
})
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
// Refresh the task list after successful delete
taskListRef.value?.refresh()
console.log(`Task ${taskToDelete.value} deleted successfully`)
} catch (err) {
console.error('Failed to delete task:', err)
} finally {
showConfirm.value = false
taskToDelete.value = null
}
}
// New function to handle task creation
const createTask = () => {
// Route to your create task page or open a create dialog
// Example:
$router.push({ name: 'CreateTask' })
}
</script>
<style scoped>
.task-view {
display: flex;
flex-direction: column;
align-items: center;
flex: 1 1 auto;
width: 100%;
height: 100%;
padding: 0;
min-height: 0;
}
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 1200;
}
.modal {
background: #fff;
color: #222;
padding: 1.5rem 2rem;
border-radius: 12px;
min-width: 240px;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
text-align: center;
}
.actions {
margin-top: 1.2rem;
display: flex;
gap: 1rem;
justify-content: center;
}
.actions button {
padding: 0.5rem 1.2rem;
border-radius: 8px;
border: none;
font-weight: 600;
cursor: pointer;
}
.actions button:first-child {
background: #ef4444;
color: #fff;
}
.actions button:last-child {
background: #f3f3f3;
color: #666;
}
.actions button:last-child:hover {
background: #e2e8f0;
}
/* Floating Action Button styles */
.fab {
position: fixed;
bottom: 2rem;
right: 2rem;
background: #667eea;
color: #fff;
border: none;
border-radius: 50%;
width: 56px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
cursor: pointer;
font-size: 24px;
z-index: 1300;
}
.fab:hover {
background: #5a67d8;
}
</style>