All checks were successful
Docker Deploy / build-and-push (push) Successful in 4m6s
183 lines
5.7 KiB
Plaintext
183 lines
5.7 KiB
Plaintext
---
|
|
import DashboardLayout from '../../../../layouts/DashboardLayout.astro';
|
|
import { Icon } from 'astro-icon/components';
|
|
import { db } from '../../../../db';
|
|
import { clients } from '../../../../db/schema';
|
|
import { eq, and } from 'drizzle-orm';
|
|
import { getCurrentTeam } from '../../../../lib/getCurrentTeam';
|
|
|
|
const user = Astro.locals.user;
|
|
if (!user) return Astro.redirect('/login');
|
|
|
|
const { id } = Astro.params;
|
|
if (!id) return Astro.redirect('/dashboard/clients');
|
|
|
|
const userMembership = await getCurrentTeam(user, Astro.cookies.get('currentTeamId')?.value);
|
|
if (!userMembership) return Astro.redirect('/dashboard');
|
|
|
|
const client = await db.select()
|
|
.from(clients)
|
|
.where(and(
|
|
eq(clients.id, id),
|
|
eq(clients.organizationId, userMembership.organizationId)
|
|
))
|
|
.get();
|
|
|
|
if (!client) return Astro.redirect('/dashboard/clients');
|
|
---
|
|
|
|
<DashboardLayout title={`Edit ${client.name} - Chronus`}>
|
|
<div class="max-w-2xl mx-auto">
|
|
<div class="flex items-center gap-3 mb-6">
|
|
<a href={`/dashboard/clients/${client.id}`} class="btn btn-ghost btn-xs">
|
|
<Icon name="heroicons:arrow-left" class="w-4 h-4" />
|
|
</a>
|
|
<h1 class="text-2xl font-extrabold tracking-tight">Edit Client</h1>
|
|
</div>
|
|
|
|
<form method="POST" action={`/api/clients/${client.id}/update`} class="card card-border bg-base-100">
|
|
<div class="card-body p-4">
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Client Name</legend>
|
|
<input
|
|
type="text"
|
|
id="name"
|
|
name="name"
|
|
value={client.name}
|
|
placeholder="Acme Corp"
|
|
class="input w-full"
|
|
required
|
|
/>
|
|
</fieldset>
|
|
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Email (optional)</legend>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
value={client.email || ''}
|
|
placeholder="jason.borne@cia.com"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Phone (optional)</legend>
|
|
<input
|
|
type="tel"
|
|
id="phone"
|
|
name="phone"
|
|
value={client.phone || ''}
|
|
placeholder="+1 (780) 420-1337"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
|
|
<div class="divider text-xs text-base-content/40">Address Details</div>
|
|
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Street Address (optional)</legend>
|
|
<input
|
|
type="text"
|
|
id="street"
|
|
name="street"
|
|
value={client.street || ''}
|
|
placeholder="123 Business Rd"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">City (optional)</legend>
|
|
<input
|
|
type="text"
|
|
id="city"
|
|
name="city"
|
|
value={client.city || ''}
|
|
placeholder="Edmonton"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">State / Province (optional)</legend>
|
|
<input
|
|
type="text"
|
|
id="state"
|
|
name="state"
|
|
value={client.state || ''}
|
|
placeholder="AB"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Zip / Postal Code (optional)</legend>
|
|
<input
|
|
type="text"
|
|
id="zip"
|
|
name="zip"
|
|
value={client.zip || ''}
|
|
placeholder="10001"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
|
|
<fieldset class="fieldset">
|
|
<legend class="fieldset-legend text-xs">Country (optional)</legend>
|
|
<input
|
|
type="text"
|
|
id="country"
|
|
name="country"
|
|
value={client.country || ''}
|
|
placeholder="Canada"
|
|
class="input w-full"
|
|
/>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<div class="flex justify-between items-center mt-4">
|
|
<button
|
|
type="button"
|
|
class="btn btn-error btn-outline btn-sm"
|
|
onclick={`document.getElementById('delete_modal').showModal()`}
|
|
>
|
|
Delete Client
|
|
</button>
|
|
|
|
<div class="flex gap-2">
|
|
<a href={`/dashboard/clients/${client.id}`} class="btn btn-ghost btn-sm">Cancel</a>
|
|
<button type="submit" class="btn btn-primary btn-sm">Save Changes</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Delete Confirmation Modal -->
|
|
<dialog id="delete_modal" class="modal">
|
|
<div class="modal-box">
|
|
<h3 class="font-semibold text-base text-error">Delete Client?</h3>
|
|
<p class="py-4 text-sm">
|
|
Are you sure you want to delete <strong>{client.name}</strong>?
|
|
This action cannot be undone and will delete all associated time entries.
|
|
</p>
|
|
<div class="modal-action">
|
|
<form method="dialog">
|
|
<button class="btn btn-sm">Cancel</button>
|
|
</form>
|
|
<form method="POST" action={`/api/clients/${client.id}/delete`}>
|
|
<button type="submit" class="btn btn-error btn-sm">Delete</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<form method="dialog" class="modal-backdrop">
|
|
<button>close</button>
|
|
</form>
|
|
</dialog>
|
|
</DashboardLayout>
|