mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-12 13:26:45 +00:00
refactor: consolidate the routers
This commit is contained in:
parent
32be4bb0df
commit
3a66b00c74
5 changed files with 49 additions and 66 deletions
|
|
@ -7,10 +7,10 @@
|
||||||
type="text"
|
type="text"
|
||||||
class="grow"
|
class="grow"
|
||||||
placeholder="Search recipes..."
|
placeholder="Search recipes..."
|
||||||
|
:autofocus="autofocus"
|
||||||
@focus="isFocused = true"
|
@focus="isFocused = true"
|
||||||
@blur="isFocused = false"
|
@blur="isFocused = false"
|
||||||
:autofocus="autofocus"
|
>
|
||||||
/>
|
|
||||||
<kbd
|
<kbd
|
||||||
class="hidden md:inline-block kbd kbd-sm"
|
class="hidden md:inline-block kbd kbd-sm"
|
||||||
:class="{ 'opacity-50': !isFocused }"
|
:class="{ 'opacity-50': !isFocused }"
|
||||||
|
|
@ -28,9 +28,8 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const model = defineModel<string>();
|
const model = defineModel<string>();
|
||||||
const props = defineProps<{
|
defineProps<{ autofocus?: boolean }>();
|
||||||
autofocus?: boolean;
|
|
||||||
}>();
|
|
||||||
const isFocused = ref(false);
|
const isFocused = ref(false);
|
||||||
|
|
||||||
// Debounced navigation
|
// Debounced navigation
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,15 @@ export default defineNuxtConfig({
|
||||||
modules: [
|
modules: [
|
||||||
"@nuxt/eslint",
|
"@nuxt/eslint",
|
||||||
"@nuxt/image",
|
"@nuxt/image",
|
||||||
"nuxt-icon",
|
|
||||||
"nuxt-delay-hydration",
|
|
||||||
"@nuxtjs/robots",
|
"@nuxtjs/robots",
|
||||||
"@vueuse/nuxt",
|
"@vueuse/nuxt",
|
||||||
|
"nuxt-delay-hydration",
|
||||||
|
"nuxt-icon",
|
||||||
],
|
],
|
||||||
|
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
title: "Meal Planner",
|
title: "Mood2Food",
|
||||||
htmlAttrs: { lang: "en" },
|
htmlAttrs: { lang: "en" },
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: "utf-8" },
|
{ charset: "utf-8" },
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { publicProcedure, router } from "../trpc";
|
|
||||||
import {} from "~/types/recipe";
|
|
||||||
import {
|
|
||||||
categoriesResponseSchema,
|
|
||||||
type CategoriesResponse,
|
|
||||||
} from "~/types/category";
|
|
||||||
|
|
||||||
const { apiUrl } = useRuntimeConfig();
|
|
||||||
|
|
||||||
export const categoryRouter = router({
|
|
||||||
listCategories: publicProcedure.query(async () => {
|
|
||||||
const response = await $fetch<CategoriesResponse>(
|
|
||||||
new URL("categories.php", apiUrl).href,
|
|
||||||
);
|
|
||||||
|
|
||||||
const result = categoriesResponseSchema.safeParse(response);
|
|
||||||
|
|
||||||
if (!result.success) {
|
|
||||||
throw createError({
|
|
||||||
statusCode: 500,
|
|
||||||
statusMessage: "Invalid API response format",
|
|
||||||
data: result.error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.data.categories.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import type { inferRouterOutputs } from "@trpc/server";
|
import type { inferRouterOutputs } from "@trpc/server";
|
||||||
import { mergeRouters } from "../trpc";
|
import { mergeRouters } from "../trpc";
|
||||||
import { recipeRouter } from "./recipes";
|
import { recipeRouter } from "./recipes";
|
||||||
import { categoryRouter } from "./categories";
|
|
||||||
|
|
||||||
export const appRouter = mergeRouters(categoryRouter, recipeRouter);
|
export const appRouter = mergeRouters(recipeRouter);
|
||||||
// export type definition of API
|
// export type definition of API
|
||||||
export type AppRouter = typeof appRouter;
|
export type AppRouter = typeof appRouter;
|
||||||
export type RouterOutput = inferRouterOutputs<AppRouter>;
|
export type RouterOutput = inferRouterOutputs<AppRouter>;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { publicProcedure, router } from "../trpc";
|
import {
|
||||||
|
categoriesResponseSchema,
|
||||||
|
categoryRecipesResponseSchema,
|
||||||
|
type CategoriesResponse,
|
||||||
|
} from "~/types/category";
|
||||||
import type { Meal } from "~/types/recipe";
|
import type { Meal } from "~/types/recipe";
|
||||||
import { parseRecipeData } from "~/utils/recipes";
|
import { parseRecipeData } from "~/utils/recipes";
|
||||||
import { categoryRecipesResponseSchema } from "~/types/category";
|
import { publicProcedure, router } from "../trpc";
|
||||||
|
|
||||||
const { apiUrl } = useRuntimeConfig();
|
const { apiUrl } = useRuntimeConfig();
|
||||||
|
|
||||||
export const recipeRouter = router({
|
export const recipeRouter = router({
|
||||||
recipesByCategory: publicProcedure
|
recipesByCategory: publicProcedure.input(z.string()).query(async ({ input }) => {
|
||||||
.input(z.string())
|
const data = await $fetch<{ meals: Meal[] }>(new URL(`filter.php?c=${input}`, apiUrl).href);
|
||||||
.query(async ({ input }) => {
|
|
||||||
const data = await $fetch<{ meals: Meal[] }>(
|
|
||||||
new URL(`filter.php?c=${input}`, apiUrl).href,
|
|
||||||
);
|
|
||||||
|
|
||||||
const result = categoryRecipesResponseSchema.safeParse(data);
|
const result = categoryRecipesResponseSchema.safeParse(data);
|
||||||
|
|
||||||
|
|
@ -25,6 +25,7 @@ export const recipeRouter = router({
|
||||||
|
|
||||||
return result.data.recipes;
|
return result.data.recipes;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
recipeGet: publicProcedure
|
recipeGet: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.coerce
|
z.coerce
|
||||||
|
|
@ -32,12 +33,10 @@ export const recipeRouter = router({
|
||||||
required_error: "recipe id is required",
|
required_error: "recipe id is required",
|
||||||
invalid_type_error: "recipe id must be a number",
|
invalid_type_error: "recipe id must be a number",
|
||||||
})
|
})
|
||||||
.positive("recipe id must be positive"),
|
.positive("recipe id must be positive")
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
const data = await $fetch<{ meals: Meal[] }>(
|
const data = await $fetch<{ meals: Meal[] }>(new URL(`lookup.php?i=${input}`, apiUrl).href);
|
||||||
new URL(`lookup.php?i=${input}`, apiUrl).href,
|
|
||||||
);
|
|
||||||
if (!data?.meals) {
|
if (!data?.meals) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 404,
|
statusCode: 404,
|
||||||
|
|
@ -48,10 +47,9 @@ export const recipeRouter = router({
|
||||||
const recipes = parseRecipeData(data);
|
const recipes = parseRecipeData(data);
|
||||||
return recipes[0];
|
return recipes[0];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
recipeRandom: publicProcedure.query(async () => {
|
recipeRandom: publicProcedure.query(async () => {
|
||||||
const data = await $fetch<{ meals: Meal[] }>(
|
const data = await $fetch<{ meals: Meal[] }>(new URL("random.php", apiUrl).toString());
|
||||||
new URL("random.php", apiUrl).toString(),
|
|
||||||
);
|
|
||||||
if (!data?.meals) {
|
if (!data?.meals) {
|
||||||
throw createError({
|
throw createError({
|
||||||
statusCode: 500,
|
statusCode: 500,
|
||||||
|
|
@ -61,20 +59,35 @@ export const recipeRouter = router({
|
||||||
const recipes = parseRecipeData(data);
|
const recipes = parseRecipeData(data);
|
||||||
return recipes[0];
|
return recipes[0];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
recipeSearch: publicProcedure
|
recipeSearch: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
z.string({
|
z.string({
|
||||||
required_error: "search query is required",
|
required_error: "search query is required",
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
const data = await $fetch<{ meals: Meal[] }>(
|
const data = await $fetch<{ meals: Meal[] }>(new URL(`search.php?s=${input}`, apiUrl).href);
|
||||||
new URL(`search.php?s=${input}`, apiUrl).href,
|
|
||||||
);
|
|
||||||
if (!data?.meals) {
|
if (!data?.meals) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const recipes = parseRecipeData(data);
|
const recipes = parseRecipeData(data);
|
||||||
return recipes;
|
return recipes;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
listCategories: publicProcedure.query(async () => {
|
||||||
|
const response = await $fetch<CategoriesResponse>(new URL("categories.php", apiUrl).href);
|
||||||
|
|
||||||
|
const result = categoriesResponseSchema.safeParse(response);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
statusMessage: "Invalid API response format",
|
||||||
|
data: result.error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.data.categories.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue