- Add Docker configuration (Dockerfile, docker-compose.yml) - Add Nginx and Supervisor configuration - Add deployment documentation (DEPLOYMENT.md) - Complete Phase 3 data migration (63 entries, 63 docs, 28 subs) - Add responsive PDF viewer component - Fix date format to American (MM/DD/YYYY) - Update typography to match v1.0 - Add admin dashboard with full CRUD operations - Configure PostgreSQL with secure password - Connect to caddy_network for reverse proxy - Ready for production deployment
174 lines
8.3 KiB
Vue
174 lines
8.3 KiB
Vue
<script setup lang="ts">
|
|
import { Head, Link, router } from '@inertiajs/vue3';
|
|
import { ref } from 'vue';
|
|
|
|
interface DocketEntry {
|
|
id: number;
|
|
date: string;
|
|
title: string;
|
|
summary: string;
|
|
documents_count: number;
|
|
}
|
|
|
|
interface Pagination {
|
|
current_page: number;
|
|
last_page: number;
|
|
per_page: number;
|
|
total: number;
|
|
}
|
|
|
|
interface Props {
|
|
entries: DocketEntry[];
|
|
pagination: Pagination;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const deleteEntry = (id: number, title: string) => {
|
|
if (confirm(`Are you sure you want to delete "${title}"? This will also delete all associated documents.`)) {
|
|
router.delete(route('admin.docket-entries.destroy', id));
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="min-h-screen bg-gray-100">
|
|
<Head title="Manage Docket Entries" />
|
|
|
|
<!-- Header -->
|
|
<header class="bg-white shadow">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
|
<div class="flex justify-between items-center">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-900">
|
|
Manage Docket Entries
|
|
</h1>
|
|
<p class="text-sm text-gray-600 mt-1">
|
|
{{ props.pagination.total }} total entries
|
|
</p>
|
|
</div>
|
|
<div class="flex gap-4">
|
|
<Link
|
|
:href="route('admin.dashboard')"
|
|
class="px-4 py-2 text-sm text-gray-700 hover:text-gray-900 transition-colors"
|
|
>
|
|
← Back to Dashboard
|
|
</Link>
|
|
<Link
|
|
:href="route('admin.docket-entries.create')"
|
|
class="px-4 py-2 bg-blue-600 text-white text-sm rounded-lg hover:bg-blue-700 transition-colors"
|
|
>
|
|
+ Create New Entry
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main Content -->
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="bg-white rounded-lg shadow">
|
|
<!-- Table -->
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Date
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Title
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Summary
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Documents
|
|
</th>
|
|
<th class="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
|
|
Actions
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
<tr
|
|
v-for="entry in props.entries"
|
|
:key="entry.id"
|
|
class="hover:bg-gray-50 transition-colors"
|
|
>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
|
|
{{ entry.date }}
|
|
</td>
|
|
<td class="px-6 py-4 text-sm font-medium text-gray-900">
|
|
{{ entry.title }}
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-600">
|
|
<div class="line-clamp-2">
|
|
{{ entry.summary }}
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">
|
|
<span class="px-2 py-1 text-xs font-medium text-blue-700 bg-blue-100 rounded-full">
|
|
{{ entry.documents_count }} doc{{ entry.documents_count !== 1 ? 's' : '' }}
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
|
<div class="flex justify-end gap-2">
|
|
<Link
|
|
:href="route('admin.docket-entries.show', entry.id)"
|
|
class="text-blue-600 hover:text-blue-900 transition-colors"
|
|
>
|
|
View
|
|
</Link>
|
|
<Link
|
|
:href="route('admin.docket-entries.edit', entry.id)"
|
|
class="text-indigo-600 hover:text-indigo-900 transition-colors"
|
|
>
|
|
Edit
|
|
</Link>
|
|
<button
|
|
@click="deleteEntry(entry.id, entry.title)"
|
|
class="text-red-600 hover:text-red-900 transition-colors"
|
|
>
|
|
Delete
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<tr v-if="props.entries.length === 0">
|
|
<td colspan="5" class="px-6 py-12 text-center text-gray-500">
|
|
No docket entries found. Create your first entry to get started.
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
<div v-if="props.pagination.last_page > 1" class="px-6 py-4 border-t border-gray-200">
|
|
<div class="flex items-center justify-between">
|
|
<div class="text-sm text-gray-700">
|
|
Showing page {{ props.pagination.current_page }} of {{ props.pagination.last_page }}
|
|
</div>
|
|
<div class="flex gap-2">
|
|
<Link
|
|
v-if="props.pagination.current_page > 1"
|
|
:href="route('admin.docket-entries.index', { page: props.pagination.current_page - 1 })"
|
|
class="px-3 py-1 text-sm bg-white border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
|
|
>
|
|
Previous
|
|
</Link>
|
|
<Link
|
|
v-if="props.pagination.current_page < props.pagination.last_page"
|
|
:href="route('admin.docket-entries.index', { page: props.pagination.current_page + 1 })"
|
|
class="px-3 py-1 text-sm bg-white border border-gray-300 rounded-md hover:bg-gray-50 transition-colors"
|
|
>
|
|
Next
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</template>
|