Migrate all kitchen frontend fetch calls to /kitchen/api/ prefix (B5b)
All archive components were calling fetch('/api/...') directly. Replaced
all occurrences of /api/ URLs (string literals, template literals,
window.open, src attributes) with /kitchen/api/ across 37 source files.
The central axios instance in api.ts was already correct.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ecd63fc65f
commit
9905d0e0dd
51 changed files with 453 additions and 453 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
// Central axios instance for new/migrated code.
|
// Central axios instance for new/migrated code.
|
||||||
// Existing archive components still call fetch('/api/...') directly —
|
// Existing archive components still call fetch('/kitchen/api/...') directly —
|
||||||
// see port log B5 for the migration tracker.
|
// see port log B5 for the migration tracker.
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: '/kitchen/api',
|
baseURL: '/kitchen/api',
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ export default function AllowancesReport() {
|
||||||
const { data: summary, isLoading, error } = useQuery<AllowancesSummaryResponse>({
|
const { data: summary, isLoading, error } = useQuery<AllowancesSummaryResponse>({
|
||||||
queryKey: ['allowances-summary', submittedFromDate, submittedToDate],
|
queryKey: ['allowances-summary', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/allowances/summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/allowances/summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch allowances summary')
|
if (!res.ok) throw new Error('Failed to fetch allowances summary')
|
||||||
|
|
@ -268,7 +268,7 @@ export default function AllowancesReport() {
|
||||||
const { data: chartData } = useQuery<DailyAllowanceChartResponse>({
|
const { data: chartData } = useQuery<DailyAllowanceChartResponse>({
|
||||||
queryKey: ['allowances-daily', submittedFromDate, submittedToDate],
|
queryKey: ['allowances-daily', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/allowances/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/allowances/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch chart data')
|
if (!res.ok) throw new Error('Failed to fetch chart data')
|
||||||
|
|
@ -282,7 +282,7 @@ export default function AllowancesReport() {
|
||||||
const { data: disputes } = useQuery<DisputesSummaryResponse>({
|
const { data: disputes } = useQuery<DisputesSummaryResponse>({
|
||||||
queryKey: ['disputes-period-summary', submittedFromDate, submittedToDate],
|
queryKey: ['disputes-period-summary', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/disputes/period-summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/disputes/period-summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch disputes summary')
|
if (!res.ok) throw new Error('Failed to fetch disputes summary')
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ export default function Budget() {
|
||||||
const { data: budgetData, isLoading, error, refetch } = useQuery<WeeklyBudgetResponse>({
|
const { data: budgetData, isLoading, error, refetch } = useQuery<WeeklyBudgetResponse>({
|
||||||
queryKey: ['budget', 'weekly', weekOffset],
|
queryKey: ['budget', 'weekly', weekOffset],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/budget/weekly?week_offset=${weekOffset}`, {
|
const res = await fetch(`/kitchen/api/budget/weekly?week_offset=${weekOffset}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch budget data')
|
if (!res.ok) throw new Error('Failed to fetch budget data')
|
||||||
|
|
@ -267,7 +267,7 @@ export default function Budget() {
|
||||||
const { data: prevWeek1 } = useQuery<WeeklyBudgetResponse>({
|
const { data: prevWeek1 } = useQuery<WeeklyBudgetResponse>({
|
||||||
queryKey: ['budget', 'weekly', weekOffset - 1],
|
queryKey: ['budget', 'weekly', weekOffset - 1],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/budget/weekly?week_offset=${weekOffset - 1}`, {
|
const res = await fetch(`/kitchen/api/budget/weekly?week_offset=${weekOffset - 1}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return null
|
if (!res.ok) return null
|
||||||
|
|
@ -278,7 +278,7 @@ export default function Budget() {
|
||||||
const { data: prevWeek2 } = useQuery<WeeklyBudgetResponse>({
|
const { data: prevWeek2 } = useQuery<WeeklyBudgetResponse>({
|
||||||
queryKey: ['budget', 'weekly', weekOffset - 2],
|
queryKey: ['budget', 'weekly', weekOffset - 2],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/budget/weekly?week_offset=${weekOffset - 2}`, {
|
const res = await fetch(`/kitchen/api/budget/weekly?week_offset=${weekOffset - 2}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return null
|
if (!res.ok) return null
|
||||||
|
|
@ -298,7 +298,7 @@ export default function Budget() {
|
||||||
const { data: overrideData, refetch: refetchOverrides, isLoading: isOverrideLoading } = useQuery<WeeklyOverrideResponse>({
|
const { data: overrideData, refetch: refetchOverrides, isLoading: isOverrideLoading } = useQuery<WeeklyOverrideResponse>({
|
||||||
queryKey: ['cover-overrides', 'weekly', weekOffset],
|
queryKey: ['cover-overrides', 'weekly', weekOffset],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/cover-overrides/weekly?week_offset=${weekOffset}`, {
|
const res = await fetch(`/kitchen/api/cover-overrides/weekly?week_offset=${weekOffset}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch override data')
|
if (!res.ok) throw new Error('Failed to fetch override data')
|
||||||
|
|
@ -312,7 +312,7 @@ export default function Budget() {
|
||||||
queryKey: ['cost-distributions', 'weekly', weekOffset, budgetData?.week_start, budgetData?.week_end],
|
queryKey: ['cost-distributions', 'weekly', weekOffset, budgetData?.week_start, budgetData?.week_end],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`/api/cost-distributions/weekly?week_start=${budgetData!.week_start}&week_end=${budgetData!.week_end}`,
|
`/kitchen/api/cost-distributions/weekly?week_start=${budgetData!.week_start}&week_end=${budgetData!.week_end}`,
|
||||||
{ headers: { Authorization: `Bearer ${token}` } }
|
{ headers: { Authorization: `Bearer ${token}` } }
|
||||||
)
|
)
|
||||||
if (!res.ok) throw new Error('Failed to fetch distribution data')
|
if (!res.ok) throw new Error('Failed to fetch distribution data')
|
||||||
|
|
@ -335,7 +335,7 @@ export default function Budget() {
|
||||||
queryKey: ['resos', 'resident-covers', budgetData?.week_start, budgetData?.week_end],
|
queryKey: ['resos', 'resident-covers', budgetData?.week_start, budgetData?.week_end],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`/api/resos/resident-covers?start_date=${budgetData!.week_start}&end_date=${budgetData!.week_end}`,
|
`/kitchen/api/resos/resident-covers?start_date=${budgetData!.week_start}&end_date=${budgetData!.week_end}`,
|
||||||
{ headers: { Authorization: `Bearer ${token}` } }
|
{ headers: { Authorization: `Bearer ${token}` } }
|
||||||
)
|
)
|
||||||
if (!res.ok) return {}
|
if (!res.ok) return {}
|
||||||
|
|
@ -347,7 +347,7 @@ export default function Budget() {
|
||||||
|
|
||||||
const snapshotMutation = useMutation({
|
const snapshotMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/cover-overrides/snapshot', {
|
const res = await fetch('/kitchen/api/cover-overrides/snapshot', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ week_offset: weekOffset }),
|
body: JSON.stringify({ week_offset: weekOffset }),
|
||||||
|
|
@ -383,7 +383,7 @@ export default function Budget() {
|
||||||
try {
|
try {
|
||||||
await Promise.all(Object.entries(pendingOverrides).map(([key, value]) => {
|
await Promise.all(Object.entries(pendingOverrides).map(([key, value]) => {
|
||||||
const [overrideDate, period] = key.split('|')
|
const [overrideDate, period] = key.split('|')
|
||||||
return fetch('/api/cover-overrides', {
|
return fetch('/kitchen/api/cover-overrides', {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ override_date: overrideDate, period, override_covers: value }),
|
body: JSON.stringify({ override_date: overrideDate, period, override_covers: value }),
|
||||||
|
|
@ -398,7 +398,7 @@ export default function Budget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteOverride = async (id: number) => {
|
const deleteOverride = async (id: number) => {
|
||||||
await fetch(`/api/cover-overrides/${id}`, {
|
await fetch(`/kitchen/api/cover-overrides/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -407,7 +407,7 @@ export default function Budget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveSpendRate = async (period: string, food: number | null, drinks: number | null) => {
|
const saveSpendRate = async (period: string, food: number | null, drinks: number | null) => {
|
||||||
await fetch('/api/cover-overrides/spend-rates', {
|
await fetch('/kitchen/api/cover-overrides/spend-rates', {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ week_offset: weekOffset, period, food_spend: food, drinks_spend: drinks }),
|
body: JSON.stringify({ week_offset: weekOffset, period, food_spend: food, drinks_spend: drinks }),
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ export default function BulkAllergens() {
|
||||||
const { data: ingredients } = useQuery<IngredientItem[]>({
|
const { data: ingredients } = useQuery<IngredientItem[]>({
|
||||||
queryKey: ['ingredients-bulk'],
|
queryKey: ['ingredients-bulk'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients?limit=9999', {
|
const res = await fetch('/kitchen/api/ingredients?limit=9999', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch ingredients')
|
if (!res.ok) throw new Error('Failed to fetch ingredients')
|
||||||
|
|
@ -78,7 +78,7 @@ export default function BulkAllergens() {
|
||||||
const { data: categories } = useQuery<IngredientCategory[]>({
|
const { data: categories } = useQuery<IngredientCategory[]>({
|
||||||
queryKey: ['ingredient-categories'],
|
queryKey: ['ingredient-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients/categories', {
|
const res = await fetch('/kitchen/api/ingredients/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -91,7 +91,7 @@ export default function BulkAllergens() {
|
||||||
const { data: flagCategories } = useQuery<FoodFlagCategoryItem[]>({
|
const { data: flagCategories } = useQuery<FoodFlagCategoryItem[]>({
|
||||||
queryKey: ['food-flag-categories-full'],
|
queryKey: ['food-flag-categories-full'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
||||||
|
|
@ -104,7 +104,7 @@ export default function BulkAllergens() {
|
||||||
const { data: bulkNones } = useQuery<Record<number, number[]>>({
|
const { data: bulkNones } = useQuery<Record<number, number[]>>({
|
||||||
queryKey: ['bulk-nones'],
|
queryKey: ['bulk-nones'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients/bulk-nones', {
|
const res = await fetch('/kitchen/api/ingredients/bulk-nones', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return {}
|
if (!res.ok) return {}
|
||||||
|
|
@ -117,7 +117,7 @@ export default function BulkAllergens() {
|
||||||
const { data: allSuggestions } = useQuery<Record<number, AllergenSuggestion[]>>({
|
const { data: allSuggestions } = useQuery<Record<number, AllergenSuggestion[]>>({
|
||||||
queryKey: ['bulk-suggestions'],
|
queryKey: ['bulk-suggestions'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/suggest/bulk', {
|
const res = await fetch('/kitchen/api/food-flags/suggest/bulk', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return {}
|
if (!res.ok) return {}
|
||||||
|
|
@ -140,7 +140,7 @@ export default function BulkAllergens() {
|
||||||
newFlagIds = currentFlagIds.filter(id => id !== flagId)
|
newFlagIds = currentFlagIds.filter(id => id !== flagId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_ids: newFlagIds }),
|
body: JSON.stringify({ food_flag_ids: newFlagIds }),
|
||||||
|
|
@ -156,7 +156,7 @@ export default function BulkAllergens() {
|
||||||
// Toggle None for a category on an ingredient
|
// Toggle None for a category on an ingredient
|
||||||
const toggleNoneMutation = useMutation({
|
const toggleNoneMutation = useMutation({
|
||||||
mutationFn: async ({ ingredientId, categoryId }: { ingredientId: number; categoryId: number }) => {
|
mutationFn: async ({ ingredientId, categoryId }: { ingredientId: number; categoryId: number }) => {
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags/none`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/none`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ category_id: categoryId }),
|
body: JSON.stringify({ category_id: categoryId }),
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export default function BulkPublishModal({ menuId, divisionId, divisionName, onC
|
||||||
const { data: dishes } = useQuery<DishItem[]>({
|
const { data: dishes } = useQuery<DishItem[]>({
|
||||||
queryKey: ['dishes-for-bulk'],
|
queryKey: ['dishes-for-bulk'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes?recipe_type=dish', {
|
const res = await fetch('/kitchen/api/recipes?recipe_type=dish', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -46,7 +46,7 @@ export default function BulkPublishModal({ menuId, divisionId, divisionName, onC
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const results: Record<number, { ok: boolean; unassessed?: Array<{ name: string }> }> = {}
|
const results: Record<number, { ok: boolean; unassessed?: Array<{ name: string }> }> = {}
|
||||||
for (const rid of selected) {
|
for (const rid of selected) {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${rid}/flags`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${rid}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -76,7 +76,7 @@ export default function BulkPublishModal({ menuId, divisionId, divisionName, onC
|
||||||
price: editedPrices[id] ? parseFloat(editedPrices[id]) : (dish?.gross_sell_price || null),
|
price: editedPrices[id] ? parseFloat(editedPrices[id]) : (dish?.gross_sell_price || null),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/bulk`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/bulk`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
if (distributionId) {
|
if (distributionId) {
|
||||||
// Load existing distribution
|
// Load existing distribution
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
fetch(`/api/cost-distributions/${distributionId}`, {
|
fetch(`/kitchen/api/cost-distributions/${distributionId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
.then(r => { if (!r.ok) throw new Error('Failed to load distribution'); return r.json() })
|
.then(r => { if (!r.ok) throw new Error('Failed to load distribution'); return r.json() })
|
||||||
|
|
@ -136,7 +136,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
} else if (invoiceId) {
|
} else if (invoiceId) {
|
||||||
// Load invoice availability
|
// Load invoice availability
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
fetch(`/api/cost-distributions/invoice/${invoiceId}/availability`, {
|
fetch(`/kitchen/api/cost-distributions/invoice/${invoiceId}/availability`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
.then(r => { if (!r.ok) throw new Error('Failed to load invoice data'); return r.json() })
|
.then(r => { if (!r.ok) throw new Error('Failed to load invoice data'); return r.json() })
|
||||||
|
|
@ -276,7 +276,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
body.start_date = startDate
|
body.start_date = startDate
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch('/api/cost-distributions/', {
|
const res = await fetch('/kitchen/api/cost-distributions/', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
|
@ -300,7 +300,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
if (!token || !distributionId) return
|
if (!token || !distributionId) return
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/cost-distributions/${distributionId}`, {
|
const res = await fetch(`/kitchen/api/cost-distributions/${distributionId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ notes }),
|
body: JSON.stringify({ notes }),
|
||||||
|
|
@ -320,7 +320,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
if (!confirm('Are you sure you want to cancel this distribution? This will remove all scheduled entries.')) return
|
if (!confirm('Are you sure you want to cancel this distribution? This will remove all scheduled entries.')) return
|
||||||
setDeleting(true)
|
setDeleting(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/cost-distributions/${distributionId}`, {
|
const res = await fetch(`/kitchen/api/cost-distributions/${distributionId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -343,7 +343,7 @@ export default function CostDistributionModal({ isOpen, onClose, onSaved, invoic
|
||||||
try {
|
try {
|
||||||
const body: any = { entry_date: settleDate }
|
const body: any = { entry_date: settleDate }
|
||||||
if (!settleAll && settleAmount) body.amount = parseFloat(settleAmount)
|
if (!settleAll && settleAmount) body.amount = parseFloat(settleAmount)
|
||||||
const res = await fetch(`/api/cost-distributions/${distributionId}/settle-early`, {
|
const res = await fetch(`/kitchen/api/cost-distributions/${distributionId}/settle-early`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ export default function CreateDisputeModal({
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: CreateDisputeRequest) => {
|
mutationFn: async (data: CreateDisputeRequest) => {
|
||||||
const res = await fetch('/api/disputes', {
|
const res = await fetch('/kitchen/api/disputes', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ export default function Dashboard() {
|
||||||
const { data: resosSettings } = useQuery<ResosSettings>({
|
const { data: resosSettings } = useQuery<ResosSettings>({
|
||||||
queryKey: ['resos-settings'],
|
queryKey: ['resos-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/resos/settings', {
|
const res = await fetch('/kitchen/api/resos/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch Resos settings')
|
if (!res.ok) throw new Error('Failed to fetch Resos settings')
|
||||||
|
|
@ -148,7 +148,7 @@ export default function Dashboard() {
|
||||||
const { data, isLoading, error } = useQuery<DashboardData>({
|
const { data, isLoading, error } = useQuery<DashboardData>({
|
||||||
queryKey: ['dashboard'],
|
queryKey: ['dashboard'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/reports/dashboard', {
|
const res = await fetch('/kitchen/api/reports/dashboard', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dashboard')
|
if (!res.ok) throw new Error('Failed to fetch dashboard')
|
||||||
|
|
@ -159,7 +159,7 @@ export default function Dashboard() {
|
||||||
const { data: resosCovers } = useQuery<ResosCoversData>({
|
const { data: resosCovers } = useQuery<ResosCoversData>({
|
||||||
queryKey: ['resos-dashboard-covers'],
|
queryKey: ['resos-dashboard-covers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/resos/dashboard/today-tomorrow', {
|
const res = await fetch('/kitchen/api/resos/dashboard/today-tomorrow', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch Resos covers')
|
if (!res.ok) throw new Error('Failed to fetch Resos covers')
|
||||||
|
|
@ -172,7 +172,7 @@ export default function Dashboard() {
|
||||||
const { data: arrivalStats } = useQuery<ArrivalDashboardData>({
|
const { data: arrivalStats } = useQuery<ArrivalDashboardData>({
|
||||||
queryKey: ['newbook-arrival-stats'],
|
queryKey: ['newbook-arrival-stats'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/newbook/dashboard/arrivals?days=3', {
|
const res = await fetch('/kitchen/api/newbook/dashboard/arrivals?days=3', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch arrival stats')
|
if (!res.ok) throw new Error('Failed to fetch arrival stats')
|
||||||
|
|
@ -193,7 +193,7 @@ export default function Dashboard() {
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['upcoming-events'],
|
queryKey: ['upcoming-events'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/calendar-events/dashboard/upcoming', {
|
const res = await fetch('/kitchen/api/calendar-events/dashboard/upcoming', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch upcoming events')
|
if (!res.ok) throw new Error('Failed to fetch upcoming events')
|
||||||
|
|
@ -217,7 +217,7 @@ export default function Dashboard() {
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['recipe-dashboard-stats'],
|
queryKey: ['recipe-dashboard-stats'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/dashboard-stats', {
|
const res = await fetch('/kitchen/api/recipes/dashboard-stats', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch recipe stats')
|
if (!res.ok) throw new Error('Failed to fetch recipe stats')
|
||||||
|
|
@ -230,7 +230,7 @@ export default function Dashboard() {
|
||||||
const { data: disputeStats } = useQuery<DisputeStats>({
|
const { data: disputeStats } = useQuery<DisputeStats>({
|
||||||
queryKey: ['dispute-stats'],
|
queryKey: ['dispute-stats'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/disputes/stats/summary', {
|
const res = await fetch('/kitchen/api/disputes/stats/summary', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dispute stats')
|
if (!res.ok) throw new Error('Failed to fetch dispute stats')
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ export default function DishEditor() {
|
||||||
const { data: recipe } = useQuery<RecipeDetail>({
|
const { data: recipe } = useQuery<RecipeDetail>({
|
||||||
queryKey: ['recipe', recipeId],
|
queryKey: ['recipe', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Not found')
|
if (!res.ok) throw new Error('Not found')
|
||||||
|
|
@ -301,7 +301,7 @@ export default function DishEditor() {
|
||||||
const { data: sections } = useQuery<MenuSection[]>({
|
const { data: sections } = useQuery<MenuSection[]>({
|
||||||
queryKey: ['dish-courses'],
|
queryKey: ['dish-courses'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=dish', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=dish', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -313,7 +313,7 @@ export default function DishEditor() {
|
||||||
const { data: costData } = useQuery<CostData>({
|
const { data: costData } = useQuery<CostData>({
|
||||||
queryKey: ['recipe-cost', recipeId],
|
queryKey: ['recipe-cost', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/costing`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/costing`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -325,7 +325,7 @@ export default function DishEditor() {
|
||||||
const { data: scaledCostData } = useQuery<CostData>({
|
const { data: scaledCostData } = useQuery<CostData>({
|
||||||
queryKey: ['recipe-cost-scaled', recipeId, scalePortions],
|
queryKey: ['recipe-cost-scaled', recipeId, scalePortions],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/costing?scale_to=${scalePortions}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/costing?scale_to=${scalePortions}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -337,7 +337,7 @@ export default function DishEditor() {
|
||||||
const { data: flagData } = useQuery<FlagState>({
|
const { data: flagData } = useQuery<FlagState>({
|
||||||
queryKey: ['recipe-flags', recipeId],
|
queryKey: ['recipe-flags', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/flags`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -349,7 +349,7 @@ export default function DishEditor() {
|
||||||
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; propagation_type: string; required: boolean }>>({
|
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; propagation_type: string; required: boolean }>>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -361,7 +361,7 @@ export default function DishEditor() {
|
||||||
const { data: changeLog } = useQuery<ChangeLogEntry[]>({
|
const { data: changeLog } = useQuery<ChangeLogEntry[]>({
|
||||||
queryKey: ['recipe-changelog', recipeId],
|
queryKey: ['recipe-changelog', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/change-log`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/change-log`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -373,7 +373,7 @@ export default function DishEditor() {
|
||||||
const { data: costTrendRaw } = useQuery<CostTrendResponse>({
|
const { data: costTrendRaw } = useQuery<CostTrendResponse>({
|
||||||
queryKey: ['recipe-cost-trend', recipeId],
|
queryKey: ['recipe-cost-trend', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/cost-trend`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/cost-trend`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
||||||
|
|
@ -386,7 +386,7 @@ export default function DishEditor() {
|
||||||
const { data: dishMenus } = useQuery<Array<{ menu_id: number; menu_name: string; is_active: boolean }>>({
|
const { data: dishMenus } = useQuery<Array<{ menu_id: number; menu_name: string; is_active: boolean }>>({
|
||||||
queryKey: ['dish-menus', recipeId],
|
queryKey: ['dish-menus', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/menus/dish/${recipeId}/menus`, {
|
const res = await fetch(`/kitchen/api/menus/dish/${recipeId}/menus`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -399,7 +399,7 @@ export default function DishEditor() {
|
||||||
const { data: editIngData } = useQuery<EditingIngredient>({
|
const { data: editIngData } = useQuery<EditingIngredient>({
|
||||||
queryKey: ['ingredient-edit', editIngId],
|
queryKey: ['ingredient-edit', editIngId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${editIngId}`, {
|
const res = await fetch(`/kitchen/api/ingredients/${editIngId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Not found')
|
if (!res.ok) throw new Error('Not found')
|
||||||
|
|
@ -425,7 +425,7 @@ export default function DishEditor() {
|
||||||
const { data: availableRecipes } = useQuery<Array<{ id: number; name: string; recipe_type: string; batch_portions: number; batch_output_type: string; batch_yield_qty: number | null; batch_yield_unit: string | null; output_unit: string }>>({
|
const { data: availableRecipes } = useQuery<Array<{ id: number; name: string; recipe_type: string; batch_portions: number; batch_output_type: string; batch_yield_qty: number | null; batch_yield_unit: string | null; output_unit: string }>>({
|
||||||
queryKey: ['recipes-list-for-sub'],
|
queryKey: ['recipes-list-for-sub'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes?recipe_type=component', {
|
const res = await fetch('/kitchen/api/recipes?recipe_type=component', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -438,7 +438,7 @@ export default function DishEditor() {
|
||||||
const { data: sambaposItems } = useQuery<SambaposMenuItem[]>({
|
const { data: sambaposItems } = useQuery<SambaposMenuItem[]>({
|
||||||
queryKey: ['sambapos-menu-items-portions'],
|
queryKey: ['sambapos-menu-items-portions'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/menu-items-with-portions', {
|
const res = await fetch('/kitchen/api/sambapos/menu-items-with-portions', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -467,7 +467,7 @@ export default function DishEditor() {
|
||||||
if (!ingSearch || ingSearch.length < 2 || !token) return
|
if (!ingSearch || ingSearch.length < 2 || !token) return
|
||||||
const timer = setTimeout(async () => {
|
const timer = setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/suggest?description=${encodeURIComponent(ingSearch)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/suggest?description=${encodeURIComponent(ingSearch)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -484,7 +484,7 @@ export default function DishEditor() {
|
||||||
// Mutations
|
// Mutations
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -502,7 +502,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const addIngMutation = useMutation({
|
const addIngMutation = useMutation({
|
||||||
mutationFn: async (data: { ingredient_id: number; quantity: number; unit?: string; notes?: string }) => {
|
mutationFn: async (data: { ingredient_id: number; quantity: number; unit?: string; notes?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/ingredients`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/ingredients`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -527,7 +527,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const updateIngMutation = useMutation({
|
const updateIngMutation = useMutation({
|
||||||
mutationFn: async ({ riId, quantity, unit, yield_percent, notes }: { riId: number; quantity?: number; unit?: string; yield_percent?: number; notes?: string }) => {
|
mutationFn: async ({ riId, quantity, unit, yield_percent, notes }: { riId: number; quantity?: number; unit?: string; yield_percent?: number; notes?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-ingredients/${riId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-ingredients/${riId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ quantity, unit, yield_percent, notes }),
|
body: JSON.stringify({ quantity, unit, yield_percent, notes }),
|
||||||
|
|
@ -545,7 +545,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const removeIngMutation = useMutation({
|
const removeIngMutation = useMutation({
|
||||||
mutationFn: async (riId: number) => {
|
mutationFn: async (riId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-ingredients/${riId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-ingredients/${riId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -562,7 +562,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const addSubMutation = useMutation({
|
const addSubMutation = useMutation({
|
||||||
mutationFn: async (data: { child_recipe_id: number; portions_needed: number; portions_needed_unit?: string }) => {
|
mutationFn: async (data: { child_recipe_id: number; portions_needed: number; portions_needed_unit?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/sub-recipes`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/sub-recipes`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -583,7 +583,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const removeSubMutation = useMutation({
|
const removeSubMutation = useMutation({
|
||||||
mutationFn: async (srId: number) => {
|
mutationFn: async (srId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-sub-recipes/${srId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-sub-recipes/${srId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -599,7 +599,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const addStepMutation = useMutation({
|
const addStepMutation = useMutation({
|
||||||
mutationFn: async (data: { title?: string; instruction: string; step_number: number; duration_minutes?: number }) => {
|
mutationFn: async (data: { title?: string; instruction: string; step_number: number; duration_minutes?: number }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/steps`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/steps`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -617,7 +617,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const updateStepMutation = useMutation({
|
const updateStepMutation = useMutation({
|
||||||
mutationFn: async ({ stepId, data }: { stepId: number; data: { title?: string; instruction?: string; duration_minutes?: number } }) => {
|
mutationFn: async ({ stepId, data }: { stepId: number; data: { title?: string; instruction?: string; duration_minutes?: number } }) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-steps/${stepId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-steps/${stepId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -636,7 +636,7 @@ export default function DishEditor() {
|
||||||
|
|
||||||
const removeStepMutation = useMutation({
|
const removeStepMutation = useMutation({
|
||||||
mutationFn: async (stepId: number) => {
|
mutationFn: async (stepId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-steps/${stepId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-steps/${stepId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -652,7 +652,7 @@ export default function DishEditor() {
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
formData.append('caption', caption)
|
formData.append('caption', caption)
|
||||||
formData.append('image_type', image_type)
|
formData.append('image_type', image_type)
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/images`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/images`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -670,7 +670,7 @@ export default function DishEditor() {
|
||||||
// Delete image mutation
|
// Delete image mutation
|
||||||
const deleteImageMutation = useMutation({
|
const deleteImageMutation = useMutation({
|
||||||
mutationFn: async (imageId: number) => {
|
mutationFn: async (imageId: number) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/images/${imageId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/images/${imageId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -684,7 +684,7 @@ export default function DishEditor() {
|
||||||
// Batch reorder ingredients
|
// Batch reorder ingredients
|
||||||
const reorderIngMutation = useMutation({
|
const reorderIngMutation = useMutation({
|
||||||
mutationFn: async (ingredientIds: number[]) => {
|
mutationFn: async (ingredientIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/ingredients/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/ingredients/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ingredient_ids: ingredientIds }),
|
body: JSON.stringify({ ingredient_ids: ingredientIds }),
|
||||||
|
|
@ -699,7 +699,7 @@ export default function DishEditor() {
|
||||||
// Batch reorder sub-recipes
|
// Batch reorder sub-recipes
|
||||||
const reorderSubMutation = useMutation({
|
const reorderSubMutation = useMutation({
|
||||||
mutationFn: async (subRecipeIds: number[]) => {
|
mutationFn: async (subRecipeIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/sub-recipes/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/sub-recipes/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ sub_recipe_ids: subRecipeIds }),
|
body: JSON.stringify({ sub_recipe_ids: subRecipeIds }),
|
||||||
|
|
@ -714,7 +714,7 @@ export default function DishEditor() {
|
||||||
// Reorder steps mutation
|
// Reorder steps mutation
|
||||||
const reorderStepsMutation = useMutation({
|
const reorderStepsMutation = useMutation({
|
||||||
mutationFn: async (stepIds: number[]) => {
|
mutationFn: async (stepIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/steps/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/steps/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ step_ids: stepIds }),
|
body: JSON.stringify({ step_ids: stepIds }),
|
||||||
|
|
@ -799,7 +799,7 @@ export default function DishEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePrint = (format: string) => {
|
const handlePrint = (format: string) => {
|
||||||
window.open(`/api/recipes/${recipeId}/print?format=${format}&token=${token}`, '_blank')
|
window.open(`/kitchen/api/recipes/${recipeId}/print?format=${format}&token=${token}`, '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recipe) return <div style={styles.loading}>Loading dish...</div>
|
if (!recipe) return <div style={styles.loading}>Loading dish...</div>
|
||||||
|
|
@ -929,7 +929,7 @@ export default function DishEditor() {
|
||||||
style={{ marginLeft: 'auto', background: 'none', border: '1px solid #b4530955', borderRadius: '4px', color: '#b45309', cursor: 'pointer', padding: '0.15rem 0.5rem', fontSize: '0.8rem', whiteSpace: 'nowrap' }}
|
style={{ marginLeft: 'auto', background: 'none', border: '1px solid #b4530955', borderRadius: '4px', color: '#b45309', cursor: 'pointer', padding: '0.15rem 0.5rem', fontSize: '0.8rem', whiteSpace: 'nowrap' }}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/text-dismissals`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/text-dismissals`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
@ -1345,10 +1345,10 @@ export default function DishEditor() {
|
||||||
{recipe.images.map(img => (
|
{recipe.images.map(img => (
|
||||||
<div key={img.id} style={styles.imageCard}>
|
<div key={img.id} style={styles.imageCard}>
|
||||||
<img
|
<img
|
||||||
src={`/api/recipes/${recipeId}/images/${img.id}?token=${token}`}
|
src={`/kitchen/api/recipes/${recipeId}/images/${img.id}?token=${token}`}
|
||||||
alt={img.caption || 'Dish image'}
|
alt={img.caption || 'Dish image'}
|
||||||
style={{ ...styles.imageThumb, cursor: 'pointer' }}
|
style={{ ...styles.imageThumb, cursor: 'pointer' }}
|
||||||
onClick={() => setLightboxImg(`/api/recipes/${recipeId}/images/${img.id}?token=${token}`)}
|
onClick={() => setLightboxImg(`/kitchen/api/recipes/${recipeId}/images/${img.id}?token=${token}`)}
|
||||||
/>
|
/>
|
||||||
<div style={{ padding: '0.4rem' }}>
|
<div style={{ padding: '0.4rem' }}>
|
||||||
{img.caption && <div style={{ fontSize: '0.8rem', color: '#333', marginTop: '2px' }}>{img.caption}</div>}
|
{img.caption && <div style={{ fontSize: '0.8rem', color: '#333', marginTop: '2px' }}>{img.caption}</div>}
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ export default function DishList() {
|
||||||
const { data: sections } = useQuery<MenuSection[]>({
|
const { data: sections } = useQuery<MenuSection[]>({
|
||||||
queryKey: ['dish-courses'],
|
queryKey: ['dish-courses'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=dish', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=dish', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch sections')
|
if (!res.ok) throw new Error('Failed to fetch sections')
|
||||||
|
|
@ -137,7 +137,7 @@ export default function DishList() {
|
||||||
params.set('recipe_type', 'dish')
|
params.set('recipe_type', 'dish')
|
||||||
if (sectionFilter) params.set('menu_section_id', sectionFilter)
|
if (sectionFilter) params.set('menu_section_id', sectionFilter)
|
||||||
if (showArchived) params.set('archived', 'true')
|
if (showArchived) params.set('archived', 'true')
|
||||||
const res = await fetch(`/api/recipes?${params}`, {
|
const res = await fetch(`/kitchen/api/recipes?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dishes')
|
if (!res.ok) throw new Error('Failed to fetch dishes')
|
||||||
|
|
@ -150,7 +150,7 @@ export default function DishList() {
|
||||||
const { data: impactData } = useQuery<{ days: number; recipes: ImpactItem[] }>({
|
const { data: impactData } = useQuery<{ days: number; recipes: ImpactItem[] }>({
|
||||||
queryKey: ['price-impact-dishes', costChangeDays],
|
queryKey: ['price-impact-dishes', costChangeDays],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/price-impact?days=${costChangeDays}`, {
|
const res = await fetch(`/kitchen/api/recipes/price-impact?days=${costChangeDays}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch price impact')
|
if (!res.ok) throw new Error('Failed to fetch price impact')
|
||||||
|
|
@ -167,7 +167,7 @@ export default function DishList() {
|
||||||
const { data: costTrendRaw } = useQuery<{ snapshots: CostTrendSnapshot[] }>({
|
const { data: costTrendRaw } = useQuery<{ snapshots: CostTrendSnapshot[] }>({
|
||||||
queryKey: ['cost-trend', expandedCostId],
|
queryKey: ['cost-trend', expandedCostId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${expandedCostId}/cost-trend`, {
|
const res = await fetch(`/kitchen/api/recipes/${expandedCostId}/cost-trend`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
||||||
|
|
@ -178,7 +178,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/recipes', {
|
const res = await fetch('/kitchen/api/recipes', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -195,7 +195,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const duplicateMutation = useMutation({
|
const duplicateMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}/duplicate`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}/duplicate`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -210,7 +210,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const archiveMutation = useMutation({
|
const archiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -221,7 +221,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const unarchiveMutation = useMutation({
|
const unarchiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ is_archived: false }),
|
body: JSON.stringify({ is_archived: false }),
|
||||||
|
|
@ -233,7 +233,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const createSectionMutation = useMutation({
|
const createSectionMutation = useMutation({
|
||||||
mutationFn: async (name: string) => {
|
mutationFn: async (name: string) => {
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'dish' }),
|
body: JSON.stringify({ name, section_type: 'dish' }),
|
||||||
|
|
@ -250,7 +250,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const updateSectionMutation = useMutation({
|
const updateSectionMutation = useMutation({
|
||||||
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
|
|
@ -268,7 +268,7 @@ export default function DishList() {
|
||||||
|
|
||||||
const deleteSectionMutation = useMutation({
|
const deleteSectionMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -284,7 +284,7 @@ export default function DishList() {
|
||||||
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; flags: Array<{ id: number; name: string; code: string | null }> }>>({
|
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; flags: Array<{ id: number; name: string; code: string | null }> }>>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
const { data: settings } = useQuery<{ llm_enabled?: boolean; anthropic_api_key_set?: boolean }>({
|
const { data: settings } = useQuery<{ llm_enabled?: boolean; anthropic_api_key_set?: boolean }>({
|
||||||
queryKey: ['settings'],
|
queryKey: ['settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings', { headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch('/kitchen/api/settings', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (!res.ok) return {}
|
if (!res.ok) return {}
|
||||||
return res.json()
|
return res.json()
|
||||||
},
|
},
|
||||||
|
|
@ -136,7 +136,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
const { data: dispute, isLoading, error } = useQuery<DisputeDetail>({
|
const { data: dispute, isLoading, error } = useQuery<DisputeDetail>({
|
||||||
queryKey: ['dispute', disputeId],
|
queryKey: ['dispute', disputeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/disputes/${disputeId}`, {
|
const res = await fetch(`/kitchen/api/disputes/${disputeId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dispute')
|
if (!res.ok) throw new Error('Failed to fetch dispute')
|
||||||
|
|
@ -147,7 +147,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: { status?: string; priority?: string; supplier_response?: string; supplier_contact_name?: string; title?: string; description?: string }) => {
|
mutationFn: async (data: { status?: string; priority?: string; supplier_response?: string; supplier_contact_name?: string; title?: string; description?: string }) => {
|
||||||
const res = await fetch(`/api/disputes/${disputeId}`, {
|
const res = await fetch(`/kitchen/api/disputes/${disputeId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -172,7 +172,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch(`/api/disputes/${disputeId}`, {
|
const res = await fetch(`/kitchen/api/disputes/${disputeId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -251,7 +251,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
setAiEmailSubject('')
|
setAiEmailSubject('')
|
||||||
setAiEmailBody('')
|
setAiEmailBody('')
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/disputes/${disputeId}/draft-email`, {
|
const res = await fetch(`/kitchen/api/disputes/${disputeId}/draft-email`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -290,7 +290,7 @@ export default function DisputeDetailModal({ disputeId, onClose, onUpdate }: Dis
|
||||||
params.append('description', uploadDescription.trim())
|
params.append('description', uploadDescription.trim())
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`/api/disputes/${disputeId}/attachments?${params}`, {
|
const res = await fetch(`/kitchen/api/disputes/${disputeId}/attachments?${params}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ export default function Disputes() {
|
||||||
const { data: suppliersData } = useQuery<{ suppliers: Array<{ id: number; name: string }> }>({
|
const { data: suppliersData } = useQuery<{ suppliers: Array<{ id: number; name: string }> }>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -83,7 +83,7 @@ export default function Disputes() {
|
||||||
const { data, isLoading, error } = useQuery<DisputeListResponse>({
|
const { data, isLoading, error } = useQuery<DisputeListResponse>({
|
||||||
queryKey: ['disputes', statusFilter, priorityFilter, supplierFilter, dateFilter],
|
queryKey: ['disputes', statusFilter, priorityFilter, supplierFilter, dateFilter],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const url = queryString ? `/api/disputes?${queryString}` : '/api/disputes'
|
const url = queryString ? `/kitchen/api/disputes?${queryString}` : '/kitchen/api/disputes'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ export default function EventOrderEditor() {
|
||||||
const { data: order } = useQuery<EventOrderDetail>({
|
const { data: order } = useQuery<EventOrderDetail>({
|
||||||
queryKey: ['event-order', orderId],
|
queryKey: ['event-order', orderId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/event-orders/${orderId}`, {
|
const res = await fetch(`/kitchen/api/event-orders/${orderId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Not found')
|
if (!res.ok) throw new Error('Not found')
|
||||||
|
|
@ -142,7 +142,7 @@ export default function EventOrderEditor() {
|
||||||
const { data: recipes } = useQuery<RecipeOption[]>({
|
const { data: recipes } = useQuery<RecipeOption[]>({
|
||||||
queryKey: ['recipes-for-event', recipeType],
|
queryKey: ['recipes-for-event', recipeType],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes?recipe_type=${recipeType}`, {
|
const res = await fetch(`/kitchen/api/recipes?recipe_type=${recipeType}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -155,7 +155,7 @@ export default function EventOrderEditor() {
|
||||||
const { data: menus } = useQuery<MenuOption[]>({
|
const { data: menus } = useQuery<MenuOption[]>({
|
||||||
queryKey: ['menus-for-event'],
|
queryKey: ['menus-for-event'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/menus', {
|
const res = await fetch('/kitchen/api/menus', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -168,7 +168,7 @@ export default function EventOrderEditor() {
|
||||||
const { data: menuDetail } = useQuery<MenuDetail>({
|
const { data: menuDetail } = useQuery<MenuDetail>({
|
||||||
queryKey: ['menu-detail-for-event', selectedMenuId],
|
queryKey: ['menu-detail-for-event', selectedMenuId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/menus/${selectedMenuId}`, {
|
const res = await fetch(`/kitchen/api/menus/${selectedMenuId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -181,7 +181,7 @@ export default function EventOrderEditor() {
|
||||||
queryKey: ['event-shopping-list', orderId, groupBySupplier],
|
queryKey: ['event-shopping-list', orderId, groupBySupplier],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const params = groupBySupplier ? '?group_by_supplier=true' : ''
|
const params = groupBySupplier ? '?group_by_supplier=true' : ''
|
||||||
const res = await fetch(`/api/event-orders/${orderId}/shopping-list${params}`, {
|
const res = await fetch(`/kitchen/api/event-orders/${orderId}/shopping-list${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -191,7 +191,7 @@ export default function EventOrderEditor() {
|
||||||
|
|
||||||
const addItemMutation = useMutation({
|
const addItemMutation = useMutation({
|
||||||
mutationFn: async (data: { recipe_id: number; quantity: number }) => {
|
mutationFn: async (data: { recipe_id: number; quantity: number }) => {
|
||||||
const res = await fetch(`/api/event-orders/${orderId}/items`, {
|
const res = await fetch(`/kitchen/api/event-orders/${orderId}/items`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -207,7 +207,7 @@ export default function EventOrderEditor() {
|
||||||
|
|
||||||
const bulkAddMutation = useMutation({
|
const bulkAddMutation = useMutation({
|
||||||
mutationFn: async (items: Array<{ recipe_id: number; quantity: number; notes?: string }>) => {
|
mutationFn: async (items: Array<{ recipe_id: number; quantity: number; notes?: string }>) => {
|
||||||
const res = await fetch(`/api/event-orders/${orderId}/items/bulk`, {
|
const res = await fetch(`/kitchen/api/event-orders/${orderId}/items/bulk`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ items }),
|
body: JSON.stringify({ items }),
|
||||||
|
|
@ -224,7 +224,7 @@ export default function EventOrderEditor() {
|
||||||
|
|
||||||
const removeItemMutation = useMutation({
|
const removeItemMutation = useMutation({
|
||||||
mutationFn: async (itemId: number) => {
|
mutationFn: async (itemId: number) => {
|
||||||
const res = await fetch(`/api/event-orders/items/${itemId}`, {
|
const res = await fetch(`/kitchen/api/event-orders/items/${itemId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -238,7 +238,7 @@ export default function EventOrderEditor() {
|
||||||
|
|
||||||
const updateStatusMutation = useMutation({
|
const updateStatusMutation = useMutation({
|
||||||
mutationFn: async (status: string) => {
|
mutationFn: async (status: string) => {
|
||||||
const res = await fetch(`/api/event-orders/${orderId}`, {
|
const res = await fetch(`/kitchen/api/event-orders/${orderId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ status }),
|
body: JSON.stringify({ status }),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export default function EventOrders() {
|
||||||
const { data: orders, isLoading } = useQuery<EventOrderItem[]>({
|
const { data: orders, isLoading } = useQuery<EventOrderItem[]>({
|
||||||
queryKey: ['event-orders'],
|
queryKey: ['event-orders'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/event-orders', {
|
const res = await fetch('/kitchen/api/event-orders', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -39,7 +39,7 @@ export default function EventOrders() {
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: { name: string; event_date?: string; notes?: string }) => {
|
mutationFn: async (data: { name: string; event_date?: string; notes?: string }) => {
|
||||||
const res = await fetch('/api/event-orders', {
|
const res = await fetch('/kitchen/api/event-orders', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -56,7 +56,7 @@ export default function EventOrders() {
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/event-orders/${id}`, {
|
const res = await fetch(`/kitchen/api/event-orders/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ export default function GPReport() {
|
||||||
const { data, isLoading, error } = useQuery<DateRangeGPResponse>({
|
const { data, isLoading, error } = useQuery<DateRangeGPResponse>({
|
||||||
queryKey: ['gp-range', submittedFromDate, submittedToDate],
|
queryKey: ['gp-range', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/gp/range?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/gp/range?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch GP data')
|
if (!res.ok) throw new Error('Failed to fetch GP data')
|
||||||
|
|
@ -331,7 +331,7 @@ export default function GPReport() {
|
||||||
const { data: chartData } = useQuery<DailyChartData>({
|
const { data: chartData } = useQuery<DailyChartData>({
|
||||||
queryKey: ['gp-daily', submittedFromDate, submittedToDate],
|
queryKey: ['gp-daily', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/gp/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/gp/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch chart data')
|
if (!res.ok) throw new Error('Failed to fetch chart data')
|
||||||
|
|
@ -345,7 +345,7 @@ export default function GPReport() {
|
||||||
const { data: topSellers, isLoading: topSellersLoading } = useQuery<TopSellersResponse>({
|
const { data: topSellers, isLoading: topSellersLoading } = useQuery<TopSellersResponse>({
|
||||||
queryKey: ['gp-top-sellers', submittedFromDate, submittedToDate],
|
queryKey: ['gp-top-sellers', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/gp/top-sellers?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/gp/top-sellers?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
const { data: categories } = useQuery<FlagCategory[]>({
|
const { data: categories } = useQuery<FlagCategory[]>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -96,7 +96,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
const { data: currentFlags } = useQuery<IngredientFlagInfo[]>({
|
const { data: currentFlags } = useQuery<IngredientFlagInfo[]>({
|
||||||
queryKey: ['ingredient-flags', ingredientId],
|
queryKey: ['ingredient-flags', ingredientId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -109,7 +109,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
const { data: currentNones } = useQuery<{ none_category_ids: number[] }>({
|
const { data: currentNones } = useQuery<{ none_category_ids: number[] }>({
|
||||||
queryKey: ['ingredient-flag-nones', ingredientId],
|
queryKey: ['ingredient-flag-nones', ingredientId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags/nones`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/nones`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { none_category_ids: [] }
|
if (!res.ok) return { none_category_ids: [] }
|
||||||
|
|
@ -122,7 +122,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
const { data: currentDismissals } = useQuery<DismissalInfo[]>({
|
const { data: currentDismissals } = useQuery<DismissalInfo[]>({
|
||||||
queryKey: ['ingredient-flag-dismissals', ingredientId],
|
queryKey: ['ingredient-flag-dismissals', ingredientId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags/dismissals`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/dismissals`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -139,7 +139,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
if (debouncedName) params.set('name', debouncedName)
|
if (debouncedName) params.set('name', debouncedName)
|
||||||
if (debouncedLineItem) params.set('line_item', debouncedLineItem)
|
if (debouncedLineItem) params.set('line_item', debouncedLineItem)
|
||||||
if (debouncedText) params.set('text', debouncedText)
|
if (debouncedText) params.set('text', debouncedText)
|
||||||
const res = await fetch(`/api/food-flags/suggest?${params}`, {
|
const res = await fetch(`/kitchen/api/food-flags/suggest?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -216,7 +216,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
|
|
||||||
// For edit mode, persist to API
|
// For edit mode, persist to API
|
||||||
if (ingredientId) {
|
if (ingredientId) {
|
||||||
fetch(`/api/ingredients/${ingredientId}/flags`, {
|
fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
||||||
|
|
@ -253,7 +253,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
const catFlags = categories.find(c => c.id === catId)?.flags || []
|
const catFlags = categories.find(c => c.id === catId)?.flags || []
|
||||||
const hasActiveFlags = catFlags.some(f => newFlags.has(f.id))
|
const hasActiveFlags = catFlags.some(f => newFlags.has(f.id))
|
||||||
if (!hasActiveFlags) {
|
if (!hasActiveFlags) {
|
||||||
fetch(`/api/ingredients/${ingredientId}/flags/none`, {
|
fetch(`/kitchen/api/ingredients/${ingredientId}/flags/none`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ category_id: catId }),
|
body: JSON.stringify({ category_id: catId }),
|
||||||
|
|
@ -325,7 +325,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
if (ingredientId) {
|
if (ingredientId) {
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
||||||
|
|
@ -356,7 +356,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
if (ingredientId) {
|
if (ingredientId) {
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags/none`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/none`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ category_id: categoryId }),
|
body: JSON.stringify({ category_id: categoryId }),
|
||||||
|
|
@ -393,7 +393,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
// Edit mode: persist immediately
|
// Edit mode: persist immediately
|
||||||
if (ingredientId) {
|
if (ingredientId) {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/${ingredientId}/flags/dismissals`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/dismissals`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(dismissal),
|
body: JSON.stringify(dismissal),
|
||||||
|
|
@ -421,7 +421,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
// Edit mode: delete from API
|
// Edit mode: delete from API
|
||||||
if (ingredientId && dismissal.id) {
|
if (ingredientId && dismissal.id) {
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags/dismissals/${dismissal.id}`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/dismissals/${dismissal.id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -452,7 +452,7 @@ export default function IngredientFlagEditor({ ingredientId, token, onChange, on
|
||||||
if (ingredientId) {
|
if (ingredientId) {
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
body: JSON.stringify({ food_flag_ids: [...newFlags] }),
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,11 @@ const SUPPLIER_LOOKUPS: SupplierLookup[] = [
|
||||||
namePattern: /brakes/i,
|
namePattern: /brakes/i,
|
||||||
label: 'Fetch Brakes',
|
label: 'Fetch Brakes',
|
||||||
color: '#f59e0b',
|
color: '#f59e0b',
|
||||||
endpoint: '/api/food-flags/brakes-lookup',
|
endpoint: '/kitchen/api/food-flags/brakes-lookup',
|
||||||
paramName: 'product_code',
|
paramName: 'product_code',
|
||||||
},
|
},
|
||||||
// To add another supplier, add an entry here:
|
// To add another supplier, add an entry here:
|
||||||
// { key: 'bidfood', namePattern: /bidfood/i, label: 'Fetch Bidfood', color: '#3b82f6', endpoint: '/api/food-flags/bidfood-lookup', paramName: 'product_code' },
|
// { key: 'bidfood', namePattern: /bidfood/i, label: 'Fetch Bidfood', color: '#3b82f6', endpoint: '/kitchen/api/food-flags/bidfood-lookup', paramName: 'product_code' },
|
||||||
]
|
]
|
||||||
|
|
||||||
function getSupplierLookup(supplierName: string | null | undefined): SupplierLookup | null {
|
function getSupplierLookup(supplierName: string | null | undefined): SupplierLookup | null {
|
||||||
|
|
@ -165,7 +165,7 @@ export default function IngredientModal({
|
||||||
const { data: categories } = useQuery<IngredientCategory[]>({
|
const { data: categories } = useQuery<IngredientCategory[]>({
|
||||||
queryKey: ['ingredient-categories'],
|
queryKey: ['ingredient-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients/categories', {
|
const res = await fetch('/kitchen/api/ingredients/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch categories')
|
if (!res.ok) throw new Error('Failed to fetch categories')
|
||||||
|
|
@ -177,7 +177,7 @@ export default function IngredientModal({
|
||||||
const { data: liSuppliers } = useQuery<Array<{ id: number; name: string }>>({
|
const { data: liSuppliers } = useQuery<Array<{ id: number; name: string }>>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch('/kitchen/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
return data.suppliers || data || []
|
return data.suppliers || data || []
|
||||||
|
|
@ -199,7 +199,7 @@ export default function IngredientModal({
|
||||||
}>>({
|
}>>({
|
||||||
queryKey: ['ingredient-sources', editingIngredient?.id],
|
queryKey: ['ingredient-sources', editingIngredient?.id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${editingIngredient!.id}/sources`, {
|
const res = await fetch(`/kitchen/api/ingredients/${editingIngredient!.id}/sources`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -216,7 +216,7 @@ export default function IngredientModal({
|
||||||
if (debouncedLiSearch) params.set('q', debouncedLiSearch)
|
if (debouncedLiSearch) params.set('q', debouncedLiSearch)
|
||||||
if (liSupplierId) params.set('supplier_id', liSupplierId)
|
if (liSupplierId) params.set('supplier_id', liSupplierId)
|
||||||
params.set('limit', '100')
|
params.set('limit', '100')
|
||||||
const res = await fetch(`/api/search/line-items?${params}`, {
|
const res = await fetch(`/kitchen/api/search/line-items?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { items: [], total_count: 0 }
|
if (!res.ok) return { items: [], total_count: 0 }
|
||||||
|
|
@ -230,7 +230,7 @@ export default function IngredientModal({
|
||||||
const { data: settingsData } = useQuery<{ llm_enabled: boolean }>({
|
const { data: settingsData } = useQuery<{ llm_enabled: boolean }>({
|
||||||
queryKey: ['settings-llm-check'],
|
queryKey: ['settings-llm-check'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { llm_enabled: false }
|
if (!res.ok) return { llm_enabled: false }
|
||||||
|
|
@ -252,7 +252,7 @@ export default function IngredientModal({
|
||||||
const runAnalysis = async () => {
|
const runAnalysis = async () => {
|
||||||
setLlmAnalysing(true)
|
setLlmAnalysing(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/food-flags/analyse-label', {
|
const res = await fetch('/kitchen/api/food-flags/analyse-label', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -294,7 +294,7 @@ export default function IngredientModal({
|
||||||
const fetchYield = async () => {
|
const fetchYield = async () => {
|
||||||
setYieldHintLoading(true)
|
setYieldHintLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/ai-estimate-yield?name=${encodeURIComponent(debouncedFormName.trim())}`, {
|
const res = await fetch(`/kitchen/api/ingredients/ai-estimate-yield?name=${encodeURIComponent(debouncedFormName.trim())}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok && !cancelled) {
|
if (res.ok && !cancelled) {
|
||||||
|
|
@ -434,8 +434,8 @@ export default function IngredientModal({
|
||||||
reader.onload = (e) => setLabelPreview(e.target?.result as string)
|
reader.onload = (e) => setLabelPreview(e.target?.result as string)
|
||||||
reader.readAsDataURL(file)
|
reader.readAsDataURL(file)
|
||||||
const url = editingIngredient
|
const url = editingIngredient
|
||||||
? `/api/food-flags/scan-label/${editingIngredient.id}`
|
? `/kitchen/api/food-flags/scan-label/${editingIngredient.id}`
|
||||||
: '/api/food-flags/scan-label'
|
: '/kitchen/api/food-flags/scan-label'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
|
@ -467,7 +467,7 @@ export default function IngredientModal({
|
||||||
}
|
}
|
||||||
if (selectedLi.most_recent_price) sourceData.latest_unit_price = selectedLi.most_recent_price
|
if (selectedLi.most_recent_price) sourceData.latest_unit_price = selectedLi.most_recent_price
|
||||||
if (selectedLi.most_recent_invoice_id) sourceData.invoice_id = selectedLi.most_recent_invoice_id
|
if (selectedLi.most_recent_invoice_id) sourceData.invoice_id = selectedLi.most_recent_invoice_id
|
||||||
const srcRes = await fetch(`/api/ingredients/${ingredientId}/sources`, {
|
const srcRes = await fetch(`/kitchen/api/ingredients/${ingredientId}/sources`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(sourceData),
|
body: JSON.stringify(sourceData),
|
||||||
|
|
@ -484,7 +484,7 @@ export default function IngredientModal({
|
||||||
const applyPendingFlags = async (ingredientId: number) => {
|
const applyPendingFlags = async (ingredientId: number) => {
|
||||||
if (pendingFlagIds.length > 0) {
|
if (pendingFlagIds.length > 0) {
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_ids: pendingFlagIds }),
|
body: JSON.stringify({ food_flag_ids: pendingFlagIds }),
|
||||||
|
|
@ -493,7 +493,7 @@ export default function IngredientModal({
|
||||||
}
|
}
|
||||||
for (const catId of pendingNoneCatIds) {
|
for (const catId of pendingNoneCatIds) {
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags/none`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/none`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ category_id: catId }),
|
body: JSON.stringify({ category_id: catId }),
|
||||||
|
|
@ -503,7 +503,7 @@ export default function IngredientModal({
|
||||||
// Batch persist dismissals from create mode
|
// Batch persist dismissals from create mode
|
||||||
if (pendingDismissals.length > 0) {
|
if (pendingDismissals.length > 0) {
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/ingredients/${ingredientId}/flags/dismissals/batch`, {
|
await fetch(`/kitchen/api/ingredients/${ingredientId}/flags/dismissals/batch`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ dismissals: pendingDismissals }),
|
body: JSON.stringify({ dismissals: pendingDismissals }),
|
||||||
|
|
@ -529,7 +529,7 @@ export default function IngredientModal({
|
||||||
setFormFree(editingIngredient.is_free || false)
|
setFormFree(editingIngredient.is_free || false)
|
||||||
setFormPrepackaged(editingIngredient.is_prepackaged || false)
|
setFormPrepackaged(editingIngredient.is_prepackaged || false)
|
||||||
setFormProductIngredients(editingIngredient.product_ingredients || '')
|
setFormProductIngredients(editingIngredient.product_ingredients || '')
|
||||||
setLabelPreview(editingIngredient.has_label_image ? `/api/ingredients/${editingIngredient.id}/label-image?token=${encodeURIComponent(token || '')}` : null)
|
setLabelPreview(editingIngredient.has_label_image ? `/kitchen/api/ingredients/${editingIngredient.id}/label-image?token=${encodeURIComponent(token || '')}` : null)
|
||||||
setLiSearch(editingIngredient.name)
|
setLiSearch(editingIngredient.name)
|
||||||
} else {
|
} else {
|
||||||
const name = prePopulateName || ''
|
const name = prePopulateName || ''
|
||||||
|
|
@ -550,7 +550,7 @@ export default function IngredientModal({
|
||||||
} else if (preSelectLineItem.description) {
|
} else if (preSelectLineItem.description) {
|
||||||
// LLM FEATURE — AI pack size deduction when regex can't parse
|
// LLM FEATURE — AI pack size deduction when regex can't parse
|
||||||
setAiPackLoading(true)
|
setAiPackLoading(true)
|
||||||
fetch(`/api/ingredients/ai-pack-size?description=${encodeURIComponent(preSelectLineItem.description)}`, {
|
fetch(`/kitchen/api/ingredients/ai-pack-size?description=${encodeURIComponent(preSelectLineItem.description)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
}).then(res => res.ok ? res.json() : null).then(data => {
|
}).then(res => res.ok ? res.json() : null).then(data => {
|
||||||
if (data?.pack_quantity && data?.unit_size) {
|
if (data?.pack_quantity && data?.unit_size) {
|
||||||
|
|
@ -589,7 +589,7 @@ export default function IngredientModal({
|
||||||
}
|
}
|
||||||
const timer = setTimeout(async () => {
|
const timer = setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/check-duplicate?name=${encodeURIComponent(formName)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/check-duplicate?name=${encodeURIComponent(formName)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -605,7 +605,7 @@ export default function IngredientModal({
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/ingredients', {
|
const res = await fetch('/kitchen/api/ingredients', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -628,7 +628,7 @@ export default function IngredientModal({
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async ({ id, data }: { id: number; data: Record<string, unknown> }) => {
|
mutationFn: async ({ id, data }: { id: number; data: Record<string, unknown> }) => {
|
||||||
const res = await fetch(`/api/ingredients/${id}`, {
|
const res = await fetch(`/kitchen/api/ingredients/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -988,7 +988,7 @@ export default function IngredientModal({
|
||||||
title="Click to enlarge"
|
title="Click to enlarge"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={`/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview?token=${encodeURIComponent(token || '')}`}
|
src={`/kitchen/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview?token=${encodeURIComponent(token || '')}`}
|
||||||
alt="Invoice line item"
|
alt="Invoice line item"
|
||||||
style={{ width: '100%', height: 'auto', display: 'block' }}
|
style={{ width: '100%', height: 'auto', display: 'block' }}
|
||||||
onError={(e) => { (e.target as HTMLImageElement).parentElement!.style.display = 'none' }}
|
onError={(e) => { (e.target as HTMLImageElement).parentElement!.style.display = 'none' }}
|
||||||
|
|
@ -1058,7 +1058,7 @@ export default function IngredientModal({
|
||||||
{selectedLi.most_recent_line_number != null && (
|
{selectedLi.most_recent_line_number != null && (
|
||||||
<div style={{ flex: '0 0 auto', maxWidth: '120px', borderRadius: '4px', overflow: 'hidden', border: '1px solid #e0e0e0' }}>
|
<div style={{ flex: '0 0 auto', maxWidth: '120px', borderRadius: '4px', overflow: 'hidden', border: '1px solid #e0e0e0' }}>
|
||||||
<img
|
<img
|
||||||
src={`/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview/field/product_code?token=${encodeURIComponent(token || '')}`}
|
src={`/kitchen/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview/field/product_code?token=${encodeURIComponent(token || '')}`}
|
||||||
alt="Product code from invoice"
|
alt="Product code from invoice"
|
||||||
style={{ width: '100%', height: 'auto', display: 'block' }}
|
style={{ width: '100%', height: 'auto', display: 'block' }}
|
||||||
onError={(e) => { (e.target as HTMLImageElement).parentElement!.style.display = 'none' }}
|
onError={(e) => { (e.target as HTMLImageElement).parentElement!.style.display = 'none' }}
|
||||||
|
|
@ -1246,7 +1246,7 @@ export default function IngredientModal({
|
||||||
{'\u2715'}
|
{'\u2715'}
|
||||||
</button>
|
</button>
|
||||||
<img
|
<img
|
||||||
src={`/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview?token=${encodeURIComponent(token || '')}`}
|
src={`/kitchen/api/invoices/${selectedLi.most_recent_invoice_id}/line-items/${selectedLi.most_recent_line_number}/preview?token=${encodeURIComponent(token || '')}`}
|
||||||
alt="Invoice line item"
|
alt="Invoice line item"
|
||||||
style={{ maxWidth: '95vw', maxHeight: '90vh', borderRadius: '8px', boxShadow: '0 4px 20px rgba(0,0,0,0.3)' }}
|
style={{ maxWidth: '95vw', maxHeight: '90vh', borderRadius: '8px', boxShadow: '0 4px 20px rgba(0,0,0,0.3)' }}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export default function Ingredients() {
|
||||||
const { data: categories } = useQuery<IngredientCategory[]>({
|
const { data: categories } = useQuery<IngredientCategory[]>({
|
||||||
queryKey: ['ingredient-categories'],
|
queryKey: ['ingredient-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients/categories', {
|
const res = await fetch('/kitchen/api/ingredients/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch categories')
|
if (!res.ok) throw new Error('Failed to fetch categories')
|
||||||
|
|
@ -84,7 +84,7 @@ export default function Ingredients() {
|
||||||
if (categoryFilter) params.set('category_id', categoryFilter)
|
if (categoryFilter) params.set('category_id', categoryFilter)
|
||||||
if (showUnmapped) params.set('unmapped', 'true')
|
if (showUnmapped) params.set('unmapped', 'true')
|
||||||
if (showArchived) params.set('archived', 'true')
|
if (showArchived) params.set('archived', 'true')
|
||||||
const res = await fetch(`/api/ingredients?${params}`, {
|
const res = await fetch(`/kitchen/api/ingredients?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch ingredients')
|
if (!res.ok) throw new Error('Failed to fetch ingredients')
|
||||||
|
|
@ -97,7 +97,7 @@ export default function Ingredients() {
|
||||||
const { data: sources } = useQuery<SourceItem[]>({
|
const { data: sources } = useQuery<SourceItem[]>({
|
||||||
queryKey: ['ingredient-sources', expandedId],
|
queryKey: ['ingredient-sources', expandedId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${expandedId}/sources`, {
|
const res = await fetch(`/kitchen/api/ingredients/${expandedId}/sources`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch sources')
|
if (!res.ok) throw new Error('Failed to fetch sources')
|
||||||
|
|
@ -108,7 +108,7 @@ export default function Ingredients() {
|
||||||
|
|
||||||
const archiveMutation = useMutation({
|
const archiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/ingredients/${id}`, {
|
const res = await fetch(`/kitchen/api/ingredients/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -119,7 +119,7 @@ export default function Ingredients() {
|
||||||
|
|
||||||
const unarchiveMutation = useMutation({
|
const unarchiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/ingredients/${id}`, {
|
const res = await fetch(`/kitchen/api/ingredients/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ is_archived: false }),
|
body: JSON.stringify({ is_archived: false }),
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ export default function InvoiceList() {
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -119,7 +119,7 @@ export default function InvoiceList() {
|
||||||
const { data, isLoading, error } = useQuery<InvoiceListResponse>({
|
const { data, isLoading, error } = useQuery<InvoiceListResponse>({
|
||||||
queryKey: ['invoices', statusFilter, supplierFilter, dateFrom, dateTo],
|
queryKey: ['invoices', statusFilter, supplierFilter, dateFrom, dateTo],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const url = queryString ? `/api/invoices/?${queryString}` : '/api/invoices/'
|
const url = queryString ? `/kitchen/api/invoices/?${queryString}` : '/kitchen/api/invoices/'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -137,7 +137,7 @@ export default function InvoiceList() {
|
||||||
params.set('status', 'confirmed')
|
params.set('status', 'confirmed')
|
||||||
params.set('limit', '20')
|
params.set('limit', '20')
|
||||||
params.set('sort', 'recent')
|
params.set('sort', 'recent')
|
||||||
const res = await fetch(`/api/invoices/?${params}`, {
|
const res = await fetch(`/kitchen/api/invoices/?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch completed invoices')
|
if (!res.ok) throw new Error('Failed to fetch completed invoices')
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ export default function LineItemHistoryModal({
|
||||||
if (dateFrom) params.set('date_from', dateFrom)
|
if (dateFrom) params.set('date_from', dateFrom)
|
||||||
if (dateTo) params.set('date_to', dateTo)
|
if (dateTo) params.set('date_to', dateTo)
|
||||||
|
|
||||||
const res = await fetch(`/api/search/line-items/history?${params}`, {
|
const res = await fetch(`/kitchen/api/search/line-items/history?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch history')
|
if (!res.ok) throw new Error('Failed to fetch history')
|
||||||
|
|
@ -99,7 +99,7 @@ export default function LineItemHistoryModal({
|
||||||
// Acknowledge price mutation
|
// Acknowledge price mutation
|
||||||
const acknowledgeMutation = useMutation({
|
const acknowledgeMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/search/line-items/acknowledge-price', {
|
const res = await fetch('/kitchen/api/search/line-items/acknowledge-price', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ export default function LinkDisputeModal({
|
||||||
const { data: disputes, isLoading } = useQuery<OpenDispute[]>({
|
const { data: disputes, isLoading } = useQuery<OpenDispute[]>({
|
||||||
queryKey: ['open-disputes', supplierId],
|
queryKey: ['open-disputes', supplierId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/disputes/supplier/${supplierId}/open`, {
|
const res = await fetch(`/kitchen/api/disputes/supplier/${supplierId}/open`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch disputes')
|
if (!res.ok) throw new Error('Failed to fetch disputes')
|
||||||
|
|
@ -78,7 +78,7 @@ export default function LinkDisputeModal({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
if (!selectedDisputeId) throw new Error('No dispute selected')
|
if (!selectedDisputeId) throw new Error('No dispute selected')
|
||||||
|
|
||||||
const res = await fetch(`/api/disputes/${selectedDisputeId}/link-credit-note`, {
|
const res = await fetch(`/kitchen/api/disputes/${selectedDisputeId}/link-credit-note`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ export default function MapLineItemsModal({ ingredient, onClose, onSaved }: MapL
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch('/kitchen/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
return data.suppliers || data || []
|
return data.suppliers || data || []
|
||||||
|
|
@ -112,7 +112,7 @@ export default function MapLineItemsModal({ ingredient, onClose, onSaved }: MapL
|
||||||
params.set('date_from', dateFrom)
|
params.set('date_from', dateFrom)
|
||||||
params.set('date_to', dateTo)
|
params.set('date_to', dateTo)
|
||||||
params.set('limit', '50')
|
params.set('limit', '50')
|
||||||
const res = await fetch(`/api/search/line-items?${params}`, {
|
const res = await fetch(`/kitchen/api/search/line-items?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { items: [], total_count: 0 }
|
if (!res.ok) return { items: [], total_count: 0 }
|
||||||
|
|
@ -206,7 +206,7 @@ export default function MapLineItemsModal({ ingredient, onClose, onSaved }: MapL
|
||||||
sourceData.invoice_id = selectedItem.most_recent_invoice_id
|
sourceData.invoice_id = selectedItem.most_recent_invoice_id
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(`/api/ingredients/${ingredient.id}/sources`, {
|
const res = await fetch(`/kitchen/api/ingredients/${ingredient.id}/sources`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(sourceData),
|
body: JSON.stringify(sourceData),
|
||||||
|
|
@ -233,7 +233,7 @@ export default function MapLineItemsModal({ ingredient, onClose, onSaved }: MapL
|
||||||
|
|
||||||
// Preview URL for the selected line item
|
// Preview URL for the selected line item
|
||||||
const previewUrl = selectedItem?.most_recent_invoice_id && selectedItem?.most_recent_line_number != null
|
const previewUrl = selectedItem?.most_recent_invoice_id && selectedItem?.most_recent_line_number != null
|
||||||
? `/api/invoices/${selectedItem.most_recent_invoice_id}/line-items/${selectedItem.most_recent_line_number}/preview?token=${token}`
|
? `/kitchen/api/invoices/${selectedItem.most_recent_invoice_id}/line-items/${selectedItem.most_recent_line_number}/preview?token=${token}`
|
||||||
: null
|
: null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ export default function MenuEditor() {
|
||||||
const { data: menu, isLoading } = useQuery<MenuDetail>({
|
const { data: menu, isLoading } = useQuery<MenuDetail>({
|
||||||
queryKey: ['menu', menuId],
|
queryKey: ['menu', menuId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/menus/${menuId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch menu')
|
if (!res.ok) throw new Error('Failed to fetch menu')
|
||||||
|
|
@ -97,7 +97,7 @@ export default function MenuEditor() {
|
||||||
// Mutations
|
// Mutations
|
||||||
const updateMenuMutation = useMutation({
|
const updateMenuMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -109,7 +109,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const addDivMutation = useMutation({
|
const addDivMutation = useMutation({
|
||||||
mutationFn: async (name: string) => {
|
mutationFn: async (name: string) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/divisions`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/divisions`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
|
|
@ -125,7 +125,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const updateDivMutation = useMutation({
|
const updateDivMutation = useMutation({
|
||||||
mutationFn: async ({ divId, name }: { divId: number; name: string }) => {
|
mutationFn: async ({ divId, name }: { divId: number; name: string }) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/divisions/${divId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/divisions/${divId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
|
|
@ -140,7 +140,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const deleteDivMutation = useMutation({
|
const deleteDivMutation = useMutation({
|
||||||
mutationFn: async (divId: number) => {
|
mutationFn: async (divId: number) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/divisions/${divId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/divisions/${divId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -151,7 +151,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const reorderDivsMutation = useMutation({
|
const reorderDivsMutation = useMutation({
|
||||||
mutationFn: async (ids: number[]) => {
|
mutationFn: async (ids: number[]) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/divisions/reorder`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/divisions/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ids }),
|
body: JSON.stringify({ ids }),
|
||||||
|
|
@ -163,7 +163,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const updateItemMutation = useMutation({
|
const updateItemMutation = useMutation({
|
||||||
mutationFn: async ({ itemId, data }: { itemId: number; data: Record<string, unknown> }) => {
|
mutationFn: async ({ itemId, data }: { itemId: number; data: Record<string, unknown> }) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/${itemId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/${itemId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -178,7 +178,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const deleteItemMutation = useMutation({
|
const deleteItemMutation = useMutation({
|
||||||
mutationFn: async (itemId: number) => {
|
mutationFn: async (itemId: number) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/${itemId}`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/${itemId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -189,7 +189,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const republishMutation = useMutation({
|
const republishMutation = useMutation({
|
||||||
mutationFn: async ({ itemId, confirmed_by_name }: { itemId: number; confirmed_by_name: string }) => {
|
mutationFn: async ({ itemId, confirmed_by_name }: { itemId: number; confirmed_by_name: string }) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/${itemId}/republish`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/${itemId}/republish`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ confirmed_by_name }),
|
body: JSON.stringify({ confirmed_by_name }),
|
||||||
|
|
@ -201,7 +201,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const reorderItemsMutation = useMutation({
|
const reorderItemsMutation = useMutation({
|
||||||
mutationFn: async (ids: number[]) => {
|
mutationFn: async (ids: number[]) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/reorder`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ids }),
|
body: JSON.stringify({ ids }),
|
||||||
|
|
@ -213,7 +213,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const batchRepublishMutation = useMutation({
|
const batchRepublishMutation = useMutation({
|
||||||
mutationFn: async (body: { confirmed_by_name: string; items: Array<{ id: number; confirmed: boolean }> }) => {
|
mutationFn: async (body: { confirmed_by_name: string; items: Array<{ id: number; confirmed: boolean }> }) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/republish-stale`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/republish-stale`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
|
|
@ -231,7 +231,7 @@ export default function MenuEditor() {
|
||||||
mutationFn: async ({ itemId, file }: { itemId: number; file: File }) => {
|
mutationFn: async ({ itemId, file }: { itemId: number; file: File }) => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/${itemId}/image`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/${itemId}/image`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -243,7 +243,7 @@ export default function MenuEditor() {
|
||||||
|
|
||||||
const deleteImageMutation = useMutation({
|
const deleteImageMutation = useMutation({
|
||||||
mutationFn: async (itemId: number) => {
|
mutationFn: async (itemId: number) => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/items/${itemId}/image`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/items/${itemId}/image`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -471,7 +471,7 @@ export default function MenuEditor() {
|
||||||
{/* Image thumbnail */}
|
{/* Image thumbnail */}
|
||||||
{item.has_image ? (
|
{item.has_image ? (
|
||||||
<img
|
<img
|
||||||
src={`/api/menus/${menuId}/items/${item.id}/image?token=${token}`}
|
src={`/kitchen/api/menus/${menuId}/items/${item.id}/image?token=${token}`}
|
||||||
alt=""
|
alt=""
|
||||||
style={styles.thumbnail}
|
style={styles.thumbnail}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export default function MenuFlagMatrix({ menuId, menuName, onClose }: Props) {
|
||||||
const { data, isLoading } = useQuery<MatrixData>({
|
const { data, isLoading } = useQuery<MatrixData>({
|
||||||
queryKey: ['menu-flag-matrix', menuId],
|
queryKey: ['menu-flag-matrix', menuId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/menus/${menuId}/flags`, {
|
const res = await fetch(`/kitchen/api/menus/${menuId}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ export default function MenuList() {
|
||||||
const { data: menus, isLoading } = useQuery<MenuListItem[]>({
|
const { data: menus, isLoading } = useQuery<MenuListItem[]>({
|
||||||
queryKey: ['menus'],
|
queryKey: ['menus'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/menus', {
|
const res = await fetch('/kitchen/api/menus', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch menus')
|
if (!res.ok) throw new Error('Failed to fetch menus')
|
||||||
|
|
@ -49,7 +49,7 @@ export default function MenuList() {
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: { name: string; description: string | null; notes: string | null; preset_divisions: boolean }) => {
|
mutationFn: async (data: { name: string; description: string | null; notes: string | null; preset_divisions: boolean }) => {
|
||||||
const res = await fetch('/api/menus', {
|
const res = await fetch('/kitchen/api/menus', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -72,7 +72,7 @@ export default function MenuList() {
|
||||||
|
|
||||||
const toggleActiveMutation = useMutation({
|
const toggleActiveMutation = useMutation({
|
||||||
mutationFn: async ({ id, is_active }: { id: number; is_active: boolean }) => {
|
mutationFn: async ({ id, is_active }: { id: number; is_active: boolean }) => {
|
||||||
const res = await fetch(`/api/menus/${id}`, {
|
const res = await fetch(`/kitchen/api/menus/${id}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ is_active }),
|
body: JSON.stringify({ is_active }),
|
||||||
|
|
@ -84,7 +84,7 @@ export default function MenuList() {
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/menus/${id}`, {
|
const res = await fetch(`/kitchen/api/menus/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -95,7 +95,7 @@ export default function MenuList() {
|
||||||
|
|
||||||
const duplicateMutation = useMutation({
|
const duplicateMutation = useMutation({
|
||||||
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
||||||
const res = await fetch(`/api/menus/${id}/duplicate`, {
|
const res = await fetch(`/kitchen/api/menus/${id}/duplicate`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
|
|
@ -116,7 +116,7 @@ export default function MenuList() {
|
||||||
|
|
||||||
const reorderMutation = useMutation({
|
const reorderMutation = useMutation({
|
||||||
mutationFn: async (ids: number[]) => {
|
mutationFn: async (ids: number[]) => {
|
||||||
const res = await fetch('/api/menus/reorder', {
|
const res = await fetch('/kitchen/api/menus/reorder', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ids }),
|
body: JSON.stringify({ ids }),
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ export default function PriceImpact() {
|
||||||
const { data, isLoading } = useQuery<ImpactData>({
|
const { data, isLoading } = useQuery<ImpactData>({
|
||||||
queryKey: ['price-impact', days],
|
queryKey: ['price-impact', days],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/price-impact?days=${days}`, {
|
const res = await fetch(`/kitchen/api/recipes/price-impact?days=${days}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch price impact')
|
if (!res.ok) throw new Error('Failed to fetch price impact')
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default function PublishToMenuModal({
|
||||||
const { data: llmSettings } = useQuery<{ llm_enabled: boolean; anthropic_api_key_set: boolean }>({
|
const { data: llmSettings } = useQuery<{ llm_enabled: boolean; anthropic_api_key_set: boolean }>({
|
||||||
queryKey: ['settings'],
|
queryKey: ['settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/', { headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch('/kitchen/api/settings/', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (!res.ok) return { llm_enabled: false, anthropic_api_key_set: false }
|
if (!res.ok) return { llm_enabled: false, anthropic_api_key_set: false }
|
||||||
return res.json()
|
return res.json()
|
||||||
},
|
},
|
||||||
|
|
@ -70,7 +70,7 @@ export default function PublishToMenuModal({
|
||||||
if (!recipeIdToUse) return
|
if (!recipeIdToUse) return
|
||||||
setAiDescLoading(true)
|
setAiDescLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/menus/generate-description', {
|
const res = await fetch('/kitchen/api/menus/generate-description', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ recipe_id: recipeIdToUse, recipe_name: displayName || recipeName || '', ingredients: [], allergen_flags: [] }),
|
body: JSON.stringify({ recipe_id: recipeIdToUse, recipe_name: displayName || recipeName || '', ingredients: [], allergen_flags: [] }),
|
||||||
|
|
@ -87,7 +87,7 @@ export default function PublishToMenuModal({
|
||||||
const { data: dishes } = useQuery<Array<{ id: number; name: string; description: string | null; gross_sell_price: number | null }>>({
|
const { data: dishes } = useQuery<Array<{ id: number; name: string; description: string | null; gross_sell_price: number | null }>>({
|
||||||
queryKey: ['dishes-for-menu'],
|
queryKey: ['dishes-for-menu'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes?recipe_type=dish', {
|
const res = await fetch('/kitchen/api/recipes?recipe_type=dish', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dishes')
|
if (!res.ok) throw new Error('Failed to fetch dishes')
|
||||||
|
|
@ -100,7 +100,7 @@ export default function PublishToMenuModal({
|
||||||
const { data: menus } = useQuery<Array<{ id: number; name: string; is_active: boolean }>>({
|
const { data: menus } = useQuery<Array<{ id: number; name: string; is_active: boolean }>>({
|
||||||
queryKey: ['menus-for-publish'],
|
queryKey: ['menus-for-publish'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/menus', {
|
const res = await fetch('/kitchen/api/menus', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch menus')
|
if (!res.ok) throw new Error('Failed to fetch menus')
|
||||||
|
|
@ -113,7 +113,7 @@ export default function PublishToMenuModal({
|
||||||
const { data: menuDetail } = useQuery<{ divisions: Division[] }>({
|
const { data: menuDetail } = useQuery<{ divisions: Division[] }>({
|
||||||
queryKey: ['menu-divisions', selectedMenuId],
|
queryKey: ['menu-divisions', selectedMenuId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/menus/${selectedMenuId}`, {
|
const res = await fetch(`/kitchen/api/menus/${selectedMenuId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -129,7 +129,7 @@ export default function PublishToMenuModal({
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['recipe-flags-for-publish', selectedRecipeId],
|
queryKey: ['recipe-flags-for-publish', selectedRecipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${selectedRecipeId}/flags`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${selectedRecipeId}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed')
|
if (!res.ok) throw new Error('Failed')
|
||||||
|
|
@ -158,7 +158,7 @@ export default function PublishToMenuModal({
|
||||||
|
|
||||||
const publishMutation = useMutation({
|
const publishMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch(`/api/menus/${selectedMenuId}/items`, {
|
const res = await fetch(`/kitchen/api/menus/${selectedMenuId}/items`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export default function PurchaseOrderList() {
|
||||||
const { data: suppliersData } = useQuery<{ suppliers: Array<{ id: number; name: string }> }>({
|
const { data: suppliersData } = useQuery<{ suppliers: Array<{ id: number; name: string }> }>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -52,7 +52,7 @@ export default function PurchaseOrderList() {
|
||||||
const { data: poList, refetch } = useQuery<PurchaseOrderSummary[]>({
|
const { data: poList, refetch } = useQuery<PurchaseOrderSummary[]>({
|
||||||
queryKey: ['purchase-orders', statusFilter, supplierFilter],
|
queryKey: ['purchase-orders', statusFilter, supplierFilter],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/purchase-orders/?${params}`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch purchase orders')
|
if (!res.ok) throw new Error('Failed to fetch purchase orders')
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
// Load suppliers (including order_email for email button visibility)
|
// Load suppliers (including order_email for email button visibility)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token) return
|
if (!token) return
|
||||||
fetch('/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
fetch('/kitchen/api/suppliers/', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => setSuppliers(data.suppliers || data || []))
|
.then(data => setSuppliers(data.suppliers || data || []))
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
|
|
@ -73,7 +73,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
// Check if SMTP is configured (for email button visibility)
|
// Check if SMTP is configured (for email button visibility)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!token) return
|
if (!token) return
|
||||||
fetch('/api/settings/', { headers: { Authorization: `Bearer ${token}` } })
|
fetch('/kitchen/api/settings/', { headers: { Authorization: `Bearer ${token}` } })
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => setSmtpConfigured(!!(data.smtp_host && data.smtp_from_email)))
|
.then(data => setSmtpConfigured(!!(data.smtp_host && data.smtp_from_email)))
|
||||||
.catch(() => setSmtpConfigured(false))
|
.catch(() => setSmtpConfigured(false))
|
||||||
|
|
@ -83,7 +83,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!poId || !token) return
|
if (!poId || !token) return
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
fetch(`/api/purchase-orders/${poId}`, { headers: { Authorization: `Bearer ${token}` } })
|
fetch(`/kitchen/api/purchase-orders/${poId}`, { headers: { Authorization: `Bearer ${token}` } })
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (!r.ok) throw new Error('Failed to load')
|
if (!r.ok) throw new Error('Failed to load')
|
||||||
return r.json()
|
return r.json()
|
||||||
|
|
@ -144,7 +144,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
searchTimeout.current = setTimeout(() => {
|
searchTimeout.current = setTimeout(() => {
|
||||||
const params = new URLSearchParams({ query: searchQuery })
|
const params = new URLSearchParams({ query: searchQuery })
|
||||||
if (supplierId) params.append('supplier_id', String(supplierId))
|
if (supplierId) params.append('supplier_id', String(supplierId))
|
||||||
fetch(`/api/purchase-orders/products/search?${params}`, {
|
fetch(`/kitchen/api/purchase-orders/products/search?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
|
|
@ -243,7 +243,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = poId ? `/api/purchase-orders/${poId}` : '/api/purchase-orders/'
|
const url = poId ? `/kitchen/api/purchase-orders/${poId}` : '/kitchen/api/purchase-orders/'
|
||||||
const method = poId ? 'PUT' : 'POST'
|
const method = poId ? 'PUT' : 'POST'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
method,
|
method,
|
||||||
|
|
@ -269,7 +269,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
form.append('file', file)
|
form.append('file', file)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/purchase-orders/${poId}/attachment`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/${poId}/attachment`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: form,
|
body: form,
|
||||||
|
|
@ -285,7 +285,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
const handleRemoveAttachment = async () => {
|
const handleRemoveAttachment = async () => {
|
||||||
if (!poId || !token) return
|
if (!poId || !token) return
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/purchase-orders/${poId}/attachment`, {
|
await fetch(`/kitchen/api/purchase-orders/${poId}/attachment`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -299,7 +299,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
if (!poId || !token) return
|
if (!poId || !token) return
|
||||||
if (!confirm('Delete this purchase order?')) return
|
if (!confirm('Delete this purchase order?')) return
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/purchase-orders/${poId}`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/${poId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -346,14 +346,14 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
...(orderType === 'single_value' ? { total_amount: totalAmount } : {}),
|
...(orderType === 'single_value' ? { total_amount: totalAmount } : {}),
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/purchase-orders/', {
|
const res = await fetch('/kitchen/api/purchase-orders/', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to save')
|
if (!res.ok) throw new Error('Failed to save')
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
window.open(`/api/purchase-orders/${data.id}/preview?token=${encodeURIComponent(token || '')}`, '_blank')
|
window.open(`/kitchen/api/purchase-orders/${data.id}/preview?token=${encodeURIComponent(token || '')}`, '_blank')
|
||||||
onSaved()
|
onSaved()
|
||||||
onClose()
|
onClose()
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
|
@ -364,7 +364,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
} else {
|
} else {
|
||||||
// Existing PO — save current state then preview
|
// Existing PO — save current state then preview
|
||||||
await handleSave()
|
await handleSave()
|
||||||
window.open(`/api/purchase-orders/${poId}/preview?token=${encodeURIComponent(token || '')}`, '_blank')
|
window.open(`/kitchen/api/purchase-orders/${poId}/preview?token=${encodeURIComponent(token || '')}`, '_blank')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,7 +400,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = poId ? `/api/purchase-orders/${poId}` : '/api/purchase-orders/'
|
const url = poId ? `/kitchen/api/purchase-orders/${poId}` : '/kitchen/api/purchase-orders/'
|
||||||
const method = poId ? 'PUT' : 'POST'
|
const method = poId ? 'PUT' : 'POST'
|
||||||
const saveRes = await fetch(url, {
|
const saveRes = await fetch(url, {
|
||||||
method,
|
method,
|
||||||
|
|
@ -411,7 +411,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
const savedPo = await saveRes.json()
|
const savedPo = await saveRes.json()
|
||||||
|
|
||||||
// Now send the email
|
// Now send the email
|
||||||
const emailRes = await fetch(`/api/purchase-orders/${savedPo.id}/send-email`, {
|
const emailRes = await fetch(`/kitchen/api/purchase-orders/${savedPo.id}/send-email`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -712,7 +712,7 @@ export default function PurchaseOrderModal({ isOpen, onClose, onSaved, poId, def
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isEditable && poId && (
|
{!isEditable && poId && (
|
||||||
<button style={styles.previewBtn} onClick={() => window.open(`/api/purchase-orders/${poId}/preview?token=${encodeURIComponent(token || '')}`, '_blank')}>
|
<button style={styles.previewBtn} onClick={() => window.open(`/kitchen/api/purchase-orders/${poId}/preview?token=${encodeURIComponent(token || '')}`, '_blank')}>
|
||||||
Preview
|
Preview
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ export default function Purchases() {
|
||||||
const { data, isLoading, error } = useQuery<DateRangePurchasesResponse>({
|
const { data, isLoading, error } = useQuery<DateRangePurchasesResponse>({
|
||||||
queryKey: ['purchases-range', submittedFromDate, submittedToDate],
|
queryKey: ['purchases-range', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/purchases/range?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/purchases/range?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch purchases')
|
if (!res.ok) throw new Error('Failed to fetch purchases')
|
||||||
|
|
@ -293,7 +293,7 @@ export default function Purchases() {
|
||||||
const { data: disputeStats } = useQuery<DailyDisputeStats>({
|
const { data: disputeStats } = useQuery<DailyDisputeStats>({
|
||||||
queryKey: ['daily-dispute-stats', submittedFromDate, submittedToDate],
|
queryKey: ['daily-dispute-stats', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/disputes/stats/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/disputes/stats/daily?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch dispute stats')
|
if (!res.ok) throw new Error('Failed to fetch dispute stats')
|
||||||
|
|
@ -305,7 +305,7 @@ export default function Purchases() {
|
||||||
const { data: allowanceStats } = useQuery<DailyLogbookStats>({
|
const { data: allowanceStats } = useQuery<DailyLogbookStats>({
|
||||||
queryKey: ['daily-allowance-stats', submittedFromDate, submittedToDate],
|
queryKey: ['daily-allowance-stats', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/logbook/daily-stats?date_from=${submittedFromDate}&date_to=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/logbook/daily-stats?date_from=${submittedFromDate}&date_to=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch allowance stats')
|
if (!res.ok) throw new Error('Failed to fetch allowance stats')
|
||||||
|
|
@ -379,7 +379,7 @@ export default function Purchases() {
|
||||||
const { data: weeklyChartData, isLoading: weeklyChartLoading, error: weeklyChartError } = useQuery<DailyGPChartResponse>({
|
const { data: weeklyChartData, isLoading: weeklyChartLoading, error: weeklyChartError } = useQuery<DailyGPChartResponse>({
|
||||||
queryKey: ['weekly-chart-data', weeklyChartDateRange.from, weeklyChartDateRange.to],
|
queryKey: ['weekly-chart-data', weeklyChartDateRange.from, weeklyChartDateRange.to],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/gp/daily?from_date=${weeklyChartDateRange.from}&to_date=${weeklyChartDateRange.to}`, {
|
const res = await fetch(`/kitchen/api/reports/gp/daily?from_date=${weeklyChartDateRange.from}&to_date=${weeklyChartDateRange.to}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch weekly chart data')
|
if (!res.ok) throw new Error('Failed to fetch weekly chart data')
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ export default function PurchasesReport() {
|
||||||
const { data: summary, isLoading, error } = useQuery<PurchasesSummaryResponse>({
|
const { data: summary, isLoading, error } = useQuery<PurchasesSummaryResponse>({
|
||||||
queryKey: ['purchases-summary', submittedFromDate, submittedToDate],
|
queryKey: ['purchases-summary', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/purchases/summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/purchases/summary?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch purchases summary')
|
if (!res.ok) throw new Error('Failed to fetch purchases summary')
|
||||||
|
|
@ -284,7 +284,7 @@ export default function PurchasesReport() {
|
||||||
const { data: chartData } = useQuery<DailySupplierChartResponse>({
|
const { data: chartData } = useQuery<DailySupplierChartResponse>({
|
||||||
queryKey: ['purchases-daily-supplier', submittedFromDate, submittedToDate],
|
queryKey: ['purchases-daily-supplier', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/purchases/daily-by-supplier?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/reports/purchases/daily-by-supplier?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch chart data')
|
if (!res.ok) throw new Error('Failed to fetch chart data')
|
||||||
|
|
@ -298,7 +298,7 @@ export default function PurchasesReport() {
|
||||||
const { data: topItems } = useQuery<TopItemsResponse>({
|
const { data: topItems } = useQuery<TopItemsResponse>({
|
||||||
queryKey: ['purchases-top-items', submittedFromDate, submittedToDate, topItemsSupplierFilter],
|
queryKey: ['purchases-top-items', submittedFromDate, submittedToDate, topItemsSupplierFilter],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
let url = `/api/reports/purchases/top-items?from_date=${submittedFromDate}&to_date=${submittedToDate}`
|
let url = `/kitchen/api/reports/purchases/top-items?from_date=${submittedFromDate}&to_date=${submittedToDate}`
|
||||||
if (topItemsSupplierFilter !== null) {
|
if (topItemsSupplierFilter !== null) {
|
||||||
url += `&supplier_id=${topItemsSupplierFilter}`
|
url += `&supplier_id=${topItemsSupplierFilter}`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@ export default function RecipeEditor() {
|
||||||
const { data: recipe } = useQuery<RecipeDetail>({
|
const { data: recipe } = useQuery<RecipeDetail>({
|
||||||
queryKey: ['recipe', recipeId],
|
queryKey: ['recipe', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Not found')
|
if (!res.ok) throw new Error('Not found')
|
||||||
|
|
@ -297,7 +297,7 @@ export default function RecipeEditor() {
|
||||||
const { data: sections } = useQuery<MenuSection[]>({
|
const { data: sections } = useQuery<MenuSection[]>({
|
||||||
queryKey: ['recipe-sections'],
|
queryKey: ['recipe-sections'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=recipe', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=recipe', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -309,7 +309,7 @@ export default function RecipeEditor() {
|
||||||
const { data: costData } = useQuery<CostData>({
|
const { data: costData } = useQuery<CostData>({
|
||||||
queryKey: ['recipe-cost', recipeId],
|
queryKey: ['recipe-cost', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/costing`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/costing`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -321,7 +321,7 @@ export default function RecipeEditor() {
|
||||||
const { data: scaledCostData } = useQuery<CostData>({
|
const { data: scaledCostData } = useQuery<CostData>({
|
||||||
queryKey: ['recipe-cost-scaled', recipeId, scalePortions],
|
queryKey: ['recipe-cost-scaled', recipeId, scalePortions],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/costing?scale_to=${scalePortions}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/costing?scale_to=${scalePortions}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -333,7 +333,7 @@ export default function RecipeEditor() {
|
||||||
const { data: flagData } = useQuery<FlagState>({
|
const { data: flagData } = useQuery<FlagState>({
|
||||||
queryKey: ['recipe-flags', recipeId],
|
queryKey: ['recipe-flags', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/flags`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/flags`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -345,7 +345,7 @@ export default function RecipeEditor() {
|
||||||
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; propagation_type: string; required: boolean }>>({
|
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; propagation_type: string; required: boolean }>>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -357,7 +357,7 @@ export default function RecipeEditor() {
|
||||||
const { data: changeLog } = useQuery<ChangeLogEntry[]>({
|
const { data: changeLog } = useQuery<ChangeLogEntry[]>({
|
||||||
queryKey: ['recipe-changelog', recipeId],
|
queryKey: ['recipe-changelog', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/change-log`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/change-log`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -369,7 +369,7 @@ export default function RecipeEditor() {
|
||||||
const { data: costTrendRaw } = useQuery<CostTrendResponse>({
|
const { data: costTrendRaw } = useQuery<CostTrendResponse>({
|
||||||
queryKey: ['recipe-cost-trend', recipeId],
|
queryKey: ['recipe-cost-trend', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/cost-trend`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/cost-trend`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
if (!res.ok) throw new Error('Failed to fetch cost trend')
|
||||||
|
|
@ -382,7 +382,7 @@ export default function RecipeEditor() {
|
||||||
const { data: editIngData } = useQuery<EditingIngredient>({
|
const { data: editIngData } = useQuery<EditingIngredient>({
|
||||||
queryKey: ['ingredient-edit', editIngId],
|
queryKey: ['ingredient-edit', editIngId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/ingredients/${editIngId}`, {
|
const res = await fetch(`/kitchen/api/ingredients/${editIngId}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Not found')
|
if (!res.ok) throw new Error('Not found')
|
||||||
|
|
@ -408,7 +408,7 @@ export default function RecipeEditor() {
|
||||||
const { data: availableRecipes } = useQuery<Array<{ id: number; name: string; recipe_type: string; batch_portions: number; batch_output_type: string; batch_yield_qty: number | null; batch_yield_unit: string | null; output_unit: string }>>({
|
const { data: availableRecipes } = useQuery<Array<{ id: number; name: string; recipe_type: string; batch_portions: number; batch_output_type: string; batch_yield_qty: number | null; batch_yield_unit: string | null; output_unit: string }>>({
|
||||||
queryKey: ['recipes-list-for-sub'],
|
queryKey: ['recipes-list-for-sub'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes?recipe_type=component', {
|
const res = await fetch('/kitchen/api/recipes?recipe_type=component', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
return res.json()
|
return res.json()
|
||||||
|
|
@ -438,7 +438,7 @@ export default function RecipeEditor() {
|
||||||
if (!ingSearch || ingSearch.length < 2 || !token) return
|
if (!ingSearch || ingSearch.length < 2 || !token) return
|
||||||
const timer = setTimeout(async () => {
|
const timer = setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/suggest?description=${encodeURIComponent(ingSearch)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/suggest?description=${encodeURIComponent(ingSearch)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -455,7 +455,7 @@ export default function RecipeEditor() {
|
||||||
// Mutations
|
// Mutations
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -473,7 +473,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const addIngMutation = useMutation({
|
const addIngMutation = useMutation({
|
||||||
mutationFn: async (data: { ingredient_id: number; quantity: number; unit?: string; notes?: string }) => {
|
mutationFn: async (data: { ingredient_id: number; quantity: number; unit?: string; notes?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/ingredients`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/ingredients`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -498,7 +498,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const updateIngMutation = useMutation({
|
const updateIngMutation = useMutation({
|
||||||
mutationFn: async ({ riId, quantity, unit, yield_percent, notes }: { riId: number; quantity?: number; unit?: string; yield_percent?: number; notes?: string }) => {
|
mutationFn: async ({ riId, quantity, unit, yield_percent, notes }: { riId: number; quantity?: number; unit?: string; yield_percent?: number; notes?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-ingredients/${riId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-ingredients/${riId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ quantity, unit, yield_percent, notes }),
|
body: JSON.stringify({ quantity, unit, yield_percent, notes }),
|
||||||
|
|
@ -516,7 +516,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const removeIngMutation = useMutation({
|
const removeIngMutation = useMutation({
|
||||||
mutationFn: async (riId: number) => {
|
mutationFn: async (riId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-ingredients/${riId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-ingredients/${riId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -533,7 +533,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const addSubMutation = useMutation({
|
const addSubMutation = useMutation({
|
||||||
mutationFn: async (data: { child_recipe_id: number; portions_needed: number; portions_needed_unit?: string }) => {
|
mutationFn: async (data: { child_recipe_id: number; portions_needed: number; portions_needed_unit?: string }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/sub-recipes`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/sub-recipes`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -554,7 +554,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const removeSubMutation = useMutation({
|
const removeSubMutation = useMutation({
|
||||||
mutationFn: async (srId: number) => {
|
mutationFn: async (srId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-sub-recipes/${srId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-sub-recipes/${srId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -570,7 +570,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const addStepMutation = useMutation({
|
const addStepMutation = useMutation({
|
||||||
mutationFn: async (data: { title?: string; instruction: string; step_number: number; duration_minutes?: number }) => {
|
mutationFn: async (data: { title?: string; instruction: string; step_number: number; duration_minutes?: number }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/steps`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/steps`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -588,7 +588,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const updateStepMutation = useMutation({
|
const updateStepMutation = useMutation({
|
||||||
mutationFn: async ({ stepId, data }: { stepId: number; data: { title?: string; instruction?: string; duration_minutes?: number } }) => {
|
mutationFn: async ({ stepId, data }: { stepId: number; data: { title?: string; instruction?: string; duration_minutes?: number } }) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-steps/${stepId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-steps/${stepId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -607,7 +607,7 @@ export default function RecipeEditor() {
|
||||||
|
|
||||||
const removeStepMutation = useMutation({
|
const removeStepMutation = useMutation({
|
||||||
mutationFn: async (stepId: number) => {
|
mutationFn: async (stepId: number) => {
|
||||||
const res = await fetch(`/api/recipes/recipe-steps/${stepId}`, {
|
const res = await fetch(`/kitchen/api/recipes/recipe-steps/${stepId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -623,7 +623,7 @@ export default function RecipeEditor() {
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
formData.append('caption', caption)
|
formData.append('caption', caption)
|
||||||
formData.append('image_type', image_type)
|
formData.append('image_type', image_type)
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/images`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/images`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -641,7 +641,7 @@ export default function RecipeEditor() {
|
||||||
// Delete image mutation
|
// Delete image mutation
|
||||||
const deleteImageMutation = useMutation({
|
const deleteImageMutation = useMutation({
|
||||||
mutationFn: async (imageId: number) => {
|
mutationFn: async (imageId: number) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/images/${imageId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/images/${imageId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -655,7 +655,7 @@ export default function RecipeEditor() {
|
||||||
// Batch reorder ingredients
|
// Batch reorder ingredients
|
||||||
const reorderIngMutation = useMutation({
|
const reorderIngMutation = useMutation({
|
||||||
mutationFn: async (ingredientIds: number[]) => {
|
mutationFn: async (ingredientIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/ingredients/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/ingredients/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ingredient_ids: ingredientIds }),
|
body: JSON.stringify({ ingredient_ids: ingredientIds }),
|
||||||
|
|
@ -670,7 +670,7 @@ export default function RecipeEditor() {
|
||||||
// Batch reorder sub-recipes
|
// Batch reorder sub-recipes
|
||||||
const reorderSubMutation = useMutation({
|
const reorderSubMutation = useMutation({
|
||||||
mutationFn: async (subRecipeIds: number[]) => {
|
mutationFn: async (subRecipeIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/sub-recipes/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/sub-recipes/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ sub_recipe_ids: subRecipeIds }),
|
body: JSON.stringify({ sub_recipe_ids: subRecipeIds }),
|
||||||
|
|
@ -685,7 +685,7 @@ export default function RecipeEditor() {
|
||||||
// Reorder steps mutation
|
// Reorder steps mutation
|
||||||
const reorderStepsMutation = useMutation({
|
const reorderStepsMutation = useMutation({
|
||||||
mutationFn: async (stepIds: number[]) => {
|
mutationFn: async (stepIds: number[]) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}/steps/reorder`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}/steps/reorder`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ step_ids: stepIds }),
|
body: JSON.stringify({ step_ids: stepIds }),
|
||||||
|
|
@ -769,7 +769,7 @@ export default function RecipeEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePrint = (format: string) => {
|
const handlePrint = (format: string) => {
|
||||||
window.open(`/api/recipes/${recipeId}/print?format=${format}&token=${token}`, '_blank')
|
window.open(`/kitchen/api/recipes/${recipeId}/print?format=${format}&token=${token}`, '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recipe) return <div style={styles.loading}>Loading recipe...</div>
|
if (!recipe) return <div style={styles.loading}>Loading recipe...</div>
|
||||||
|
|
@ -893,7 +893,7 @@ export default function RecipeEditor() {
|
||||||
style={{ marginLeft: 'auto', background: 'none', border: '1px solid #b4530955', borderRadius: '4px', color: '#b45309', cursor: 'pointer', padding: '0.15rem 0.5rem', fontSize: '0.8rem', whiteSpace: 'nowrap' }}
|
style={{ marginLeft: 'auto', background: 'none', border: '1px solid #b4530955', borderRadius: '4px', color: '#b45309', cursor: 'pointer', padding: '0.15rem 0.5rem', fontSize: '0.8rem', whiteSpace: 'nowrap' }}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/text-dismissals`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/text-dismissals`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
@ -1309,10 +1309,10 @@ export default function RecipeEditor() {
|
||||||
{recipe.images.map(img => (
|
{recipe.images.map(img => (
|
||||||
<div key={img.id} style={styles.imageCard}>
|
<div key={img.id} style={styles.imageCard}>
|
||||||
<img
|
<img
|
||||||
src={`/api/recipes/${recipeId}/images/${img.id}?token=${token}`}
|
src={`/kitchen/api/recipes/${recipeId}/images/${img.id}?token=${token}`}
|
||||||
alt={img.caption || 'Recipe image'}
|
alt={img.caption || 'Recipe image'}
|
||||||
style={{ ...styles.imageThumb, cursor: 'pointer' }}
|
style={{ ...styles.imageThumb, cursor: 'pointer' }}
|
||||||
onClick={() => setLightboxImg(`/api/recipes/${recipeId}/images/${img.id}?token=${token}`)}
|
onClick={() => setLightboxImg(`/kitchen/api/recipes/${recipeId}/images/${img.id}?token=${token}`)}
|
||||||
/>
|
/>
|
||||||
<div style={{ padding: '0.4rem' }}>
|
<div style={{ padding: '0.4rem' }}>
|
||||||
{img.caption && <div style={{ fontSize: '0.8rem', color: '#333', marginTop: '2px' }}>{img.caption}</div>}
|
{img.caption && <div style={{ fontSize: '0.8rem', color: '#333', marginTop: '2px' }}>{img.caption}</div>}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ export default function RecipeFlagMatrix({ recipeId, categoryId }: Props) {
|
||||||
const { data: rawData, isLoading } = useQuery<MatrixData>({
|
const { data: rawData, isLoading } = useQuery<MatrixData>({
|
||||||
queryKey: ['recipe-flag-matrix', recipeId],
|
queryKey: ['recipe-flag-matrix', recipeId],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/flags/matrix`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/flags/matrix`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch matrix')
|
if (!res.ok) throw new Error('Failed to fetch matrix')
|
||||||
|
|
@ -62,7 +62,7 @@ export default function RecipeFlagMatrix({ recipeId, categoryId }: Props) {
|
||||||
|
|
||||||
const toggleMutation = useMutation({
|
const toggleMutation = useMutation({
|
||||||
mutationFn: async ({ ingredientId, flagId, hasFlag }: { ingredientId: number; flagId: number; hasFlag: boolean }) => {
|
mutationFn: async ({ ingredientId, flagId, hasFlag }: { ingredientId: number; flagId: number; hasFlag: boolean }) => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/flags/matrix`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/flags/matrix`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ updates: [{ ingredient_id: ingredientId, food_flag_id: flagId, has_flag: hasFlag }] }),
|
body: JSON.stringify({ updates: [{ ingredient_id: ingredientId, food_flag_id: flagId, has_flag: hasFlag }] }),
|
||||||
|
|
@ -86,7 +86,7 @@ export default function RecipeFlagMatrix({ recipeId, categoryId }: Props) {
|
||||||
|
|
||||||
const toggleNoneMutation = useMutation({
|
const toggleNoneMutation = useMutation({
|
||||||
mutationFn: async ({ ingredientId, catId }: { ingredientId: number; catId: number }) => {
|
mutationFn: async ({ ingredientId, catId }: { ingredientId: number; catId: number }) => {
|
||||||
const res = await fetch(`/api/food-flags/recipes/${recipeId}/flags/matrix/none`, {
|
const res = await fetch(`/kitchen/api/food-flags/recipes/${recipeId}/flags/matrix/none`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ingredient_id: ingredientId, category_id: catId }),
|
body: JSON.stringify({ ingredient_id: ingredientId, category_id: catId }),
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export default function RecipeList() {
|
||||||
const { data: sections } = useQuery<MenuSection[]>({
|
const { data: sections } = useQuery<MenuSection[]>({
|
||||||
queryKey: ['recipe-sections'],
|
queryKey: ['recipe-sections'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=recipe', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=recipe', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch sections')
|
if (!res.ok) throw new Error('Failed to fetch sections')
|
||||||
|
|
@ -98,7 +98,7 @@ export default function RecipeList() {
|
||||||
if (search) params.set('search', search)
|
if (search) params.set('search', search)
|
||||||
if (sectionFilter) params.set('menu_section_id', sectionFilter)
|
if (sectionFilter) params.set('menu_section_id', sectionFilter)
|
||||||
if (showArchived) params.set('archived', 'true')
|
if (showArchived) params.set('archived', 'true')
|
||||||
const res = await fetch(`/api/recipes?${params}`, {
|
const res = await fetch(`/kitchen/api/recipes?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch recipes')
|
if (!res.ok) throw new Error('Failed to fetch recipes')
|
||||||
|
|
@ -109,7 +109,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/recipes', {
|
const res = await fetch('/kitchen/api/recipes', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -126,7 +126,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const duplicateMutation = useMutation({
|
const duplicateMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}/duplicate`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}/duplicate`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -141,7 +141,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const archiveMutation = useMutation({
|
const archiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -152,7 +152,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const unarchiveMutation = useMutation({
|
const unarchiveMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ is_archived: false }),
|
body: JSON.stringify({ is_archived: false }),
|
||||||
|
|
@ -164,7 +164,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const createSectionMutation = useMutation({
|
const createSectionMutation = useMutation({
|
||||||
mutationFn: async (name: string) => {
|
mutationFn: async (name: string) => {
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'recipe' }),
|
body: JSON.stringify({ name, section_type: 'recipe' }),
|
||||||
|
|
@ -181,7 +181,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const updateSectionMutation = useMutation({
|
const updateSectionMutation = useMutation({
|
||||||
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
mutationFn: async ({ id, name }: { id: number; name: string }) => {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name }),
|
body: JSON.stringify({ name }),
|
||||||
|
|
@ -199,7 +199,7 @@ export default function RecipeList() {
|
||||||
|
|
||||||
const deleteSectionMutation = useMutation({
|
const deleteSectionMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${id}`, {
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -215,7 +215,7 @@ export default function RecipeList() {
|
||||||
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; flags: Array<{ id: number; name: string; code: string | null }> }>>({
|
const { data: flagCategories } = useQuery<Array<{ id: number; name: string; flags: Array<{ id: number; name: string; code: string | null }> }>>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
if (!res.ok) throw new Error('Failed to fetch flag categories')
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ export default function ReconcilePurchases() {
|
||||||
mutationFn: async (file: File) => {
|
mutationFn: async (file: File) => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
const res = await fetch('/api/reports/purchases/reconcile', {
|
const res = await fetch('/kitchen/api/reports/purchases/reconcile', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
|
||||||
|
|
@ -541,7 +541,7 @@ export default function Review() {
|
||||||
const { data: invoice, isLoading, refetch: refetchInvoice } = useQuery<Invoice>({
|
const { data: invoice, isLoading, refetch: refetchInvoice } = useQuery<Invoice>({
|
||||||
queryKey: ['invoice', id],
|
queryKey: ['invoice', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch invoice')
|
if (!res.ok) throw new Error('Failed to fetch invoice')
|
||||||
|
|
@ -553,13 +553,13 @@ export default function Review() {
|
||||||
|
|
||||||
// Direct URL with token - simpler approach
|
// Direct URL with token - simpler approach
|
||||||
const imageUrl = invoice
|
const imageUrl = invoice
|
||||||
? `/api/invoices/${id}/file?token=${encodeURIComponent(token || '')}#toolbar=0&navpanes=0&view=FitH`
|
? `/kitchen/api/invoices/${id}/file?token=${encodeURIComponent(token || '')}#toolbar=0&navpanes=0&view=FitH`
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const { data: lineItems, refetch: refetchLineItems } = useQuery<LineItem[]>({
|
const { data: lineItems, refetch: refetchLineItems } = useQuery<LineItem[]>({
|
||||||
queryKey: ['invoice-line-items', id],
|
queryKey: ['invoice-line-items', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch line items')
|
if (!res.ok) throw new Error('Failed to fetch line items')
|
||||||
|
|
@ -576,7 +576,7 @@ export default function Review() {
|
||||||
}>>({
|
}>>({
|
||||||
queryKey: ['invoice-stock-history', id],
|
queryKey: ['invoice-stock-history', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}/stock-history`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/stock-history`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch stock history')
|
if (!res.ok) throw new Error('Failed to fetch stock history')
|
||||||
|
|
@ -588,7 +588,7 @@ export default function Review() {
|
||||||
const { data: duplicateInfo } = useQuery<DuplicateCompare>({
|
const { data: duplicateInfo } = useQuery<DuplicateCompare>({
|
||||||
queryKey: ['invoice-duplicates', id],
|
queryKey: ['invoice-duplicates', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}/duplicates`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/duplicates`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch duplicates')
|
if (!res.ok) throw new Error('Failed to fetch duplicates')
|
||||||
|
|
@ -600,7 +600,7 @@ export default function Review() {
|
||||||
const { data: rawOcrData } = useQuery<{ raw_json: any; raw_text: string }>({
|
const { data: rawOcrData } = useQuery<{ raw_json: any; raw_text: string }>({
|
||||||
queryKey: ['invoice-ocr-data', id],
|
queryKey: ['invoice-ocr-data', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}/ocr-data`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/ocr-data`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch OCR data')
|
if (!res.ok) throw new Error('Failed to fetch OCR data')
|
||||||
|
|
@ -612,7 +612,7 @@ export default function Review() {
|
||||||
const { data: settings } = useQuery<Settings>({
|
const { data: settings } = useQuery<Settings>({
|
||||||
queryKey: ['settings'],
|
queryKey: ['settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch settings')
|
if (!res.ok) throw new Error('Failed to fetch settings')
|
||||||
|
|
@ -637,7 +637,7 @@ export default function Review() {
|
||||||
const uniqueItems = Array.from(new Map(items.map(i => [i.description.toLowerCase(), i])).values())
|
const uniqueItems = Array.from(new Map(items.map(i => [i.description.toLowerCase(), i])).values())
|
||||||
if (uniqueItems.length === 0) return
|
if (uniqueItems.length === 0) return
|
||||||
|
|
||||||
fetch('/api/ingredients/sources/alias-suggestions', {
|
fetch('/kitchen/api/ingredients/sources/alias-suggestions', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ supplier_id: parseInt(supplierId), items: uniqueItems }),
|
body: JSON.stringify({ supplier_id: parseInt(supplierId), items: uniqueItems }),
|
||||||
|
|
@ -885,7 +885,7 @@ export default function Review() {
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -915,7 +915,7 @@ export default function Review() {
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['po-match', id],
|
queryKey: ['po-match', id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/purchase-orders/matching/for-invoice?invoice_id=${id}`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/matching/for-invoice?invoice_id=${id}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { matches: [], linked_po: null }
|
if (!res.ok) return { matches: [], linked_po: null }
|
||||||
|
|
@ -944,7 +944,7 @@ export default function Review() {
|
||||||
|
|
||||||
const pollInterval = setInterval(async () => {
|
const pollInterval = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
const checkRes = await fetch(`/api/invoices/${id}`, {
|
const checkRes = await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (checkRes.ok) {
|
if (checkRes.ok) {
|
||||||
|
|
@ -971,7 +971,7 @@ export default function Review() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch the PDF
|
// Fetch the PDF
|
||||||
const pdfUrl = `/api/invoices/${id}/file?token=${encodeURIComponent(token)}`
|
const pdfUrl = `/kitchen/api/invoices/${id}/file?token=${encodeURIComponent(token)}`
|
||||||
const response = await fetch(pdfUrl)
|
const response = await fetch(pdfUrl)
|
||||||
const arrayBuffer = await response.arrayBuffer()
|
const arrayBuffer = await response.arrayBuffer()
|
||||||
|
|
||||||
|
|
@ -1041,7 +1041,7 @@ export default function Review() {
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: Partial<Invoice>) => {
|
mutationFn: async (data: Partial<Invoice>) => {
|
||||||
const res = await fetch(`/api/invoices/${id}`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1067,7 +1067,7 @@ export default function Review() {
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${id}`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1082,7 +1082,7 @@ export default function Review() {
|
||||||
|
|
||||||
const updateLineItemMutation = useMutation({
|
const updateLineItemMutation = useMutation({
|
||||||
mutationFn: async ({ itemId, data }: { itemId: number; data: Partial<LineItem> }) => {
|
mutationFn: async ({ itemId, data }: { itemId: number; data: Partial<LineItem> }) => {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items/${itemId}`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items/${itemId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1104,7 +1104,7 @@ export default function Review() {
|
||||||
|
|
||||||
const createLineItemMutation = useMutation({
|
const createLineItemMutation = useMutation({
|
||||||
mutationFn: async (data: Partial<LineItem>) => {
|
mutationFn: async (data: Partial<LineItem>) => {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1125,7 +1125,7 @@ export default function Review() {
|
||||||
|
|
||||||
const deleteLineItemMutation = useMutation({
|
const deleteLineItemMutation = useMutation({
|
||||||
mutationFn: async (itemId: number) => {
|
mutationFn: async (itemId: number) => {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items/${itemId}`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items/${itemId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1143,7 +1143,7 @@ export default function Review() {
|
||||||
|
|
||||||
const saveDefinitionMutation = useMutation({
|
const saveDefinitionMutation = useMutation({
|
||||||
mutationFn: async ({ itemId, portionDesc }: { itemId: number; portionDesc?: string }) => {
|
mutationFn: async ({ itemId, portionDesc }: { itemId: number; portionDesc?: string }) => {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items/${itemId}/save-definition`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items/${itemId}/save-definition`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1161,7 +1161,7 @@ export default function Review() {
|
||||||
|
|
||||||
const createSupplierMutation = useMutation({
|
const createSupplierMutation = useMutation({
|
||||||
mutationFn: async (name: string) => {
|
mutationFn: async (name: string) => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1182,7 +1182,7 @@ export default function Review() {
|
||||||
|
|
||||||
const addAliasMutation = useMutation({
|
const addAliasMutation = useMutation({
|
||||||
mutationFn: async ({ supplierId, alias, invoiceId }: { supplierId: number; alias: string; invoiceId?: number }) => {
|
mutationFn: async ({ supplierId, alias, invoiceId }: { supplierId: number; alias: string; invoiceId?: number }) => {
|
||||||
const res = await fetch(`/api/suppliers/${supplierId}/aliases`, {
|
const res = await fetch(`/kitchen/api/suppliers/${supplierId}/aliases`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1201,7 +1201,7 @@ export default function Review() {
|
||||||
|
|
||||||
const addDescriptionAliasMutation = useMutation({
|
const addDescriptionAliasMutation = useMutation({
|
||||||
mutationFn: async ({ sourceId, alias }: { sourceId: number; alias: string }) => {
|
mutationFn: async ({ sourceId, alias }: { sourceId: number; alias: string }) => {
|
||||||
const res = await fetch(`/api/ingredients/sources/${sourceId}/aliases`, {
|
const res = await fetch(`/kitchen/api/ingredients/sources/${sourceId}/aliases`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1228,7 +1228,7 @@ export default function Review() {
|
||||||
// PO link/unlink handlers
|
// PO link/unlink handlers
|
||||||
const handleLinkPo = async (poId: number) => {
|
const handleLinkPo = async (poId: number) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/purchase-orders/${poId}/link`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/${poId}/link`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ invoice_id: parseInt(id!) }),
|
body: JSON.stringify({ invoice_id: parseInt(id!) }),
|
||||||
|
|
@ -1242,7 +1242,7 @@ export default function Review() {
|
||||||
|
|
||||||
const handleUnlinkPo = async (poId: number) => {
|
const handleUnlinkPo = async (poId: number) => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/purchase-orders/${poId}/unlink`, {
|
const res = await fetch(`/kitchen/api/purchase-orders/${poId}/unlink`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1386,7 +1386,7 @@ export default function Review() {
|
||||||
setAdminOperationResult(null)
|
setAdminOperationResult(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/mark-dext-sent`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/mark-dext-sent`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1423,7 +1423,7 @@ export default function Review() {
|
||||||
setAdminOperationResult(null)
|
setAdminOperationResult(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/reprocess`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/reprocess`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1457,7 +1457,7 @@ export default function Review() {
|
||||||
setShowDatePickerModal(true)
|
setShowDatePickerModal(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/parse-dates`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/parse-dates`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -1485,7 +1485,7 @@ export default function Review() {
|
||||||
setInvoiceNumberExamples([])
|
setInvoiceNumberExamples([])
|
||||||
setShowInvoiceNumberModal(true)
|
setShowInvoiceNumberModal(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/parse-invoice-number`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/parse-invoice-number`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to search for invoice number')
|
if (!res.ok) throw new Error('Failed to search for invoice number')
|
||||||
|
|
@ -1513,7 +1513,7 @@ export default function Review() {
|
||||||
setAdminOperationResult(null)
|
setAdminOperationResult(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/resend-to-azure`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/resend-to-azure`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1532,7 +1532,7 @@ export default function Review() {
|
||||||
// Poll for completion
|
// Poll for completion
|
||||||
const pollInterval = setInterval(async () => {
|
const pollInterval = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
const checkRes = await fetch(`/api/invoices/${id}`, {
|
const checkRes = await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (checkRes.ok) {
|
if (checkRes.ok) {
|
||||||
|
|
@ -1565,7 +1565,7 @@ export default function Review() {
|
||||||
setAdminOperationResult(null)
|
setAdminOperationResult(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/regenerate-highlights`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/regenerate-highlights`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1756,7 +1756,7 @@ export default function Review() {
|
||||||
if (!query || query.length < 2) return
|
if (!query || query.length < 2) return
|
||||||
setSearchLoading(true)
|
setSearchLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/invoices/line-items/search', {
|
const res = await fetch('/kitchen/api/invoices/line-items/search', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -1781,7 +1781,7 @@ export default function Review() {
|
||||||
try {
|
try {
|
||||||
// Update all line items
|
// Update all line items
|
||||||
const promises = lineItems.map(item =>
|
const promises = lineItems.map(item =>
|
||||||
fetch(`/api/invoices/${id}/line-items/${item.id}`, {
|
fetch(`/kitchen/api/invoices/${id}/line-items/${item.id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1805,7 +1805,7 @@ export default function Review() {
|
||||||
setAiMatchLoading(true)
|
setAiMatchLoading(true)
|
||||||
setAiMatchResults([])
|
setAiMatchResults([])
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/ai-match?description=${encodeURIComponent(description)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/ai-match?description=${encodeURIComponent(description)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -1827,7 +1827,7 @@ export default function Review() {
|
||||||
setAiDismissedCorrections(new Set())
|
setAiDismissedCorrections(new Set())
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/ai-assist`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/ai-assist`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1906,7 +1906,7 @@ export default function Review() {
|
||||||
// Fetch saved definition
|
// Fetch saved definition
|
||||||
setDefinitionLoading(true)
|
setDefinitionLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/line-items/${item.id}/definition`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/line-items/${item.id}/definition`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -1927,7 +1927,7 @@ export default function Review() {
|
||||||
if (!item.pack_quantity && !item.unit_size) {
|
if (!item.pack_quantity && !item.unit_size) {
|
||||||
setAiPackSizeLoading(true)
|
setAiPackSizeLoading(true)
|
||||||
try {
|
try {
|
||||||
const packRes = await fetch(`/api/invoices/${id}/line-items/${item.id}/ai-pack-size`, {
|
const packRes = await fetch(`/kitchen/api/invoices/${id}/line-items/${item.id}/ai-pack-size`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (packRes.ok) {
|
if (packRes.ok) {
|
||||||
|
|
@ -1961,7 +1961,7 @@ export default function Review() {
|
||||||
}
|
}
|
||||||
setIngredientSearchLoading(true)
|
setIngredientSearchLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/suggest?description=${encodeURIComponent(query)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/suggest?description=${encodeURIComponent(query)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -2053,7 +2053,7 @@ export default function Review() {
|
||||||
if (selectedIngredientId) {
|
if (selectedIngredientId) {
|
||||||
try {
|
try {
|
||||||
// Set ingredient_id on line item
|
// Set ingredient_id on line item
|
||||||
await fetch(`/api/invoices/${id}/line-items/${itemId}`, {
|
await fetch(`/kitchen/api/invoices/${id}/line-items/${itemId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ ingredient_id: selectedIngredientId }),
|
body: JSON.stringify({ ingredient_id: selectedIngredientId }),
|
||||||
|
|
@ -2081,7 +2081,7 @@ export default function Review() {
|
||||||
if (id) {
|
if (id) {
|
||||||
sourceData.invoice_id = parseInt(id as string)
|
sourceData.invoice_id = parseInt(id as string)
|
||||||
}
|
}
|
||||||
const srcRes = await fetch(`/api/ingredients/${selectedIngredientId}/sources`, {
|
const srcRes = await fetch(`/kitchen/api/ingredients/${selectedIngredientId}/sources`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(sourceData),
|
body: JSON.stringify(sourceData),
|
||||||
|
|
@ -2610,7 +2610,7 @@ export default function Review() {
|
||||||
)}
|
)}
|
||||||
{isPDF && imageUrl && (
|
{isPDF && imageUrl && (
|
||||||
<a
|
<a
|
||||||
href={`/api/invoices/${id}/file?token=${encodeURIComponent(token || '')}`}
|
href={`/kitchen/api/invoices/${id}/file?token=${encodeURIComponent(token || '')}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
style={styles.openPdfLink}
|
style={styles.openPdfLink}
|
||||||
|
|
@ -3092,7 +3092,7 @@ export default function Review() {
|
||||||
onChange={(e) => setInvoiceNotes(e.target.value)}
|
onChange={(e) => setInvoiceNotes(e.target.value)}
|
||||||
onBlur={async () => {
|
onBlur={async () => {
|
||||||
try {
|
try {
|
||||||
await fetch(`/api/invoices/${id}`, {
|
await fetch(`/kitchen/api/invoices/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -4673,7 +4673,7 @@ export default function Review() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/invoices/${id}/send-to-dext`, {
|
const res = await fetch(`/kitchen/api/invoices/${id}/send-to-dext`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export default function SalesGPReport() {
|
||||||
const { data: report, isLoading, error } = useQuery<SalesGPResponse>({
|
const { data: report, isLoading, error } = useQuery<SalesGPResponse>({
|
||||||
queryKey: ['sales-gp', submittedFrom, submittedTo],
|
queryKey: ['sales-gp', submittedFrom, submittedTo],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/reports/sales-gp?from_date=${submittedFrom}&to_date=${submittedTo}`, {
|
const res = await fetch(`/kitchen/api/reports/sales-gp?from_date=${submittedFrom}&to_date=${submittedTo}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -91,7 +91,7 @@ export default function SalesGPReport() {
|
||||||
const { data: dishRecipes } = useQuery<DishRecipe[]>({
|
const { data: dishRecipes } = useQuery<DishRecipe[]>({
|
||||||
queryKey: ['recipes-for-mapping', recipeSearch],
|
queryKey: ['recipes-for-mapping', recipeSearch],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const url = `/api/recipes?recipe_type=dish${recipeSearch ? `&search=${encodeURIComponent(recipeSearch)}` : ''}`
|
const url = `/kitchen/api/recipes?recipe_type=dish${recipeSearch ? `&search=${encodeURIComponent(recipeSearch)}` : ''}`
|
||||||
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } })
|
||||||
return res.json()
|
return res.json()
|
||||||
},
|
},
|
||||||
|
|
@ -101,7 +101,7 @@ export default function SalesGPReport() {
|
||||||
// Map unmapped item to recipe
|
// Map unmapped item to recipe
|
||||||
const mapMutation = useMutation({
|
const mapMutation = useMutation({
|
||||||
mutationFn: async ({ recipeId, menuItemName, portionName }: { recipeId: number; menuItemName: string; portionName: string }) => {
|
mutationFn: async ({ recipeId, menuItemName, portionName }: { recipeId: number; menuItemName: string; portionName: string }) => {
|
||||||
const res = await fetch(`/api/recipes/${recipeId}`, {
|
const res = await fetch(`/kitchen/api/recipes/${recipeId}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ export default function SearchDefinitions() {
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -123,7 +123,7 @@ export default function SearchDefinitions() {
|
||||||
if (hasPortions === 'no') params.set('has_portions', 'false')
|
if (hasPortions === 'no') params.set('has_portions', 'false')
|
||||||
params.set('limit', '200')
|
params.set('limit', '200')
|
||||||
|
|
||||||
const res = await fetch(`/api/search/definitions?${params}`, {
|
const res = await fetch(`/kitchen/api/search/definitions?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Search failed')
|
if (!res.ok) throw new Error('Search failed')
|
||||||
|
|
@ -136,7 +136,7 @@ export default function SearchDefinitions() {
|
||||||
const { data: lineItems } = useQuery<LineItem[]>({
|
const { data: lineItems } = useQuery<LineItem[]>({
|
||||||
queryKey: ['invoice-line-items', editingDef?.source_invoice_id],
|
queryKey: ['invoice-line-items', editingDef?.source_invoice_id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${editingDef!.source_invoice_id}/line-items`, {
|
const res = await fetch(`/kitchen/api/invoices/${editingDef!.source_invoice_id}/line-items`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch line items')
|
if (!res.ok) throw new Error('Failed to fetch line items')
|
||||||
|
|
@ -149,7 +149,7 @@ export default function SearchDefinitions() {
|
||||||
const { data: ocrData } = useQuery<OcrData>({
|
const { data: ocrData } = useQuery<OcrData>({
|
||||||
queryKey: ['invoice-ocr-data', editingDef?.source_invoice_id],
|
queryKey: ['invoice-ocr-data', editingDef?.source_invoice_id],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/invoices/${editingDef!.source_invoice_id}/ocr-data`, {
|
const res = await fetch(`/kitchen/api/invoices/${editingDef!.source_invoice_id}/ocr-data`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch OCR data')
|
if (!res.ok) throw new Error('Failed to fetch OCR data')
|
||||||
|
|
@ -161,7 +161,7 @@ export default function SearchDefinitions() {
|
||||||
// Update definition mutation
|
// Update definition mutation
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: { id: number; updates: typeof editFormData }) => {
|
mutationFn: async (data: { id: number; updates: typeof editFormData }) => {
|
||||||
const res = await fetch(`/api/search/definitions/${data.id}`, {
|
const res = await fetch(`/kitchen/api/search/definitions/${data.id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -191,7 +191,7 @@ export default function SearchDefinitions() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = `/api/invoices/${editingDef.source_invoice_id}/image`
|
const url = `/kitchen/api/invoices/${editingDef.source_invoice_id}/image`
|
||||||
setInvoiceImageUrl(url)
|
setInvoiceImageUrl(url)
|
||||||
|
|
||||||
// Check if PDF by fetching headers
|
// Check if PDF by fetching headers
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ export default function SearchInvoices() {
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -103,7 +103,7 @@ export default function SearchInvoices() {
|
||||||
if (groupBy) params.set('group_by', groupBy)
|
if (groupBy) params.set('group_by', groupBy)
|
||||||
params.set('limit', '200')
|
params.set('limit', '200')
|
||||||
|
|
||||||
const res = await fetch(`/api/search/invoices?${params}`, {
|
const res = await fetch(`/kitchen/api/search/invoices?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Search failed')
|
if (!res.ok) throw new Error('Search failed')
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ export default function SearchLineItems() {
|
||||||
const { data: suppliers } = useQuery<Supplier[]>({
|
const { data: suppliers } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -156,7 +156,7 @@ export default function SearchLineItems() {
|
||||||
const { data: _searchSettings } = useQuery<SearchSettings>({
|
const { data: _searchSettings } = useQuery<SearchSettings>({
|
||||||
queryKey: ['search-settings'],
|
queryKey: ['search-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/search/settings', {
|
const res = await fetch('/kitchen/api/search/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch search settings')
|
if (!res.ok) throw new Error('Failed to fetch search settings')
|
||||||
|
|
@ -178,7 +178,7 @@ export default function SearchLineItems() {
|
||||||
if (mappedFilter) params.set('mapped', mappedFilter)
|
if (mappedFilter) params.set('mapped', mappedFilter)
|
||||||
params.set('limit', '200')
|
params.set('limit', '200')
|
||||||
|
|
||||||
const res = await fetch(`/api/search/line-items?${params}`, {
|
const res = await fetch(`/kitchen/api/search/line-items?${params}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Search failed')
|
if (!res.ok) throw new Error('Search failed')
|
||||||
|
|
@ -205,7 +205,7 @@ export default function SearchLineItems() {
|
||||||
|
|
||||||
const allSuggestions: typeof aliasSuggestions = {}
|
const allSuggestions: typeof aliasSuggestions = {}
|
||||||
const promises = Array.from(bySupplier.entries()).map(([sid, items]) =>
|
const promises = Array.from(bySupplier.entries()).map(([sid, items]) =>
|
||||||
fetch('/api/ingredients/sources/alias-suggestions', {
|
fetch('/kitchen/api/ingredients/sources/alias-suggestions', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ supplier_id: sid, items }),
|
body: JSON.stringify({ supplier_id: sid, items }),
|
||||||
|
|
@ -223,7 +223,7 @@ export default function SearchLineItems() {
|
||||||
|
|
||||||
const addDescriptionAliasMutation = useMutation({
|
const addDescriptionAliasMutation = useMutation({
|
||||||
mutationFn: async ({ sourceId, alias }: { sourceId: number; alias: string }) => {
|
mutationFn: async ({ sourceId, alias }: { sourceId: number; alias: string }) => {
|
||||||
const res = await fetch(`/api/ingredients/sources/${sourceId}/aliases`, {
|
const res = await fetch(`/kitchen/api/ingredients/sources/${sourceId}/aliases`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -300,7 +300,7 @@ export default function SearchLineItems() {
|
||||||
}
|
}
|
||||||
setIngredientSearchLoading(true)
|
setIngredientSearchLoading(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/ingredients/suggest?description=${encodeURIComponent(query)}`, {
|
const res = await fetch(`/kitchen/api/ingredients/suggest?description=${encodeURIComponent(query)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) setIngredientSuggestions(await res.json())
|
if (res.ok) setIngredientSuggestions(await res.json())
|
||||||
|
|
@ -371,7 +371,7 @@ export default function SearchLineItems() {
|
||||||
try {
|
try {
|
||||||
// Update the most recent line item's pack fields if we have one
|
// Update the most recent line item's pack fields if we have one
|
||||||
if (modalItem.most_recent_line_item_id && modalItem.most_recent_invoice_id) {
|
if (modalItem.most_recent_line_item_id && modalItem.most_recent_invoice_id) {
|
||||||
await fetch(`/api/invoices/${modalItem.most_recent_invoice_id}/line-items/${modalItem.most_recent_line_item_id}`, {
|
await fetch(`/kitchen/api/invoices/${modalItem.most_recent_invoice_id}/line-items/${modalItem.most_recent_line_item_id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
@ -399,7 +399,7 @@ export default function SearchLineItems() {
|
||||||
if (costEdits.unit_price) sourceData.latest_unit_price = costEdits.unit_price
|
if (costEdits.unit_price) sourceData.latest_unit_price = costEdits.unit_price
|
||||||
if (modalItem.most_recent_invoice_id) sourceData.invoice_id = modalItem.most_recent_invoice_id
|
if (modalItem.most_recent_invoice_id) sourceData.invoice_id = modalItem.most_recent_invoice_id
|
||||||
|
|
||||||
await fetch(`/api/ingredients/${selectedIngredientId}/sources`, {
|
await fetch(`/kitchen/api/ingredients/${selectedIngredientId}/sources`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(sourceData),
|
body: JSON.stringify(sourceData),
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ export default function Suppliers() {
|
||||||
const { data: suppliers, isLoading } = useQuery<Supplier[]>({
|
const { data: suppliers, isLoading } = useQuery<Supplier[]>({
|
||||||
queryKey: ['suppliers'],
|
queryKey: ['suppliers'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
if (!res.ok) throw new Error('Failed to fetch suppliers')
|
||||||
|
|
@ -41,7 +41,7 @@ export default function Suppliers() {
|
||||||
|
|
||||||
const createMutation = useMutation({
|
const createMutation = useMutation({
|
||||||
mutationFn: async ({ name, aliases, skip_dext, order_email, account_number }: { name: string; aliases: string[]; skip_dext: boolean; order_email: string; account_number: string }) => {
|
mutationFn: async ({ name, aliases, skip_dext, order_email, account_number }: { name: string; aliases: string[]; skip_dext: boolean; order_email: string; account_number: string }) => {
|
||||||
const res = await fetch('/api/suppliers/', {
|
const res = await fetch('/kitchen/api/suppliers/', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -66,7 +66,7 @@ export default function Suppliers() {
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async ({ id, name, aliases, skip_dext, order_email, account_number }: { id: number; name: string; aliases: string[]; skip_dext: boolean; order_email: string; account_number: string }) => {
|
mutationFn: async ({ id, name, aliases, skip_dext, order_email, account_number }: { id: number; name: string; aliases: string[]; skip_dext: boolean; order_email: string; account_number: string }) => {
|
||||||
const res = await fetch(`/api/suppliers/${id}`, {
|
const res = await fetch(`/kitchen/api/suppliers/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -91,7 +91,7 @@ export default function Suppliers() {
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/suppliers/${id}`, {
|
const res = await fetch(`/kitchen/api/suppliers/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ export default function SupportButton() {
|
||||||
const { data: supportStatus } = useQuery<SupportEnabledResponse>({
|
const { data: supportStatus } = useQuery<SupportEnabledResponse>({
|
||||||
queryKey: ['support-enabled'],
|
queryKey: ['support-enabled'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/support/enabled', {
|
const res = await fetch('/kitchen/api/support/enabled', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { enabled: false }
|
if (!res.ok) return { enabled: false }
|
||||||
|
|
@ -31,7 +31,7 @@ export default function SupportButton() {
|
||||||
// Submit support request
|
// Submit support request
|
||||||
const submitMutation = useMutation({
|
const submitMutation = useMutation({
|
||||||
mutationFn: async (data: { description: string; screenshot: string }) => {
|
mutationFn: async (data: { description: string; screenshot: string }) => {
|
||||||
const res = await fetch('/api/support/request', {
|
const res = await fetch('/kitchen/api/support/request', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ export default function Upload() {
|
||||||
item.id === queueId ? { ...item, status: 'processing' as const } : item
|
item.id === queueId ? { ...item, status: 'processing' as const } : item
|
||||||
))
|
))
|
||||||
|
|
||||||
const res = await fetch('/api/invoices/upload', {
|
const res = await fetch('/kitchen/api/invoices/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ export default function UsageVarianceReport() {
|
||||||
setError(null)
|
setError(null)
|
||||||
try {
|
try {
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`/api/reports/usage-variance?from_date=${fromDate}&to_date=${toDate}`,
|
`/kitchen/api/reports/usage-variance?from_date=${fromDate}&to_date=${toDate}`,
|
||||||
{ headers: { Authorization: `Bearer ${token}` } }
|
{ headers: { Authorization: `Bearer ${token}` } }
|
||||||
)
|
)
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ export default function BookingsStats() {
|
||||||
const { data: stats, isLoading } = useQuery<StatsData>({
|
const { data: stats, isLoading } = useQuery<StatsData>({
|
||||||
queryKey: ['resos-stats', submittedFromDate, submittedToDate],
|
queryKey: ['resos-stats', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/resos/stats?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
const res = await fetch(`/kitchen/api/resos/stats?from_date=${submittedFromDate}&to_date=${submittedToDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch stats')
|
if (!res.ok) throw new Error('Failed to fetch stats')
|
||||||
|
|
@ -182,7 +182,7 @@ export default function BookingsStats() {
|
||||||
queryKey: ['resos-stats-previous', submittedFromDate, submittedToDate],
|
queryKey: ['resos-stats-previous', submittedFromDate, submittedToDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const prevDates = getPreviousPeriodDates()
|
const prevDates = getPreviousPeriodDates()
|
||||||
const res = await fetch(`/api/resos/stats?from_date=${prevDates.from}&to_date=${prevDates.to}`, {
|
const res = await fetch(`/kitchen/api/resos/stats?from_date=${prevDates.from}&to_date=${prevDates.to}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch previous stats')
|
if (!res.ok) throw new Error('Failed to fetch previous stats')
|
||||||
|
|
@ -195,7 +195,7 @@ export default function BookingsStats() {
|
||||||
const { data: selectedDayBookings } = useQuery<Booking[]>({
|
const { data: selectedDayBookings } = useQuery<Booking[]>({
|
||||||
queryKey: ['resos-bookings', selectedDate],
|
queryKey: ['resos-bookings', selectedDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/resos/bookings/${selectedDate}`, {
|
const res = await fetch(`/kitchen/api/resos/bookings/${selectedDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch bookings')
|
if (!res.ok) throw new Error('Failed to fetch bookings')
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ export default function NewbookData() {
|
||||||
const { data: settings } = useQuery<Settings>({
|
const { data: settings } = useQuery<Settings>({
|
||||||
queryKey: ['settings'],
|
queryKey: ['settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch settings')
|
if (!res.ok) throw new Error('Failed to fetch settings')
|
||||||
|
|
@ -65,7 +65,7 @@ export default function NewbookData() {
|
||||||
const { data: calendarData, isLoading } = useQuery<CalendarData>({
|
const { data: calendarData, isLoading } = useQuery<CalendarData>({
|
||||||
queryKey: ['newbook-calendar', year, month],
|
queryKey: ['newbook-calendar', year, month],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/newbook/calendar/${year}/${month}`, {
|
const res = await fetch(`/kitchen/api/newbook/calendar/${year}/${month}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch calendar data')
|
if (!res.ok) throw new Error('Failed to fetch calendar data')
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export default function ResidentsTableChart() {
|
||||||
const { data, isLoading } = useQuery<ChartData>({
|
const { data, isLoading } = useQuery<ChartData>({
|
||||||
queryKey: ['residents-table-chart', 'v2', startDate], // v2 to invalidate old cache
|
queryKey: ['residents-table-chart', 'v2', startDate], // v2 to invalidate old cache
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/residents-table-chart?start_date=${startDate}`, {
|
const res = await fetch(`/kitchen/api/residents-table-chart?start_date=${startDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch chart data')
|
if (!res.ok) throw new Error('Failed to fetch chart data')
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ export default function ResosData() {
|
||||||
const { data: settings } = useQuery<ResosSettings>({
|
const { data: settings } = useQuery<ResosSettings>({
|
||||||
queryKey: ['resos-settings'],
|
queryKey: ['resos-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/resos/settings', {
|
const res = await fetch('/kitchen/api/resos/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch settings')
|
if (!res.ok) throw new Error('Failed to fetch settings')
|
||||||
|
|
@ -132,7 +132,7 @@ export default function ResosData() {
|
||||||
const lastDay = new Date(year, month, 0)
|
const lastDay = new Date(year, month, 0)
|
||||||
const toDate = `${year}-${String(month).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
const toDate = `${year}-${String(month).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
||||||
|
|
||||||
const res = await fetch(`/api/resos/daily-stats?from_date=${firstDay}&to_date=${toDate}`, {
|
const res = await fetch(`/kitchen/api/resos/daily-stats?from_date=${firstDay}&to_date=${toDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch daily stats')
|
if (!res.ok) throw new Error('Failed to fetch daily stats')
|
||||||
|
|
@ -151,7 +151,7 @@ export default function ResosData() {
|
||||||
const lastDay = new Date(prevYear, prevMonth, 0)
|
const lastDay = new Date(prevYear, prevMonth, 0)
|
||||||
const toDate = `${prevYear}-${String(prevMonth).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
const toDate = `${prevYear}-${String(prevMonth).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
||||||
|
|
||||||
const res = await fetch(`/api/resos/daily-stats?from_date=${firstDay}&to_date=${toDate}`, {
|
const res = await fetch(`/kitchen/api/resos/daily-stats?from_date=${firstDay}&to_date=${toDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch previous month stats')
|
if (!res.ok) throw new Error('Failed to fetch previous month stats')
|
||||||
|
|
@ -167,7 +167,7 @@ export default function ResosData() {
|
||||||
const firstDay = `${year}-${String(month).padStart(2, '0')}-01`
|
const firstDay = `${year}-${String(month).padStart(2, '0')}-01`
|
||||||
const lastDay = new Date(year, month, 0)
|
const lastDay = new Date(year, month, 0)
|
||||||
const toDate = `${year}-${String(month).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
const toDate = `${year}-${String(month).padStart(2, '0')}-${String(lastDay.getDate()).padStart(2, '0')}`
|
||||||
const res = await fetch(`/api/calendar-events/?from_date=${firstDay}&to_date=${toDate}`, {
|
const res = await fetch(`/kitchen/api/calendar-events/?from_date=${firstDay}&to_date=${toDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch calendar events')
|
if (!res.ok) throw new Error('Failed to fetch calendar events')
|
||||||
|
|
@ -181,7 +181,7 @@ export default function ResosData() {
|
||||||
queryKey: ['resos-bookings', selectedDate],
|
queryKey: ['resos-bookings', selectedDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!selectedDate) return []
|
if (!selectedDate) return []
|
||||||
const res = await fetch(`/api/resos/bookings/${selectedDate}`, {
|
const res = await fetch(`/kitchen/api/resos/bookings/${selectedDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch bookings')
|
if (!res.ok) throw new Error('Failed to fetch bookings')
|
||||||
|
|
@ -194,7 +194,7 @@ export default function ResosData() {
|
||||||
const { data: allOpeningHoursData } = useQuery<{ opening_hours: any[] }>({
|
const { data: allOpeningHoursData } = useQuery<{ opening_hours: any[] }>({
|
||||||
queryKey: ['resos-all-opening-hours'],
|
queryKey: ['resos-all-opening-hours'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch(`/api/resos/opening-hours`, {
|
const res = await fetch(`/kitchen/api/resos/opening-hours`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch opening hours')
|
if (!res.ok) throw new Error('Failed to fetch opening hours')
|
||||||
|
|
@ -230,7 +230,7 @@ export default function ResosData() {
|
||||||
queryKey: ['resos-opening-hours', selectedDate],
|
queryKey: ['resos-opening-hours', selectedDate],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
if (!selectedDate) return []
|
if (!selectedDate) return []
|
||||||
const res = await fetch(`/api/resos/opening-hours/${selectedDate}`, {
|
const res = await fetch(`/kitchen/api/resos/opening-hours/${selectedDate}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch opening hours')
|
if (!res.ok) throw new Error('Failed to fetch opening hours')
|
||||||
|
|
@ -1322,7 +1322,7 @@ export default function ResosData() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (confirm('Delete this event?')) {
|
if (confirm('Delete this event?')) {
|
||||||
await fetch(`/api/calendar-events/${editingEvent.id}`, {
|
await fetch(`/kitchen/api/calendar-events/${editingEvent.id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -1359,8 +1359,8 @@ export default function ResosData() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const url = editingEvent
|
const url = editingEvent
|
||||||
? `/api/calendar-events/${editingEvent.id}`
|
? `/kitchen/api/calendar-events/${editingEvent.id}`
|
||||||
: '/api/calendar-events/'
|
: '/kitchen/api/calendar-events/'
|
||||||
const method = editingEvent ? 'PUT' : 'POST'
|
const method = editingEvent ? 'PUT' : 'POST'
|
||||||
|
|
||||||
await fetch(url, {
|
await fetch(url, {
|
||||||
|
|
|
||||||
|
|
@ -530,7 +530,7 @@ export default function Settings() {
|
||||||
const { data: settings, isLoading } = useQuery<SettingsData>({
|
const { data: settings, isLoading } = useQuery<SettingsData>({
|
||||||
queryKey: ['settings'],
|
queryKey: ['settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch settings')
|
if (!res.ok) throw new Error('Failed to fetch settings')
|
||||||
|
|
@ -542,7 +542,7 @@ export default function Settings() {
|
||||||
const { data: newbookSettings, error: newbookError, isLoading: newbookLoading } = useQuery<NewbookSettingsData>({
|
const { data: newbookSettings, error: newbookError, isLoading: newbookLoading } = useQuery<NewbookSettingsData>({
|
||||||
queryKey: ['newbook-settings'],
|
queryKey: ['newbook-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/newbook/settings', {
|
const res = await fetch('/kitchen/api/newbook/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -561,7 +561,7 @@ export default function Settings() {
|
||||||
const { data: resosSettings, error: resosError, isLoading: resosLoading } = useQuery<ResosSettingsData>({
|
const { data: resosSettings, error: resosError, isLoading: resosLoading } = useQuery<ResosSettingsData>({
|
||||||
queryKey: ['resos-settings'],
|
queryKey: ['resos-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/resos/settings', {
|
const res = await fetch('/kitchen/api/resos/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -579,7 +579,7 @@ export default function Settings() {
|
||||||
const { data: glAccounts, refetch: refetchGLAccounts } = useQuery<GLAccount[]>({
|
const { data: glAccounts, refetch: refetchGLAccounts } = useQuery<GLAccount[]>({
|
||||||
queryKey: ['gl-accounts'],
|
queryKey: ['gl-accounts'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/newbook/gl-accounts', {
|
const res = await fetch('/kitchen/api/newbook/gl-accounts', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -591,7 +591,7 @@ export default function Settings() {
|
||||||
const { data: roomCategories, refetch: refetchRoomCategories } = useQuery<RoomCategory[]>({
|
const { data: roomCategories, refetch: refetchRoomCategories } = useQuery<RoomCategory[]>({
|
||||||
queryKey: ['room-categories'],
|
queryKey: ['room-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/newbook/room-categories', {
|
const res = await fetch('/kitchen/api/newbook/room-categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -619,7 +619,7 @@ export default function Settings() {
|
||||||
const { data: sambaSettings } = useQuery<SambaPOSSettingsData>({
|
const { data: sambaSettings } = useQuery<SambaPOSSettingsData>({
|
||||||
queryKey: ['sambapos-settings'],
|
queryKey: ['sambapos-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/settings', {
|
const res = await fetch('/kitchen/api/sambapos/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch SambaPOS settings')
|
if (!res.ok) throw new Error('Failed to fetch SambaPOS settings')
|
||||||
|
|
@ -632,7 +632,7 @@ export default function Settings() {
|
||||||
const { data: sambaCategories, refetch: refetchSambaCategories, isLoading: sambaCategoriesLoading, error: sambaCategoriesError } = useQuery<SambaPOSCategory[]>({
|
const { data: sambaCategories, refetch: refetchSambaCategories, isLoading: sambaCategoriesLoading, error: sambaCategoriesError } = useQuery<SambaPOSCategory[]>({
|
||||||
queryKey: ['sambapos-categories'],
|
queryKey: ['sambapos-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/categories', {
|
const res = await fetch('/kitchen/api/sambapos/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -649,7 +649,7 @@ export default function Settings() {
|
||||||
const { data: sambaGroupCodes, refetch: refetchSambaGroupCodes, isLoading: sambaGroupCodesLoading } = useQuery<SambaPOSGroupCode[]>({
|
const { data: sambaGroupCodes, refetch: refetchSambaGroupCodes, isLoading: sambaGroupCodesLoading } = useQuery<SambaPOSGroupCode[]>({
|
||||||
queryKey: ['sambapos-group-codes'],
|
queryKey: ['sambapos-group-codes'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/group-codes', {
|
const res = await fetch('/kitchen/api/sambapos/group-codes', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -666,7 +666,7 @@ export default function Settings() {
|
||||||
const { data: sambaGLCodes, refetch: refetchSambaGLCodes, isLoading: sambaGLCodesLoading } = useQuery<SambaPOSGLCode[]>({
|
const { data: sambaGLCodes, refetch: refetchSambaGLCodes, isLoading: sambaGLCodesLoading } = useQuery<SambaPOSGLCode[]>({
|
||||||
queryKey: ['sambapos-gl-codes'],
|
queryKey: ['sambapos-gl-codes'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/gl-codes', {
|
const res = await fetch('/kitchen/api/sambapos/gl-codes', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
|
|
@ -683,7 +683,7 @@ export default function Settings() {
|
||||||
const { data: selectedGLCodes } = useQuery<{ food_codes: string[]; beverage_codes: string[] }>({
|
const { data: selectedGLCodes } = useQuery<{ food_codes: string[]; beverage_codes: string[] }>({
|
||||||
queryKey: ['sambapos-selected-gl-codes'],
|
queryKey: ['sambapos-selected-gl-codes'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/gl-codes/selected', {
|
const res = await fetch('/kitchen/api/sambapos/gl-codes/selected', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch selected GL codes')
|
if (!res.ok) throw new Error('Failed to fetch selected GL codes')
|
||||||
|
|
@ -696,7 +696,7 @@ export default function Settings() {
|
||||||
const { data: kdsSettings } = useQuery<KDSSettingsData>({
|
const { data: kdsSettings } = useQuery<KDSSettingsData>({
|
||||||
queryKey: ['kds-settings'],
|
queryKey: ['kds-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/kds/settings', {
|
const res = await fetch('/kitchen/api/kds/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch KDS settings')
|
if (!res.ok) throw new Error('Failed to fetch KDS settings')
|
||||||
|
|
@ -719,7 +719,7 @@ export default function Settings() {
|
||||||
const { data: kitchenDetails } = useQuery<KitchenDetailsData>({
|
const { data: kitchenDetails } = useQuery<KitchenDetailsData>({
|
||||||
queryKey: ['kitchen-details'],
|
queryKey: ['kitchen-details'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/kitchen-details', {
|
const res = await fetch('/kitchen/api/settings/kitchen-details', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch kitchen details')
|
if (!res.ok) throw new Error('Failed to fetch kitchen details')
|
||||||
|
|
@ -739,7 +739,7 @@ export default function Settings() {
|
||||||
const { data: budgetSettings } = useQuery<BudgetSettingsData>({
|
const { data: budgetSettings } = useQuery<BudgetSettingsData>({
|
||||||
queryKey: ['budget-settings'],
|
queryKey: ['budget-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/budget/settings', {
|
const res = await fetch('/kitchen/api/budget/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch Budget settings')
|
if (!res.ok) throw new Error('Failed to fetch Budget settings')
|
||||||
|
|
@ -752,7 +752,7 @@ export default function Settings() {
|
||||||
const { data: pageRestrictions } = useQuery<{ restricted_pages: string[] }>({
|
const { data: pageRestrictions } = useQuery<{ restricted_pages: string[] }>({
|
||||||
queryKey: ['page-restrictions'],
|
queryKey: ['page-restrictions'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/page-restrictions', {
|
const res = await fetch('/kitchen/api/settings/page-restrictions', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch page restrictions')
|
if (!res.ok) throw new Error('Failed to fetch page restrictions')
|
||||||
|
|
@ -765,7 +765,7 @@ export default function Settings() {
|
||||||
const { data: nextcloudSettings } = useQuery<NextcloudSettingsData>({
|
const { data: nextcloudSettings } = useQuery<NextcloudSettingsData>({
|
||||||
queryKey: ['nextcloud-settings'],
|
queryKey: ['nextcloud-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/nextcloud', {
|
const res = await fetch('/kitchen/api/settings/nextcloud', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch Nextcloud settings')
|
if (!res.ok) throw new Error('Failed to fetch Nextcloud settings')
|
||||||
|
|
@ -778,7 +778,7 @@ export default function Settings() {
|
||||||
const { data: nextcloudStats } = useQuery<NextcloudStatsData>({
|
const { data: nextcloudStats } = useQuery<NextcloudStatsData>({
|
||||||
queryKey: ['nextcloud-stats'],
|
queryKey: ['nextcloud-stats'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/nextcloud/stats', {
|
const res = await fetch('/kitchen/api/settings/nextcloud/stats', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch Nextcloud stats')
|
if (!res.ok) throw new Error('Failed to fetch Nextcloud stats')
|
||||||
|
|
@ -791,7 +791,7 @@ export default function Settings() {
|
||||||
const { data: backupSettings } = useQuery<BackupSettingsData>({
|
const { data: backupSettings } = useQuery<BackupSettingsData>({
|
||||||
queryKey: ['backup-settings'],
|
queryKey: ['backup-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/backup/settings', {
|
const res = await fetch('/kitchen/api/backup/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch backup settings')
|
if (!res.ok) throw new Error('Failed to fetch backup settings')
|
||||||
|
|
@ -804,7 +804,7 @@ export default function Settings() {
|
||||||
const { data: backupHistory } = useQuery<BackupHistoryEntry[]>({
|
const { data: backupHistory } = useQuery<BackupHistoryEntry[]>({
|
||||||
queryKey: ['backup-history'],
|
queryKey: ['backup-history'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/backup/history', {
|
const res = await fetch('/kitchen/api/backup/history', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch backup history')
|
if (!res.ok) throw new Error('Failed to fetch backup history')
|
||||||
|
|
@ -817,7 +817,7 @@ export default function Settings() {
|
||||||
const { data: searchSettings } = useQuery<SearchSettingsData>({
|
const { data: searchSettings } = useQuery<SearchSettingsData>({
|
||||||
queryKey: ['search-settings'],
|
queryKey: ['search-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/search/settings', {
|
const res = await fetch('/kitchen/api/search/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch search settings')
|
if (!res.ok) throw new Error('Failed to fetch search settings')
|
||||||
|
|
@ -830,7 +830,7 @@ export default function Settings() {
|
||||||
const { data: imapSettings } = useQuery<ImapSettingsData>({
|
const { data: imapSettings } = useQuery<ImapSettingsData>({
|
||||||
queryKey: ['imap-settings'],
|
queryKey: ['imap-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/imap/settings', {
|
const res = await fetch('/kitchen/api/imap/settings', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch IMAP settings')
|
if (!res.ok) throw new Error('Failed to fetch IMAP settings')
|
||||||
|
|
@ -843,7 +843,7 @@ export default function Settings() {
|
||||||
const { data: imapLogs } = useQuery<ImapLogEntry[]>({
|
const { data: imapLogs } = useQuery<ImapLogEntry[]>({
|
||||||
queryKey: ['imap-logs'],
|
queryKey: ['imap-logs'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/imap/logs?limit=20', {
|
const res = await fetch('/kitchen/api/imap/logs?limit=20', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch IMAP logs')
|
if (!res.ok) throw new Error('Failed to fetch IMAP logs')
|
||||||
|
|
@ -856,7 +856,7 @@ export default function Settings() {
|
||||||
const { data: imapStats } = useQuery<ImapSyncStats>({
|
const { data: imapStats } = useQuery<ImapSyncStats>({
|
||||||
queryKey: ['imap-stats'],
|
queryKey: ['imap-stats'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/imap/logs/stats', {
|
const res = await fetch('/kitchen/api/imap/logs/stats', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) throw new Error('Failed to fetch IMAP stats')
|
if (!res.ok) throw new Error('Failed to fetch IMAP stats')
|
||||||
|
|
@ -1065,7 +1065,7 @@ export default function Settings() {
|
||||||
|
|
||||||
// Auto-fetch custom fields if mapping exists but fields list is empty
|
// Auto-fetch custom fields if mapping exists but fields list is empty
|
||||||
if (resosSettings.resos_custom_field_mapping && Object.keys(resosSettings.resos_custom_field_mapping).length > 0 && customFields.length === 0) {
|
if (resosSettings.resos_custom_field_mapping && Object.keys(resosSettings.resos_custom_field_mapping).length > 0 && customFields.length === 0) {
|
||||||
fetch('/api/resos/custom-fields', {
|
fetch('/kitchen/api/resos/custom-fields', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
|
@ -1075,7 +1075,7 @@ export default function Settings() {
|
||||||
|
|
||||||
// Auto-fetch opening hours if mapping exists but hours list is empty
|
// Auto-fetch opening hours if mapping exists but hours list is empty
|
||||||
if (resosSettings.resos_opening_hours_mapping && resosSettings.resos_opening_hours_mapping.length > 0 && openingHours.length === 0) {
|
if (resosSettings.resos_opening_hours_mapping && resosSettings.resos_opening_hours_mapping.length > 0 && openingHours.length === 0) {
|
||||||
fetch('/api/resos/opening-hours', {
|
fetch('/kitchen/api/resos/opening-hours', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
|
@ -1089,7 +1089,7 @@ export default function Settings() {
|
||||||
const { data: foodFlagCategories, refetch: refetchFoodFlags } = useQuery<FoodFlagCategoryData[]>({
|
const { data: foodFlagCategories, refetch: refetchFoodFlags } = useQuery<FoodFlagCategoryData[]>({
|
||||||
queryKey: ['food-flag-categories'],
|
queryKey: ['food-flag-categories'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -1101,7 +1101,7 @@ export default function Settings() {
|
||||||
const { data: apiAccessSettings } = useQuery<ApiAccessData>({
|
const { data: apiAccessSettings } = useQuery<ApiAccessData>({
|
||||||
queryKey: ['api-access-settings'],
|
queryKey: ['api-access-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/api-access', {
|
const res = await fetch('/kitchen/api/settings/api-access', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { api_key: null, api_key_enabled: false }
|
if (!res.ok) return { api_key: null, api_key_enabled: false }
|
||||||
|
|
@ -1120,7 +1120,7 @@ export default function Settings() {
|
||||||
// Food Flag mutations
|
// Food Flag mutations
|
||||||
const createCategoryMutation = useMutation({
|
const createCategoryMutation = useMutation({
|
||||||
mutationFn: async (data: { name: string; propagation_type: string }) => {
|
mutationFn: async (data: { name: string; propagation_type: string }) => {
|
||||||
const res = await fetch('/api/food-flags/categories', {
|
const res = await fetch('/kitchen/api/food-flags/categories', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1141,7 +1141,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const updateCategoryMutation = useMutation({
|
const updateCategoryMutation = useMutation({
|
||||||
mutationFn: async ({ id, data }: { id: number; data: { name?: string; propagation_type?: string; required?: boolean } }) => {
|
mutationFn: async ({ id, data }: { id: number; data: { name?: string; propagation_type?: string; required?: boolean } }) => {
|
||||||
const res = await fetch(`/api/food-flags/categories/${id}`, {
|
const res = await fetch(`/kitchen/api/food-flags/categories/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1160,7 +1160,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const deleteCategoryMutation = useMutation({
|
const deleteCategoryMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/food-flags/categories/${id}`, {
|
const res = await fetch(`/kitchen/api/food-flags/categories/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1177,7 +1177,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const createFlagMutation = useMutation({
|
const createFlagMutation = useMutation({
|
||||||
mutationFn: async (data: { category_id: number; name: string; code?: string; icon?: string }) => {
|
mutationFn: async (data: { category_id: number; name: string; code?: string; icon?: string }) => {
|
||||||
const res = await fetch('/api/food-flags/flags', {
|
const res = await fetch('/kitchen/api/food-flags/flags', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1199,7 +1199,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const updateFlagMutation = useMutation({
|
const updateFlagMutation = useMutation({
|
||||||
mutationFn: async ({ id, data }: { id: number; data: { name?: string; code?: string; icon?: string } }) => {
|
mutationFn: async ({ id, data }: { id: number; data: { name?: string; code?: string; icon?: string } }) => {
|
||||||
const res = await fetch(`/api/food-flags/flags/${id}`, {
|
const res = await fetch(`/kitchen/api/food-flags/flags/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1218,7 +1218,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const deleteFlagMutation = useMutation({
|
const deleteFlagMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/food-flags/flags/${id}`, {
|
const res = await fetch(`/kitchen/api/food-flags/flags/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1250,7 +1250,7 @@ export default function Settings() {
|
||||||
const { data: allergenKeywords, refetch: refetchAllergenKeywords } = useQuery<AllergenKeywordGroup[]>({
|
const { data: allergenKeywords, refetch: refetchAllergenKeywords } = useQuery<AllergenKeywordGroup[]>({
|
||||||
queryKey: ['allergen-keywords'],
|
queryKey: ['allergen-keywords'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/keywords', {
|
const res = await fetch('/kitchen/api/food-flags/keywords', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -1261,7 +1261,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const addKeywordMutation = useMutation({
|
const addKeywordMutation = useMutation({
|
||||||
mutationFn: async ({ food_flag_id, keyword }: { food_flag_id: number; keyword: string }) => {
|
mutationFn: async ({ food_flag_id, keyword }: { food_flag_id: number; keyword: string }) => {
|
||||||
const res = await fetch('/api/food-flags/keywords', {
|
const res = await fetch('/kitchen/api/food-flags/keywords', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ food_flag_id, keyword }),
|
body: JSON.stringify({ food_flag_id, keyword }),
|
||||||
|
|
@ -1286,7 +1286,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const deleteKeywordMutation = useMutation({
|
const deleteKeywordMutation = useMutation({
|
||||||
mutationFn: async (keywordId: number) => {
|
mutationFn: async (keywordId: number) => {
|
||||||
const res = await fetch(`/api/food-flags/keywords/${keywordId}`, {
|
const res = await fetch(`/kitchen/api/food-flags/keywords/${keywordId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1299,7 +1299,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const resetKeywordsMutation = useMutation({
|
const resetKeywordsMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/food-flags/keywords/reset-defaults', {
|
const res = await fetch('/kitchen/api/food-flags/keywords/reset-defaults', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1323,7 +1323,7 @@ export default function Settings() {
|
||||||
const { data: ingCategories, refetch: refetchIngCategories } = useQuery<IngredientCategoryItem[]>({
|
const { data: ingCategories, refetch: refetchIngCategories } = useQuery<IngredientCategoryItem[]>({
|
||||||
queryKey: ['ingredient-categories-settings'],
|
queryKey: ['ingredient-categories-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/ingredients/categories', {
|
const res = await fetch('/kitchen/api/ingredients/categories', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -1334,7 +1334,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const createIngCatMutation = useMutation({
|
const createIngCatMutation = useMutation({
|
||||||
mutationFn: async (data: { name: string; sort_order: number }) => {
|
mutationFn: async (data: { name: string; sort_order: number }) => {
|
||||||
const res = await fetch('/api/ingredients/categories', {
|
const res = await fetch('/kitchen/api/ingredients/categories', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1355,7 +1355,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const updateIngCatMutation = useMutation({
|
const updateIngCatMutation = useMutation({
|
||||||
mutationFn: async ({ id, data }: { id: number; data: { name?: string; sort_order?: number } }) => {
|
mutationFn: async ({ id, data }: { id: number; data: { name?: string; sort_order?: number } }) => {
|
||||||
const res = await fetch(`/api/ingredients/categories/${id}`, {
|
const res = await fetch(`/kitchen/api/ingredients/categories/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1374,7 +1374,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const deleteIngCatMutation = useMutation({
|
const deleteIngCatMutation = useMutation({
|
||||||
mutationFn: async (id: number) => {
|
mutationFn: async (id: number) => {
|
||||||
const res = await fetch(`/api/ingredients/categories/${id}`, {
|
const res = await fetch(`/kitchen/api/ingredients/categories/${id}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1405,7 +1405,7 @@ export default function Settings() {
|
||||||
const { data: recipeSections, refetch: refetchRecipeSections } = useQuery<{ id: number; name: string; sort_order: number; section_type: string; recipe_count: number }[]>({
|
const { data: recipeSections, refetch: refetchRecipeSections } = useQuery<{ id: number; name: string; sort_order: number; section_type: string; recipe_count: number }[]>({
|
||||||
queryKey: ['recipe-sections-settings'],
|
queryKey: ['recipe-sections-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=recipe', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=recipe', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -1418,7 +1418,7 @@ export default function Settings() {
|
||||||
const { data: dishCourses, refetch: refetchDishCourses } = useQuery<{ id: number; name: string; sort_order: number; section_type: string; recipe_count: number }[]>({
|
const { data: dishCourses, refetch: refetchDishCourses } = useQuery<{ id: number; name: string; sort_order: number; section_type: string; recipe_count: number }[]>({
|
||||||
queryKey: ['dish-courses-settings'],
|
queryKey: ['dish-courses-settings'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/recipes/menu-sections?section_type=dish', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections?section_type=dish', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return []
|
if (!res.ok) return []
|
||||||
|
|
@ -1430,7 +1430,7 @@ export default function Settings() {
|
||||||
// API Access mutations
|
// API Access mutations
|
||||||
const saveApiAccessMutation = useMutation({
|
const saveApiAccessMutation = useMutation({
|
||||||
mutationFn: async (data: { api_key_enabled: boolean }) => {
|
mutationFn: async (data: { api_key_enabled: boolean }) => {
|
||||||
const res = await fetch('/api/settings/api-access', {
|
const res = await fetch('/kitchen/api/settings/api-access', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1449,7 +1449,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const regenerateApiKeyMutation = useMutation({
|
const regenerateApiKeyMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/settings/api-access/regenerate', {
|
const res = await fetch('/kitchen/api/settings/api-access/regenerate', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1474,7 +1474,7 @@ export default function Settings() {
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['llm-usage'],
|
queryKey: ['llm-usage'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/llm-usage', {
|
const res = await fetch('/kitchen/api/settings/llm-usage', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { total_calls: 0, successful_calls: 0, failed_calls: 0, total_input_tokens: 0, total_output_tokens: 0, total_tokens: 0, estimated_cost_usd: 0, cache_entries_this_month: 0 }
|
if (!res.ok) return { total_calls: 0, successful_calls: 0, failed_calls: 0, total_input_tokens: 0, total_output_tokens: 0, total_tokens: 0, estimated_cost_usd: 0, cache_entries_this_month: 0 }
|
||||||
|
|
@ -1492,7 +1492,7 @@ export default function Settings() {
|
||||||
}>({
|
}>({
|
||||||
queryKey: ['llm-models'],
|
queryKey: ['llm-models'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const res = await fetch('/api/settings/llm-models', {
|
const res = await fetch('/kitchen/api/settings/llm-models', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (!res.ok) return { models: [], default: 'claude-haiku-4-5-20251001', current: 'claude-haiku-4-5-20251001' }
|
if (!res.ok) return { models: [], default: 'claude-haiku-4-5-20251001', current: 'claude-haiku-4-5-20251001' }
|
||||||
|
|
@ -1504,7 +1504,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const saveLlmSettingsMutation = useMutation({
|
const saveLlmSettingsMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|
@ -1523,7 +1523,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const llmTestMutation = useMutation({
|
const llmTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/settings/test-llm', {
|
const res = await fetch('/kitchen/api/settings/test-llm', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1559,7 +1559,7 @@ export default function Settings() {
|
||||||
// Mutations
|
// Mutations
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: async (data: Partial<SettingsData & { azure_key?: string }>) => {
|
mutationFn: async (data: Partial<SettingsData & { azure_key?: string }>) => {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1583,7 +1583,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const azureTestMutation = useMutation({
|
const azureTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/settings/test-azure', {
|
const res = await fetch('/kitchen/api/settings/test-azure', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1683,7 +1683,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const savePageRestrictionsMutation = useMutation({
|
const savePageRestrictionsMutation = useMutation({
|
||||||
mutationFn: async (pages: string[]) => {
|
mutationFn: async (pages: string[]) => {
|
||||||
const res = await fetch('/api/settings/page-restrictions', {
|
const res = await fetch('/kitchen/api/settings/page-restrictions', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1706,7 +1706,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const reprocessMutation = useMutation({
|
const reprocessMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/invoices/reprocess-all', {
|
const res = await fetch('/kitchen/api/invoices/reprocess-all', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1728,7 +1728,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const cleanupPriceChangesMutation = useMutation({
|
const cleanupPriceChangesMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/recipes/cleanup-false-price-changes', {
|
const res = await fetch('/kitchen/api/recipes/cleanup-false-price-changes', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1749,7 +1749,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const backfillInvoiceRefsMutation = useMutation({
|
const backfillInvoiceRefsMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/recipes/backfill-invoice-references', {
|
const res = await fetch('/kitchen/api/recipes/backfill-invoice-references', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1770,7 +1770,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const rematchFuzzyMutation = useMutation({
|
const rematchFuzzyMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/suppliers/rematch-fuzzy', {
|
const res = await fetch('/kitchen/api/suppliers/rematch-fuzzy', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1794,7 +1794,7 @@ export default function Settings() {
|
||||||
const updateNewbookMutation = useMutation({
|
const updateNewbookMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
console.log('[Newbook] Sending PATCH with data:', data)
|
console.log('[Newbook] Sending PATCH with data:', data)
|
||||||
const res = await fetch('/api/newbook/settings', {
|
const res = await fetch('/kitchen/api/newbook/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1826,7 +1826,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const newbookTestMutation = useMutation({
|
const newbookTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/newbook/test-connection', {
|
const res = await fetch('/kitchen/api/newbook/test-connection', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1849,7 +1849,7 @@ export default function Settings() {
|
||||||
const updateResosSyncMutation = useMutation({
|
const updateResosSyncMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
console.log('[Resos] Sending PATCH with data:', data)
|
console.log('[Resos] Sending PATCH with data:', data)
|
||||||
const res = await fetch('/api/resos/settings', {
|
const res = await fetch('/kitchen/api/resos/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1879,7 +1879,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const fetchGLAccountsMutation = useMutation({
|
const fetchGLAccountsMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/newbook/gl-accounts/fetch', {
|
const res = await fetch('/kitchen/api/newbook/gl-accounts/fetch', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1901,7 +1901,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const syncForecastMutation = useMutation({
|
const syncForecastMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/newbook/sync/forecast', {
|
const res = await fetch('/kitchen/api/newbook/sync/forecast', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -1923,7 +1923,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const syncHistoricalMutation = useMutation({
|
const syncHistoricalMutation = useMutation({
|
||||||
mutationFn: async (dates: { date_from: string; date_to: string }) => {
|
mutationFn: async (dates: { date_from: string; date_to: string }) => {
|
||||||
const res = await fetch('/api/newbook/sync/historical', {
|
const res = await fetch('/kitchen/api/newbook/sync/historical', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1950,7 +1950,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const updateGLAccountMutation = useMutation({
|
const updateGLAccountMutation = useMutation({
|
||||||
mutationFn: async ({ id, is_tracked }: { id: number; is_tracked: boolean }) => {
|
mutationFn: async ({ id, is_tracked }: { id: number; is_tracked: boolean }) => {
|
||||||
const res = await fetch(`/api/newbook/gl-accounts/${id}`, {
|
const res = await fetch(`/kitchen/api/newbook/gl-accounts/${id}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1968,7 +1968,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const bulkUpdateGLAccountsMutation = useMutation({
|
const bulkUpdateGLAccountsMutation = useMutation({
|
||||||
mutationFn: async (updates: { id: number; is_tracked: boolean }[]) => {
|
mutationFn: async (updates: { id: number; is_tracked: boolean }[]) => {
|
||||||
const res = await fetch('/api/newbook/gl-accounts/bulk-update', {
|
const res = await fetch('/kitchen/api/newbook/gl-accounts/bulk-update', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -1987,7 +1987,7 @@ export default function Settings() {
|
||||||
// Room category mutations
|
// Room category mutations
|
||||||
const fetchRoomCategoriesMutation = useMutation({
|
const fetchRoomCategoriesMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/newbook/room-categories/fetch', {
|
const res = await fetch('/kitchen/api/newbook/room-categories/fetch', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2009,7 +2009,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const bulkUpdateRoomCategoriesMutation = useMutation({
|
const bulkUpdateRoomCategoriesMutation = useMutation({
|
||||||
mutationFn: async (updates: { id: number; is_included: boolean }[]) => {
|
mutationFn: async (updates: { id: number; is_included: boolean }[]) => {
|
||||||
const res = await fetch('/api/newbook/room-categories/bulk-update', {
|
const res = await fetch('/kitchen/api/newbook/room-categories/bulk-update', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2028,7 +2028,7 @@ export default function Settings() {
|
||||||
// SambaPOS mutations
|
// SambaPOS mutations
|
||||||
const updateSambaMutation = useMutation({
|
const updateSambaMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/sambapos/settings', {
|
const res = await fetch('/kitchen/api/sambapos/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2052,7 +2052,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const sambaTestMutation = useMutation({
|
const sambaTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/sambapos/test-connection', {
|
const res = await fetch('/kitchen/api/sambapos/test-connection', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2074,7 +2074,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const saveSambaCoursesMutation = useMutation({
|
const saveSambaCoursesMutation = useMutation({
|
||||||
mutationFn: async (courses: string[]) => {
|
mutationFn: async (courses: string[]) => {
|
||||||
const res = await fetch('/api/sambapos/tracked-categories', {
|
const res = await fetch('/kitchen/api/sambapos/tracked-categories', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2097,7 +2097,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const saveExcludedItemsMutation = useMutation({
|
const saveExcludedItemsMutation = useMutation({
|
||||||
mutationFn: async (items: string[]) => {
|
mutationFn: async (items: string[]) => {
|
||||||
const res = await fetch('/api/sambapos/excluded-items', {
|
const res = await fetch('/kitchen/api/sambapos/excluded-items', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2120,7 +2120,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const saveGLCodesMutation = useMutation({
|
const saveGLCodesMutation = useMutation({
|
||||||
mutationFn: async (data: { food_codes: string[]; beverage_codes: string[] }) => {
|
mutationFn: async (data: { food_codes: string[]; beverage_codes: string[] }) => {
|
||||||
const res = await fetch('/api/sambapos/gl-codes', {
|
const res = await fetch('/kitchen/api/sambapos/gl-codes', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2144,7 +2144,7 @@ export default function Settings() {
|
||||||
// KDS mutations
|
// KDS mutations
|
||||||
const updateKdsMutation = useMutation({
|
const updateKdsMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/kds/settings', {
|
const res = await fetch('/kitchen/api/kds/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2168,7 +2168,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const kdsTestMutation = useMutation({
|
const kdsTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/kds/test-connection', {
|
const res = await fetch('/kitchen/api/kds/test-connection', {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
|
|
@ -2189,7 +2189,7 @@ export default function Settings() {
|
||||||
// Budget/Forecast API mutations
|
// Budget/Forecast API mutations
|
||||||
const saveKitchenDetailsMutation = useMutation({
|
const saveKitchenDetailsMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/settings/kitchen-details', {
|
const res = await fetch('/kitchen/api/settings/kitchen-details', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2215,7 +2215,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const saveBudgetMutation = useMutation({
|
const saveBudgetMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/budget/settings', {
|
const res = await fetch('/kitchen/api/budget/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2242,7 +2242,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const budgetTestMutation = useMutation({
|
const budgetTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/budget/test-forecast-connection', {
|
const res = await fetch('/kitchen/api/budget/test-forecast-connection', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2264,7 +2264,7 @@ export default function Settings() {
|
||||||
// Nextcloud mutations
|
// Nextcloud mutations
|
||||||
const saveNextcloudMutation = useMutation({
|
const saveNextcloudMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/settings/nextcloud', {
|
const res = await fetch('/kitchen/api/settings/nextcloud', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2291,7 +2291,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const nextcloudTestMutation = useMutation({
|
const nextcloudTestMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/settings/nextcloud/test', {
|
const res = await fetch('/kitchen/api/settings/nextcloud/test', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2312,7 +2312,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const archiveAllMutation = useMutation({
|
const archiveAllMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/settings/nextcloud/archive-all', {
|
const res = await fetch('/kitchen/api/settings/nextcloud/archive-all', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2335,7 +2335,7 @@ export default function Settings() {
|
||||||
// Backup mutations
|
// Backup mutations
|
||||||
const saveBackupMutation = useMutation({
|
const saveBackupMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/backup/settings', {
|
const res = await fetch('/kitchen/api/backup/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -2361,7 +2361,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const createBackupMutation = useMutation({
|
const createBackupMutation = useMutation({
|
||||||
mutationFn: async () => {
|
mutationFn: async () => {
|
||||||
const res = await fetch('/api/backup/create', {
|
const res = await fetch('/kitchen/api/backup/create', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2384,7 +2384,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const restoreBackupMutation = useMutation({
|
const restoreBackupMutation = useMutation({
|
||||||
mutationFn: async (backupId: number) => {
|
mutationFn: async (backupId: number) => {
|
||||||
const res = await fetch(`/api/backup/${backupId}/restore`, {
|
const res = await fetch(`/kitchen/api/backup/${backupId}/restore`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2407,7 +2407,7 @@ export default function Settings() {
|
||||||
|
|
||||||
const deleteBackupMutation = useMutation({
|
const deleteBackupMutation = useMutation({
|
||||||
mutationFn: async (backupId: number) => {
|
mutationFn: async (backupId: number) => {
|
||||||
const res = await fetch(`/api/backup/${backupId}`, {
|
const res = await fetch(`/kitchen/api/backup/${backupId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -2431,7 +2431,7 @@ export default function Settings() {
|
||||||
mutationFn: async (file: File) => {
|
mutationFn: async (file: File) => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', file)
|
||||||
const res = await fetch('/api/backup/upload', {
|
const res = await fetch('/kitchen/api/backup/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -2455,7 +2455,7 @@ export default function Settings() {
|
||||||
// Search settings mutation
|
// Search settings mutation
|
||||||
const saveSearchSettingsMutation = useMutation({
|
const saveSearchSettingsMutation = useMutation({
|
||||||
mutationFn: async (data: Record<string, unknown>) => {
|
mutationFn: async (data: Record<string, unknown>) => {
|
||||||
const res = await fetch('/api/search/settings', {
|
const res = await fetch('/kitchen/api/search/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -3426,7 +3426,7 @@ export default function Settings() {
|
||||||
support_email: supportEmail || null
|
support_email: supportEmail || null
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveRes = await fetch('/api/settings/', {
|
const saveRes = await fetch('/kitchen/api/settings/', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -3444,7 +3444,7 @@ export default function Settings() {
|
||||||
|
|
||||||
// Now test the connection
|
// Now test the connection
|
||||||
setSmtpTestStatus('Testing connection...')
|
setSmtpTestStatus('Testing connection...')
|
||||||
const res = await fetch('/api/settings/test-smtp', {
|
const res = await fetch('/kitchen/api/settings/test-smtp', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -3469,7 +3469,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -3646,7 +3646,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setImapTestStatus('Testing connection...')
|
setImapTestStatus('Testing connection...')
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/imap/test-connection', {
|
const res = await fetch('/kitchen/api/imap/test-connection', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -3679,7 +3679,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setImapSyncMessage('Syncing...')
|
setImapSyncMessage('Syncing...')
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/imap/sync-now', {
|
const res = await fetch('/kitchen/api/imap/sync-now', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -3709,7 +3709,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setImapSaveMessage('Saving...')
|
setImapSaveMessage('Saving...')
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/imap/settings', {
|
const res = await fetch('/kitchen/api/imap/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -3915,7 +3915,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/settings/', {
|
const res = await fetch('/kitchen/api/settings/', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -3966,7 +3966,7 @@ export default function Settings() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/invoices/bulk/mark-all-dext-sent', {
|
const res = await fetch('/kitchen/api/invoices/bulk/mark-all-dext-sent', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -4329,7 +4329,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
setResosTestStatus('Testing...')
|
setResosTestStatus('Testing...')
|
||||||
const res = await fetch('/api/resos/test-connection', {
|
const res = await fetch('/kitchen/api/resos/test-connection', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -4399,7 +4399,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/resos/custom-fields', {
|
const res = await fetch('/kitchen/api/resos/custom-fields', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -4463,7 +4463,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
// First, sync opening hours to database (POST endpoint)
|
// First, sync opening hours to database (POST endpoint)
|
||||||
const syncRes = await fetch('/api/resos/sync/opening-hours', {
|
const syncRes = await fetch('/kitchen/api/resos/sync/opening-hours', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -4477,7 +4477,7 @@ export default function Settings() {
|
||||||
const syncData = await syncRes.json()
|
const syncData = await syncRes.json()
|
||||||
|
|
||||||
// Then, fetch opening hours for display (GET endpoint)
|
// Then, fetch opening hours for display (GET endpoint)
|
||||||
const res = await fetch('/api/resos/opening-hours', {
|
const res = await fetch('/kitchen/api/resos/opening-hours', {
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -4787,7 +4787,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
setResosSaveMessage('Syncing upcoming bookings...')
|
setResosSaveMessage('Syncing upcoming bookings...')
|
||||||
const res = await fetch('/api/resos/sync/upcoming', {
|
const res = await fetch('/kitchen/api/resos/sync/upcoming', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -4815,7 +4815,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
setResosSaveMessage('Syncing forecast...')
|
setResosSaveMessage('Syncing forecast...')
|
||||||
const res = await fetch('/api/resos/sync/forecast', {
|
const res = await fetch('/kitchen/api/resos/sync/forecast', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -4855,7 +4855,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/resos/settings', {
|
const res = await fetch('/kitchen/api/resos/settings', {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
|
|
@ -4937,7 +4937,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
setResosSaveMessage('Syncing historical data...')
|
setResosSaveMessage('Syncing historical data...')
|
||||||
const res = await fetch(`/api/resos/sync/historical?from_date=${historicalResosDateFrom}&to_date=${historicalResosDateTo}`, {
|
const res = await fetch(`/kitchen/api/resos/sync/historical?from_date=${historicalResosDateFrom}&to_date=${historicalResosDateTo}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` }
|
headers: { Authorization: `Bearer ${token}` }
|
||||||
})
|
})
|
||||||
|
|
@ -6405,7 +6405,7 @@ export default function Settings() {
|
||||||
<div style={styles.actionButtons}>
|
<div style={styles.actionButtons}>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open(`/api/backup/${backup.id}/download?token=${token}`, '_blank')
|
window.open(`/kitchen/api/backup/${backup.id}/download?token=${token}`, '_blank')
|
||||||
}}
|
}}
|
||||||
style={styles.actionBtn}
|
style={styles.actionBtn}
|
||||||
disabled={backup.status !== 'success'}
|
disabled={backup.status !== 'success'}
|
||||||
|
|
@ -6464,7 +6464,7 @@ export default function Settings() {
|
||||||
setSeedingDefaults(true)
|
setSeedingDefaults(true)
|
||||||
setFoodFlagMessage(null)
|
setFoodFlagMessage(null)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/food-flags/seed-defaults', {
|
const res = await fetch('/kitchen/api/food-flags/seed-defaults', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -6891,7 +6891,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setIngCatMessage(null)
|
setIngCatMessage(null)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/ingredients/categories/seed-defaults', {
|
const res = await fetch('/kitchen/api/ingredients/categories/seed-defaults', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -7061,7 +7061,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setRecipeSectionsMsg(null)
|
setRecipeSectionsMsg(null)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/recipes/menu-sections/seed-defaults?section_type=recipe', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections/seed-defaults?section_type=recipe', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -7108,7 +7108,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (confirm(`Delete "${sec.name}"?${sec.recipe_count > 0 ? ` ${sec.recipe_count} recipe(s) will become unsectioned.` : ''}`)) {
|
if (confirm(`Delete "${sec.name}"?${sec.recipe_count > 0 ? ` ${sec.recipe_count} recipe(s) will become unsectioned.` : ''}`)) {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${sec.id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${sec.id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (res.ok) refetchRecipeSections()
|
if (res.ok) refetchRecipeSections()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
@ -7136,7 +7136,7 @@ export default function Settings() {
|
||||||
const input = e.currentTarget
|
const input = e.currentTarget
|
||||||
const name = input.value.trim()
|
const name = input.value.trim()
|
||||||
if (!name) return
|
if (!name) return
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'recipe', sort_order: recipeSections?.length || 0 }),
|
body: JSON.stringify({ name, section_type: 'recipe', sort_order: recipeSections?.length || 0 }),
|
||||||
|
|
@ -7150,7 +7150,7 @@ export default function Settings() {
|
||||||
const input = document.getElementById('newRecipeSectionName') as HTMLInputElement
|
const input = document.getElementById('newRecipeSectionName') as HTMLInputElement
|
||||||
const name = input?.value.trim()
|
const name = input?.value.trim()
|
||||||
if (!name) return
|
if (!name) return
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'recipe', sort_order: recipeSections?.length || 0 }),
|
body: JSON.stringify({ name, section_type: 'recipe', sort_order: recipeSections?.length || 0 }),
|
||||||
|
|
@ -7172,7 +7172,7 @@ export default function Settings() {
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setDishCoursesMsg(null)
|
setDishCoursesMsg(null)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/recipes/menu-sections/seed-defaults?section_type=dish', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections/seed-defaults?section_type=dish', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -7219,7 +7219,7 @@ export default function Settings() {
|
||||||
<button
|
<button
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (confirm(`Delete "${course.name}"?${course.recipe_count > 0 ? ` ${course.recipe_count} dish(es) will become uncategorised.` : ''}`)) {
|
if (confirm(`Delete "${course.name}"?${course.recipe_count > 0 ? ` ${course.recipe_count} dish(es) will become uncategorised.` : ''}`)) {
|
||||||
const res = await fetch(`/api/recipes/menu-sections/${course.id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } })
|
const res = await fetch(`/kitchen/api/recipes/menu-sections/${course.id}`, { method: 'DELETE', headers: { Authorization: `Bearer ${token}` } })
|
||||||
if (res.ok) refetchDishCourses()
|
if (res.ok) refetchDishCourses()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
@ -7247,7 +7247,7 @@ export default function Settings() {
|
||||||
const input = e.currentTarget
|
const input = e.currentTarget
|
||||||
const name = input.value.trim()
|
const name = input.value.trim()
|
||||||
if (!name) return
|
if (!name) return
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'dish', sort_order: dishCourses?.length || 0 }),
|
body: JSON.stringify({ name, section_type: 'dish', sort_order: dishCourses?.length || 0 }),
|
||||||
|
|
@ -7261,7 +7261,7 @@ export default function Settings() {
|
||||||
const input = document.getElementById('newDishCourseName') as HTMLInputElement
|
const input = document.getElementById('newDishCourseName') as HTMLInputElement
|
||||||
const name = input?.value.trim()
|
const name = input?.value.trim()
|
||||||
if (!name) return
|
if (!name) return
|
||||||
const res = await fetch('/api/recipes/menu-sections', {
|
const res = await fetch('/kitchen/api/recipes/menu-sections', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, section_type: 'dish', sort_order: dishCourses?.length || 0 }),
|
body: JSON.stringify({ name, section_type: 'dish', sort_order: dishCourses?.length || 0 }),
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ export default function UploadApp() {
|
||||||
q.id === queueId ? { ...q, status: 'processing' as const } : q
|
q.id === queueId ? { ...q, status: 'processing' as const } : q
|
||||||
))
|
))
|
||||||
|
|
||||||
const res = await fetch('/api/invoices/upload', {
|
const res = await fetch('/kitchen/api/invoices/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
@ -220,7 +220,7 @@ export default function UploadApp() {
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', pdfFile)
|
formData.append('file', pdfFile)
|
||||||
const res = await fetch('/api/invoices/upload', {
|
const res = await fetch('/kitchen/api/invoices/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ export default function WastageLogbook() {
|
||||||
const { data: entries, isLoading } = useQuery<LogbookEntry[]>({
|
const { data: entries, isLoading } = useQuery<LogbookEntry[]>({
|
||||||
queryKey: ['logbook', typeFilter, dateFrom, dateTo],
|
queryKey: ['logbook', typeFilter, dateFrom, dateTo],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const url = queryString ? `/api/logbook?${queryString}` : '/api/logbook'
|
const url = queryString ? `/kitchen/api/logbook?${queryString}` : '/kitchen/api/logbook'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -138,7 +138,7 @@ export default function WastageLogbook() {
|
||||||
const { data: summary } = useQuery<LogbookSummary>({
|
const { data: summary } = useQuery<LogbookSummary>({
|
||||||
queryKey: ['logbook-summary', dateFrom, dateTo],
|
queryKey: ['logbook-summary', dateFrom, dateTo],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const url = summaryString ? `/api/logbook/summary?${summaryString}` : '/api/logbook/summary'
|
const url = summaryString ? `/kitchen/api/logbook/summary?${summaryString}` : '/kitchen/api/logbook/summary'
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -150,7 +150,7 @@ export default function WastageLogbook() {
|
||||||
|
|
||||||
const deleteMutation = useMutation({
|
const deleteMutation = useMutation({
|
||||||
mutationFn: async (entryId: number) => {
|
mutationFn: async (entryId: number) => {
|
||||||
const res = await fetch(`/api/logbook/${entryId}`, {
|
const res = await fetch(`/kitchen/api/logbook/${entryId}`, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
|
|
@ -570,7 +570,7 @@ function CreateEntryModal({
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`/api/logbook/products/search?query=${encodeURIComponent(query)}`, {
|
const res = await fetch(`/kitchen/api/logbook/products/search?query=${encodeURIComponent(query)}`, {
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
})
|
})
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
|
@ -630,7 +630,7 @@ function CreateEntryModal({
|
||||||
setError(null)
|
setError(null)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let endpoint = '/api/logbook/'
|
let endpoint = '/kitchen/api/logbook/'
|
||||||
let body: Record<string, unknown> = {
|
let body: Record<string, unknown> = {
|
||||||
entry_date: entryDate,
|
entry_date: entryDate,
|
||||||
notes: notes || undefined,
|
notes: notes || undefined,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue