diff --git a/frontend.old/src/components/UI/TheRecipeFab.vue b/frontend.old/src/components/UI/TheRecipeFab.vue
index e9e6cb46d14e..8136527ff534 100644
--- a/frontend.old/src/components/UI/TheRecipeFab.vue
+++ b/frontend.old/src/components/UI/TheRecipeFab.vue
@@ -44,13 +44,13 @@
target="_blank"
rel="noreferrer nofollow"
>
- {{ $t('new-recipe.google-ld-json-info') }}
+ {{ $t("new-recipe.google-ld-json-info") }}
- {{ $t('new-recipe.github-issues') }}
+ {{ $t("new-recipe.github-issues") }}
- {{ $t('new-recipe.recipe-markup-specification') }}
+ {{ $t("new-recipe.recipe-markup-specification") }}
@@ -61,7 +61,7 @@
@click="addRecipe = false"
>
{{ $globals.icons.externalLink }}
- {{ $t('new-recipe.view-scraped-data') }}
+ {{ $t("new-recipe.view-scraped-data") }}
@@ -101,7 +101,7 @@
-
+
@@ -140,11 +140,11 @@
diff --git a/frontend/components/Domain/Recipe/RecipeCardImage.vue b/frontend/components/Domain/Recipe/RecipeCardImage.vue
index 81763290cee6..6cb2546136db 100644
--- a/frontend/components/Domain/Recipe/RecipeCardImage.vue
+++ b/frontend/components/Domain/Recipe/RecipeCardImage.vue
@@ -18,7 +18,7 @@
\ No newline at end of file
diff --git a/frontend/components/global/AppButtonUpload.vue b/frontend/components/global/AppButtonUpload.vue
new file mode 100644
index 000000000000..25b92848936e
--- /dev/null
+++ b/frontend/components/global/AppButtonUpload.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+ {{ effIcon }}
+ {{ text ? text : defaultText }}
+
+
+
+
+
+
+
+
diff --git a/frontend/components/global/BaseButton.vue b/frontend/components/global/BaseButton.vue
index e6b17062eba8..078ffce08dfb 100644
--- a/frontend/components/global/BaseButton.vue
+++ b/frontend/components/global/BaseButton.vue
@@ -1,6 +1,6 @@
-
+
{{ $t("general.confirm") }}
diff --git a/frontend/composables/use-api.ts b/frontend/composables/use-api.ts
index 4bf7ab5464ec..a0797ca3db8e 100644
--- a/frontend/composables/use-api.ts
+++ b/frontend/composables/use-api.ts
@@ -56,7 +56,7 @@ function getRequests(axoisInstance: NuxtAxiosInstance): ApiRequestInstance {
-export const useApi = function (): Api {
+export const useApiSingleton = function (): Api {
const { $axios } = useContext();
const requests = getRequests($axios);
diff --git a/frontend/composables/use-recipe-context.ts b/frontend/composables/use-recipe-context.ts
new file mode 100644
index 000000000000..1e8c42586e26
--- /dev/null
+++ b/frontend/composables/use-recipe-context.ts
@@ -0,0 +1,38 @@
+import { useAsync, ref } from "@nuxtjs/composition-api";
+import { useApiSingleton } from "~/composables/use-api";
+import { Recipe } from "~/types/api-types/recipe";
+
+export const useRecipeContext = function () {
+ const api = useApiSingleton();
+ const loading = ref(false)
+
+
+ function getBySlug(slug: string) {
+ loading.value = true
+ const recipe = useAsync(async () => {
+ const { data } = await api.recipes.getOne(slug);
+ return data;
+ }, slug);
+
+ loading.value = false
+
+ return recipe;
+ }
+
+ async function deleteRecipe(slug: string) {
+ loading.value = true
+ const { data } = await api.recipes.deleteOne(slug);
+ loading.value = false
+ return data;
+ }
+
+ async function updateRecipe(slug: string, recipe: Recipe) {
+ loading.value = true
+ const { data } = await api.recipes.updateOne(slug, recipe);
+ loading.value = false
+ return data;
+ }
+
+
+ return {loading, getBySlug, deleteRecipe, updateRecipe}
+};
diff --git a/frontend/composables/use-validators.ts b/frontend/composables/use-validators.ts
index 3e27ffeaa547..81f8b7470676 100644
--- a/frontend/composables/use-validators.ts
+++ b/frontend/composables/use-validators.ts
@@ -1,8 +1,11 @@
const EMAIL_REGEX =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+const URL_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,256}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/gm;
+
export const validators = {
required: (v: string) => !!v || "This Field is Required",
email: (v: string) => !v || EMAIL_REGEX.test(v) || "Email Must Be Valid",
- whitespace: (v: string) => !v || v.split(" ").length <= 1 || "No Whitespace Allowed"
+ whitespace: (v: string) => !v || v.split(" ").length <= 1 || "No Whitespace Allowed",
+ url: (v: string) => !v || URL_REGEX.test(v) || "Must Be A Valid URL",
}
diff --git a/frontend/layouts/default.vue b/frontend/layouts/default.vue
index f0fb6cee2e09..3a52b6cf89dc 100644
--- a/frontend/layouts/default.vue
+++ b/frontend/layouts/default.vue
@@ -28,7 +28,7 @@ import AppFloatingButton from "@/components/Layout/AppFloatingButton.vue";
export default defineComponent({
components: { AppHeader, AppSidebar, AppFloatingButton },
// @ts-ignore
- middleware: process.env.PUBLIC_SITE ? null : "auth",
+ middleware: process.env.GLOBAL_MIDDLEWARE,
setup() {
return {};
},
diff --git a/frontend/nuxt.config.js b/frontend/nuxt.config.js
index 7e4adce336f4..c36ba0a2ae98 100644
--- a/frontend/nuxt.config.js
+++ b/frontend/nuxt.config.js
@@ -12,6 +12,10 @@ export default {
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
},
+ router: {
+ base: process.env.SUB_PATH || "",
+ },
+
layoutTransition: {
name: "layout",
mode: "out-in",
@@ -36,9 +40,13 @@ export default {
"@nuxtjs/composition-api/module",
],
+ publicRuntimeConfig: {
+ GLOBAL_MIDDLEWARE: process.env.GLOBAL_MIDDLEWARE || null,
+ ALLOW_SIGNUP: process.env.ALLOW_SIGNUP || true,
+ },
+
env: {
- PUBLIC_SITE: process.env.PUBLIC_SITE || true,
- BASE_URL: process.env.BASE_URL || "",
+ GLOBAL_MIDDLEWARE: process.env.GLOBAL_MIDDLEWARE || null,
ALLOW_SIGNUP: process.env.ALLOW_SIGNUP || true,
},
diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue
index 3d3d96a42a34..8aed55519945 100644
--- a/frontend/pages/index.vue
+++ b/frontend/pages/index.vue
@@ -7,13 +7,13 @@
-
-
\ No newline at end of file
+
+
diff --git a/frontend/pages/recipes/all.vue b/frontend/pages/recipes/all.vue
index bb6aebe3f129..1ad43e8246ce 100644
--- a/frontend/pages/recipes/all.vue
+++ b/frontend/pages/recipes/all.vue
@@ -1,16 +1,38 @@
-
-
+
+
+
+
-
-
\ No newline at end of file
+import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api";
+import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
+import { useApiSingleton } from "~/composables/use-api";
+import { Recipe } from "~/types/api-types/admin";
+
+export default defineComponent({
+ components: { RecipeCardSection },
+ setup() {
+ const api = useApiSingleton();
+
+ const recipes = ref([]);
+ onMounted(async () => {
+ const { data } = await api.recipes.getAll();
+ recipes.value = data;
+ });
+
+ return { api, recipes };
+ },
+ methods: {
+ assignSorted(val: Array) {
+ this.recipes = val;
+ },
+ },
+});
+
+
\ No newline at end of file
diff --git a/frontend/pages/user/login.vue b/frontend/pages/user/login.vue
index 154f43f51984..61e1756081c3 100644
--- a/frontend/pages/user/login.vue
+++ b/frontend/pages/user/login.vue
@@ -178,7 +178,7 @@
- Sign Up
+ Sign Up
Invite Only
diff --git a/frontend/plugins/globals.js b/frontend/plugins/globals.js
index f0fd42ee3217..27b4b6363925 100644
--- a/frontend/plugins/globals.js
+++ b/frontend/plugins/globals.js
@@ -20,6 +20,7 @@ import {
mdiEmail,
mdiLock,
mdiEye,
+ mdiDrag,
mdiEyeOff,
mdiCalendarMinus,
mdiCalendar,
@@ -38,7 +39,6 @@ import {
mdiFilePdfBox,
mdiFileImage,
mdiCodeJson,
- mdiArrowUpDown,
mdiCog,
mdiSort,
mdiOrderAlphabeticalAscending,
@@ -103,7 +103,7 @@ const icons = {
alertCircle: mdiAlertCircle,
api: mdiApi,
arrowLeftBold: mdiArrowLeftBold,
- arrowUpDown: mdiArrowUpDown,
+ arrowUpDown: mdiDrag,
backupRestore: mdiBackupRestore,
bellAlert: mdiBellAlert,
broom: mdiBroom,
diff --git a/frontend/template.env b/frontend/template.env
new file mode 100644
index 000000000000..606ab3787d7a
--- /dev/null
+++ b/frontend/template.env
@@ -0,0 +1,3 @@
+GLOBAL_MIDDLEWARE=null # null or 'auth'
+BASE_URL = ""
+ALLOW_SIGNUP=true
\ No newline at end of file
diff --git a/frontend/types/api-types/admin.ts b/frontend/types/api-types/admin.ts
index 2d86f73d1b39..1fd75f86c4dc 100644
--- a/frontend/types/api-types/admin.ts
+++ b/frontend/types/api-types/admin.ts
@@ -62,8 +62,8 @@ export interface RecipeCategoryResponse {
}
export interface Recipe {
id?: number;
- name?: string;
- slug?: string;
+ name: string;
+ slug: string;
image?: unknown;
description?: string;
recipeCategory?: string[];
diff --git a/frontend/types/api-types/recipe.ts b/frontend/types/api-types/recipe.ts
index 1cf74ba7ef8e..683abafde1a4 100644
--- a/frontend/types/api-types/recipe.ts
+++ b/frontend/types/api-types/recipe.ts
@@ -49,8 +49,8 @@ export interface Nutrition {
}
export interface Recipe {
id?: number;
- name?: string;
- slug?: string;
+ name: string;
+ slug: string;
image?: unknown;
description?: string;
recipeCategory?: string[];
diff --git a/frontend/types/api.ts b/frontend/types/api.ts
index 772d1e027f59..468316835568 100644
--- a/frontend/types/api.ts
+++ b/frontend/types/api.ts
@@ -7,10 +7,10 @@ interface RequestResponse {
}
export interface ApiRequestInstance {
- get(url: string, data?: object): Promise>;
- post(url: string, data: object): Promise>;
- put(url: string, data: object): Promise>;
- patch(url: string, data: object): Promise>;
- delete(url: string, data: object): Promise>;
+ get(url: string, data?: T | object): Promise>;
+ post(url: string, data: T | object): Promise>;
+ put(url: string, data: T | object): Promise>;
+ patch(url: string, data: T | object): Promise>;
+ delete(url: string, data?: T | object): Promise>;
}
diff --git a/frontend/types/ts-shim.d.ts b/frontend/types/ts-shim.d.ts
new file mode 100644
index 000000000000..31f47b3910f7
--- /dev/null
+++ b/frontend/types/ts-shim.d.ts
@@ -0,0 +1,8 @@
+declare module "*.vue" {
+ import Vue from "vue"
+ export default Vue
+}
+
+interface VForm extends HTMLFormElement {
+ validate(): boolean;
+}
\ No newline at end of file