FEAT-13: Abgabe wizard (/vertraege/neu, 4 steps, ?tiere= prefill), Vertraege list w/ download+delete, /einstellungen Zuchtprofil form, contracts/settings API clients, nav entries, detail-page entry point + replace orphaned contactInfo with email/phone/address across Kontakt pages
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -69,4 +69,5 @@ export const resources = {
|
||||
contacts: '/contacts',
|
||||
enclosures: '/enclosures',
|
||||
colorVarieties: '/color-varieties',
|
||||
contracts: '/contracts',
|
||||
} as const
|
||||
|
||||
@@ -6,7 +6,9 @@ import type { Contact, Paged } from './types'
|
||||
/** Payload for POST /contacts. */
|
||||
export interface CreateContact {
|
||||
name: string
|
||||
contactInfo?: string | null
|
||||
email?: string | null
|
||||
phone?: string | null
|
||||
address?: string | null
|
||||
notes?: string | null
|
||||
}
|
||||
|
||||
|
||||
42
gerbil-manager-web/src/api/contracts.ts
Normal file
42
gerbil-manager-web/src/api/contracts.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/** FEAT-13: Abgabeverträge (/contracts). */
|
||||
import { API_BASE_URL, api, resources } from './client'
|
||||
import { toQueryString, type GridifyQuery } from './gridify'
|
||||
import type { DateOnlyString, Paged } from './types'
|
||||
|
||||
export interface SaleContract {
|
||||
id: string
|
||||
contactId: string
|
||||
price: number
|
||||
handoverDate: DateOnlyString
|
||||
contractDate: DateOnlyString
|
||||
fileName: string
|
||||
createdAt: string
|
||||
gerbilIds: string[]
|
||||
/** API-relativer Download-Pfad ("/contracts/{id}/file"). */
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface CreateSaleContract {
|
||||
contactId: string
|
||||
gerbilIds: string[]
|
||||
price: number
|
||||
handoverDate: DateOnlyString
|
||||
contractDate?: DateOnlyString | null
|
||||
}
|
||||
|
||||
export function listContracts(query: GridifyQuery): Promise<Paged<SaleContract>> {
|
||||
return api.get<Paged<SaleContract>>(`${resources.contracts}${toQueryString(query)}`)
|
||||
}
|
||||
|
||||
export function createContract(body: CreateSaleContract): Promise<SaleContract> {
|
||||
return api.post<SaleContract>(resources.contracts, body)
|
||||
}
|
||||
|
||||
export function deleteContract(id: string): Promise<void> {
|
||||
return api.delete(`${resources.contracts}/${id}`)
|
||||
}
|
||||
|
||||
/** Absolute Download-URL der .docx (für <a href> / window.open). */
|
||||
export function contractFileUrl(contract: Pick<SaleContract, 'url'>): string {
|
||||
return `${API_BASE_URL}${contract.url}`
|
||||
}
|
||||
36
gerbil-manager-web/src/api/settings.ts
Normal file
36
gerbil-manager-web/src/api/settings.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/** FEAT-13: Zuchtprofil (/settings/breeder-profile) — Verkäufer-Block der Verträge. */
|
||||
import { api } from './client'
|
||||
|
||||
export interface BreederProfile {
|
||||
zuchtName: string
|
||||
name: string
|
||||
address: string
|
||||
phone: string
|
||||
email: string
|
||||
homepage: string
|
||||
/** Ort der Unterschriftszeile („{Ort}, den {Datum}“). */
|
||||
city: string
|
||||
}
|
||||
|
||||
export const EMPTY_BREEDER_PROFILE: BreederProfile = {
|
||||
zuchtName: '',
|
||||
name: '',
|
||||
address: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
homepage: '',
|
||||
city: '',
|
||||
}
|
||||
|
||||
/** Pflichtangaben für einen brauchbaren Vertrag (Hinweis-Logik der UI). */
|
||||
export function isBreederProfileComplete(p: BreederProfile): boolean {
|
||||
return [p.name, p.address, p.city].every((v) => v.trim().length > 0)
|
||||
}
|
||||
|
||||
export function getBreederProfile(): Promise<BreederProfile> {
|
||||
return api.get<BreederProfile>('/settings/breeder-profile')
|
||||
}
|
||||
|
||||
export function putBreederProfile(profile: BreederProfile): Promise<void> {
|
||||
return api.put<void>('/settings/breeder-profile', profile)
|
||||
}
|
||||
@@ -73,7 +73,9 @@ export interface Enclosure {
|
||||
export interface Contact {
|
||||
id: string
|
||||
name: string
|
||||
contactInfo: string | null
|
||||
email: string | null
|
||||
phone: string | null
|
||||
address: string | null
|
||||
notes: string | null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user