cd465e0564
- Add backend/app/mcp_server.py with FastMCP server (hms-cms) - Resources: design-rules, page-structure, sync-status - Tools: trigger_sync, get_sync_log, set_rentman_token, read_file, write_file, create_page, deploy, git_commit, git_status - Bearer token auth via MCP_AUTH_TOKEN env var - Mount MCP at /mcp with streamable HTTP transport - Integrate session manager in FastAPI lifespan - Add Traefik labels for external /mcp route on hms.media-on.de - Add git, docker.io, curl to backend Dockerfile - Mount repo root + docker socket in backend container - Add mcp>=1.0.0 to requirements.txt
179 lines
4.5 KiB
TypeScript
179 lines
4.5 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import type { EquipmentItem } from "~/composables/useEquipment";
|
|
|
|
/**
|
|
* Cart item structure stored in the Pinia cart store.
|
|
*/export interface CartItem {
|
|
equipment_id: number;
|
|
name: string;
|
|
quantity: number;
|
|
rental_price: number | null;
|
|
image_url: string | null;
|
|
}
|
|
|
|
/**
|
|
* Form payload for rental request submission.
|
|
*/export interface RentalRequestPayload {
|
|
event_name: string;
|
|
date_start: string;
|
|
date_end: string;
|
|
location: string;
|
|
person_count: number;
|
|
contact_name: string;
|
|
contact_company: string;
|
|
contact_email: string;
|
|
contact_phone: string;
|
|
contact_street: string;
|
|
contact_postalcode: string;
|
|
contact_city: string;
|
|
message: string;
|
|
items: { equipment_id: number; quantity: number }[];
|
|
}
|
|
|
|
/**
|
|
* Response from POST /api/rental-requests.
|
|
*/export interface RentalRequestResponse {
|
|
reference_number: string;
|
|
status: string;
|
|
}
|
|
|
|
/**
|
|
* Pinia store for the equipment rental cart.
|
|
* Persists to localStorage via plugins/pinia-persist.client.ts.
|
|
*/export const useCartStore = defineStore("cart", {
|
|
state: (): { items: CartItem[] } => ({
|
|
items: [] as CartItem[],
|
|
}),
|
|
|
|
getters: {
|
|
/**
|
|
* Total count of all items (sum of quantities).
|
|
*/ totalCount(state): number {
|
|
return state.items.reduce((sum, item) => sum + item.quantity, 0);
|
|
},
|
|
|
|
/**
|
|
* Whether the cart is empty.
|
|
*/ isEmpty(state): boolean {
|
|
return state.items.length === 0;
|
|
},
|
|
|
|
/**
|
|
* Whether the cart has items.
|
|
*/ hasItems(state): boolean {
|
|
return state.items.length > 0;
|
|
},
|
|
|
|
/**
|
|
* Items as formatted payload for rental request API.
|
|
*/ apiItems(state): { equipment_id: number; quantity: number }[] {
|
|
return state.items.map((item) => ({
|
|
equipment_id: item.equipment_id,
|
|
quantity: item.quantity,
|
|
}));
|
|
},
|
|
},
|
|
|
|
actions: {
|
|
/**
|
|
* Add an equipment item to the cart. If it already exists, increment quantity.
|
|
*/ addItem(equipment: EquipmentItem): void {
|
|
const existing = this.items.find(
|
|
(item) => item.equipment_id === equipment.id,
|
|
);
|
|
if (existing) {
|
|
existing.quantity += 1;
|
|
} else {
|
|
this.items.push({
|
|
equipment_id: equipment.id,
|
|
name: equipment.name,
|
|
quantity: 1,
|
|
rental_price: equipment.rental_price,
|
|
image_url: equipment.image_url,
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Add an item by explicit fields (used from detail page where full EquipmentItem may not be available).
|
|
*/ addItemByFields(item: {
|
|
equipment_id: number;
|
|
name: string;
|
|
rental_price: number | null;
|
|
image_url: string | null;
|
|
}): void {
|
|
const existing = this.items.find(
|
|
(i) => i.equipment_id === item.equipment_id,
|
|
);
|
|
if (existing) {
|
|
existing.quantity += 1;
|
|
} else {
|
|
this.items.push({
|
|
equipment_id: item.equipment_id,
|
|
name: item.name,
|
|
quantity: 1,
|
|
rental_price: item.rental_price,
|
|
image_url: item.image_url,
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Remove an item from the cart by equipment_id.
|
|
*/ removeItem(equipmentId: number): void {
|
|
const idx = this.items.findIndex(
|
|
(item) => item.equipment_id === equipmentId,
|
|
);
|
|
if (idx !== -1) {
|
|
this.items.splice(idx, 1);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Update the quantity of a cart item. If quantity <= 0, remove the item.
|
|
*/ updateQuantity(equipmentId: number, quantity: number): void {
|
|
if (quantity <= 0) {
|
|
this.removeItem(equipmentId);
|
|
return;
|
|
}
|
|
const item = this.items.find(
|
|
(i) => i.equipment_id === equipmentId,
|
|
);
|
|
if (item) {
|
|
item.quantity = quantity;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Increment quantity of a cart item.
|
|
*/ incrementQuantity(equipmentId: number): void {
|
|
const item = this.items.find(
|
|
(i) => i.equipment_id === equipmentId,
|
|
);
|
|
if (item) {
|
|
item.quantity += 1;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Decrement quantity of a cart item. If quantity reaches 0, remove it.
|
|
*/ decrementQuantity(equipmentId: number): void {
|
|
const item = this.items.find(
|
|
(i) => i.equipment_id === equipmentId,
|
|
);
|
|
if (item) {
|
|
item.quantity -= 1;
|
|
if (item.quantity <= 0) {
|
|
this.removeItem(equipmentId);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Clear all items from the cart.
|
|
*/ clearCart(): void {
|
|
this.items = [];
|
|
},
|
|
},
|
|
});
|