fix: backend syntax and frontend toast API
This commit is contained in:
parent
a13d6f6907
commit
2bc596c527
2 changed files with 547 additions and 551 deletions
|
|
@ -713,14 +713,10 @@ export async function layoutRoutes(fastify: FastifyInstance, options: FastifyPlu
|
||||||
return reply.status(500).send({ error: 'Failed to move plant' });
|
return reply.status(500).send({ error: 'Failed to move plant' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
} catch (error) {
|
|
||||||
fastify.log.error(error);
|
|
||||||
return reply.status(500).send({ error: 'Failed to move plant' });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Plant (Tag, Notes)
|
// Update Plant (Tag, Notes)
|
||||||
fastify.patch('/plants/:id', {
|
fastify.patch('/plants/:id', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -761,10 +757,10 @@ fastify.patch('/plants/:id', {
|
||||||
return reply.status(500).send({ error: 'Failed to update plant' });
|
return reply.status(500).send({ error: 'Failed to update plant' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Destroy Plant
|
// Destroy Plant
|
||||||
fastify.post('/plants/:id/destroy', {
|
fastify.post('/plants/:id/destroy', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -804,10 +800,10 @@ fastify.post('/plants/:id/destroy', {
|
||||||
return reply.status(500).send({ error: 'Failed to destroy plant' });
|
return reply.status(500).send({ error: 'Failed to destroy plant' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Harvest Plant
|
// Harvest Plant
|
||||||
fastify.post('/plants/:id/harvest', {
|
fastify.post('/plants/:id/harvest', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -847,10 +843,10 @@ fastify.post('/plants/:id/harvest', {
|
||||||
return reply.status(500).send({ error: 'Failed to harvest plant' });
|
return reply.status(500).send({ error: 'Failed to harvest plant' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bulk Fill Section (Place plants in all empty positions)
|
// Bulk Fill Section (Place plants in all empty positions)
|
||||||
fastify.post('/sections/:id/fill', {
|
fastify.post('/sections/:id/fill', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -915,14 +911,14 @@ fastify.post('/sections/:id/fill', {
|
||||||
return reply.status(500).send({ error: 'Failed to fill section' });
|
return reply.status(500).send({ error: 'Failed to fill section' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// SECTION ROUTES
|
// SECTION ROUTES
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
// Create section with positions
|
// Create section with positions
|
||||||
fastify.post('/sections', {
|
fastify.post('/sections', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { roomId, name, code, type, posX, posY, width, height, rows, columns, spacing, tiers } = request.body as any;
|
const { roomId, name, code, type, posX, posY, width, height, rows, columns, spacing, tiers } = request.body as any;
|
||||||
|
|
@ -971,10 +967,10 @@ fastify.post('/sections', {
|
||||||
return reply.status(500).send({ error: 'Failed to create section' });
|
return reply.status(500).send({ error: 'Failed to create section' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get section with positions
|
// Get section with positions
|
||||||
fastify.get('/sections/:id', {
|
fastify.get('/sections/:id', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -999,14 +995,14 @@ fastify.get('/sections/:id', {
|
||||||
return reply.status(500).send({ error: 'Failed to fetch section' });
|
return reply.status(500).send({ error: 'Failed to fetch section' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// BULK SAVE LAYOUT
|
// BULK SAVE LAYOUT
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
// Save entire floor layout
|
// Save entire floor layout
|
||||||
fastify.post('/floors/:id/layout', {
|
fastify.post('/floors/:id/layout', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id: floorId } = request.params as any;
|
const { id: floorId } = request.params as any;
|
||||||
|
|
@ -1143,14 +1139,14 @@ fastify.post('/floors/:id/layout', {
|
||||||
return reply.status(500).send({ error: 'Failed to save layout' });
|
return reply.status(500).send({ error: 'Failed to save layout' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// POSITION ROUTES
|
// POSITION ROUTES
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
// Get hierarchical address for a position
|
// Get hierarchical address for a position
|
||||||
fastify.get('/positions/:id/address', {
|
fastify.get('/positions/:id/address', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { id } = request.params as any;
|
const { id } = request.params as any;
|
||||||
|
|
@ -1208,14 +1204,14 @@ fastify.get('/positions/:id/address', {
|
||||||
return reply.status(500).send({ error: 'Failed to generate address' });
|
return reply.status(500).send({ error: 'Failed to generate address' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// PLANT TYPE LIBRARY ROUTES (Rackula-inspired)
|
// PLANT TYPE LIBRARY ROUTES (Rackula-inspired)
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
// Get all plant types
|
// Get all plant types
|
||||||
fastify.get('/plant-types', {
|
fastify.get('/plant-types', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const plantTypes = await prisma.plantType.findMany({
|
const plantTypes = await prisma.plantType.findMany({
|
||||||
|
|
@ -1227,10 +1223,10 @@ fastify.get('/plant-types', {
|
||||||
return reply.status(500).send({ error: 'Failed to fetch plant types' });
|
return reply.status(500).send({ error: 'Failed to fetch plant types' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get plant type by slug
|
// Get plant type by slug
|
||||||
fastify.get('/plant-types/:slug', {
|
fastify.get('/plant-types/:slug', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { slug } = request.params as { slug: string };
|
const { slug } = request.params as { slug: string };
|
||||||
|
|
@ -1248,10 +1244,10 @@ fastify.get('/plant-types/:slug', {
|
||||||
return reply.status(500).send({ error: 'Failed to fetch plant type' });
|
return reply.status(500).send({ error: 'Failed to fetch plant type' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create plant type
|
// Create plant type
|
||||||
fastify.post('/plant-types', {
|
fastify.post('/plant-types', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { name, strain, category, colour, growthDays, yieldGrams, notes, tags, customFields } = request.body as any;
|
const { name, strain, category, colour, growthDays, yieldGrams, notes, tags, customFields } = request.body as any;
|
||||||
|
|
@ -1292,10 +1288,10 @@ fastify.post('/plant-types', {
|
||||||
return reply.status(500).send({ error: 'Failed to create plant type' });
|
return reply.status(500).send({ error: 'Failed to create plant type' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update plant type
|
// Update plant type
|
||||||
fastify.put('/plant-types/:slug', {
|
fastify.put('/plant-types/:slug', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { slug } = request.params as { slug: string };
|
const { slug } = request.params as { slug: string };
|
||||||
|
|
@ -1322,10 +1318,10 @@ fastify.put('/plant-types/:slug', {
|
||||||
return reply.status(500).send({ error: 'Failed to update plant type' });
|
return reply.status(500).send({ error: 'Failed to update plant type' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete plant type
|
// Delete plant type
|
||||||
fastify.delete('/plant-types/:slug', {
|
fastify.delete('/plant-types/:slug', {
|
||||||
handler: async (request, reply) => {
|
handler: async (request, reply) => {
|
||||||
try {
|
try {
|
||||||
const { slug } = request.params as { slug: string };
|
const { slug } = request.params as { slug: string };
|
||||||
|
|
@ -1336,5 +1332,5 @@ fastify.delete('/plant-types/:slug', {
|
||||||
return reply.status(500).send({ error: 'Failed to delete plant type' });
|
return reply.status(500).send({ error: 'Failed to delete plant type' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ export function LayoutEditor({ floorId, className }: LayoutEditorProps) {
|
||||||
if (newTag && newTag !== selectedSlot.plant?.tagNumber) {
|
if (newTag && newTag !== selectedSlot.plant?.tagNumber) {
|
||||||
layoutApi.updatePlant(selectedSlot.plant!.id, { tagNumber: newTag })
|
layoutApi.updatePlant(selectedSlot.plant!.id, { tagNumber: newTag })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast({ title: 'Tag Updated', description: newTag });
|
toast.info('Tag Updated', { description: newTag });
|
||||||
reloadFloorData();
|
reloadFloorData();
|
||||||
setSelectedSlot(prev => prev ? ({ ...prev, plant: { ...prev.plant!, tagNumber: newTag } }) : null);
|
setSelectedSlot(prev => prev ? ({ ...prev, plant: { ...prev.plant!, tagNumber: newTag } }) : null);
|
||||||
});
|
});
|
||||||
|
|
@ -319,7 +319,7 @@ export function LayoutEditor({ floorId, className }: LayoutEditorProps) {
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<button
|
<button
|
||||||
className="py-2.5 bg-secondary hover:bg-secondary/80 text-foreground border border-border text-sm rounded-lg transition-colors font-medium flex items-center justify-center gap-2"
|
className="py-2.5 bg-secondary hover:bg-secondary/80 text-foreground border border-border text-sm rounded-lg transition-colors font-medium flex items-center justify-center gap-2"
|
||||||
onClick={() => toast({ title: 'Move Plant', description: 'Drag and drop plants on the grid to move them.' })}
|
onClick={() => toast.info('Move Plant', { description: 'Drag and drop plants on the grid to move them.' })}
|
||||||
>
|
>
|
||||||
<Move className="w-4 h-4" /> Move
|
<Move className="w-4 h-4" /> Move
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -362,7 +362,7 @@ export function LayoutEditor({ floorId, className }: LayoutEditorProps) {
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
className="col-span-2 py-2.5 bg-primary hover:bg-primary-hover text-primary-foreground font-medium text-sm rounded-lg shadow-sm transition-all flex items-center justify-center gap-2"
|
className="col-span-2 py-2.5 bg-primary hover:bg-primary-hover text-primary-foreground font-medium text-sm rounded-lg shadow-sm transition-all flex items-center justify-center gap-2"
|
||||||
onClick={() => toast({ title: 'Compliance', description: 'Opening compliance manager...' })}
|
onClick={() => toast.info('Compliance', { description: 'Opening compliance manager...' })}
|
||||||
>
|
>
|
||||||
<ShieldCheck className="w-4 h-4" /> Manage Compliance
|
<ShieldCheck className="w-4 h-4" /> Manage Compliance
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue