Compare commits

...

3 Commits

Author SHA1 Message Date
5de09aa13b Merge branch 'fix_fetch' 2025-06-24 14:18:12 +02:00
7cc292296b fix shop 2025-06-24 14:14:40 +02:00
a000f966eb fix fetch 2025-06-24 12:05:43 +02:00
17 changed files with 3451 additions and 13523 deletions

View File

@ -1,6 +1,6 @@
module pocketbase module pocketbase
go 1.24.0 go 1.23.2
require ( require (
github.com/chai2010/webp v1.4.0 github.com/chai2010/webp v1.4.0

3150
bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<p class="text-lg xl:text-2xl font-extrabold text-black dark:text-white"> <p class="text-lg xl:text-2xl font-extrabold text-black dark:text-white">
{{ mainCategoryName }} {{ mainCategoryName }}
</p> </p>
<span :class="['flex items-center justify-center',isOpen && 'rotate-180', 'transition-all']"><i <span :class="['flex items-center justify-center', isOpen && 'rotate-180', 'transition-all']"><i
class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"></i></span> class="iconify i-lucide:chevron-down text-button shrink-0 size-6 ms-auto"></i></span>
</div> </div>
</div> </div>
@ -40,7 +40,7 @@ const toggle = () => {
}; };
// Computed properties // Computed properties
const hasMainCategory = computed(() => props.data.length > 0 && props.data[0].langs && props.data[0].langs.length > 0); const hasMainCategory = computed(() => props.data && props.data.length > 0 && props.data[0].langs && props.data[0].langs.length > 0);
const mainCategoryName = computed(() => hasMainCategory.value ? props.data[0].langs[0].Name : ''); const mainCategoryName = computed(() => hasMainCategory.value ? props.data[0].langs[0].Name : '');
const subcategories = computed(() => hasMainCategory.value && props.data[0].children ? props.data[0].children : []); const subcategories = computed(() => hasMainCategory.value && props.data[0].children ? props.data[0].children : []);
</script> </script>

View File

@ -78,9 +78,7 @@ type Component = {
]; ];
}; };
const props = defineProps<{ defineProps<{
component: Component; component: Component;
data: Object;
infoData: Object;
}>(); }>();
</script> </script>

View File

@ -17,7 +17,7 @@
</h1> </h1>
<div class="flex flex-col gap-[25px]"> <div class="flex flex-col gap-[25px]">
<div> <div>
<div v-if="categoriesList.length < 1" class="animate-pulse"> <div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
<div <div
class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24"> class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
<div class="w-32 h-4 bg-gray-200 rounded"></div> <div class="w-32 h-4 bg-gray-200 rounded"></div>
@ -34,7 +34,8 @@
<div v-for="(item, itemIndex) in filters" :key="itemIndex" <div v-for="(item, itemIndex) in filters" :key="itemIndex"
:class="['mb-[30px]', visibleFeatures[item.feature] && 'border-b border-block pb-2']"> :class="['mb-[30px]', visibleFeatures[item.feature] && 'border-b border-block pb-2']">
<span class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base" <span
class="flex justify-between items-center font-bold cursor-pointer mb-[25px] text-base"
@click="toggleFeature(item.feature)"> @click="toggleFeature(item.feature)">
{{ item.feature }} {{ item.feature }}
<span :class="[visibleFeatures[item.feature] && 'rotate-180', 'transition-all']"><i <span :class="[visibleFeatures[item.feature] && 'rotate-180', 'transition-all']"><i
@ -69,7 +70,7 @@
<div class="flex flex-col gap-12"> <div class="flex flex-col gap-12">
<div> <div>
<div v-if="categoriesList.length < 1" class="animate-pulse"> <div v-if="categoriesList && categoriesList.length < 1" class="animate-pulse">
<div <div
class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24"> class="flex items-center justify-between mt-4 text-white rounded-lg cursor-pointer xl:pr-24">
<div class="w-32 h-4 bg-gray-200 rounded"></div> <div class="w-32 h-4 bg-gray-200 rounded"></div>
@ -167,7 +168,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from "vue"; import { ref } from "vue";
import Product from "./Product.vue"; import Product from "./Product.vue";
import type { Feature, ProductType } from "~/types"; import type { Feature, GenericResponse, GenericResponseChildren, GenericResponseItems, ProductType } from "~/types";
import CategoryTree from "./CategoryTree.vue"; import CategoryTree from "./CategoryTree.vue";
defineProps<{ component: Component }>(); defineProps<{ component: Component }>();
@ -199,19 +200,21 @@ const maxElements = ref(0);
const products = ref([] as ProductType[]); const products = ref([] as ProductType[]);
async function getProducts() { async function getProducts() {
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
`http://127.0.0.1:4000/api/public/products/category/${categoryId.value}?p=${page.value}&elems=${elems.value}`, `/api/public/products/category/${categoryId.value}?p=${page.value}&elems=${elems.value}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json();
products.value = data.data.items; products.value = data.items;
maxElements.value = data.data.items_count + 1; maxElements.value = data.items_count + 1;
} catch (error) { } catch (error) {
console.error("getProducts error:", error); console.error("getProducts error:", error);
@ -221,18 +224,20 @@ async function getProducts() {
const filters = ref([] as Feature[]); const filters = ref([] as Feature[]);
async function getCategory() { async function getCategory() {
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponse<object>>(
`http://127.0.0.1:4000/api/public/products/category/1/classification`, `/api/public/products/category/1/classification`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json();
filters.value = data.data as Feature[]; filters.value = data as Feature[];
filters.value.forEach((el) => { filters.value.forEach((el) => {
const parentId = el.feature_id; const parentId = el.feature_id;
el.feature_values.forEach((el) => { el.feature_values.forEach((el) => {
@ -245,20 +250,22 @@ async function getCategory() {
} }
} }
const categoriesList = ref([]); const categoriesList = ref();
async function getCategoryTree() { async function getCategoryTree() {
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseChildren<ProductType[]>>(
`http://127.0.0.1:4000/api/public/categories/tree`, `/api/public/categories/tree`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json(); categoriesList.value = data.children;
categoriesList.value = data.data.children;
} catch (error) { } catch (error) {
console.error("getCategory error:", error); console.error("getCategory error:", error);
@ -325,20 +332,22 @@ async function loadMoreProducts() {
qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null); qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null);
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
`http://127.0.0.1:4000/api/public/products/category/${categoryId.value}?${qParams.toString()}`, `/api/public/products/category/${categoryId.value}?${qParams.toString()}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json(); maxElements.value = data.items_count;
maxElements.value = data.data.items_count;
if (data.data.items) { if (data.items) {
products.value.push(...(data.data.items as ProductType[])); products.value.push(...(data.items as ProductType[]));
} else { } else {
reachedEnd.value = true; reachedEnd.value = true;
} }
@ -369,18 +378,20 @@ watch(selectedFilters, async (newQuestion) => {
qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null); qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null);
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
`http://127.0.0.1:4000/api/public/products/category/1?${qParams.toString()}`, `/api/public/products/category/1?${qParams.toString()}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json(); products.value = data.items;
products.value = data.data.items; maxElements.value = data.items_count;
maxElements.value = data.data.items_count;
} catch (error) { } catch (error) {
console.error("selectedFilters error:", error); console.error("selectedFilters error:", error);
@ -401,18 +412,20 @@ watch(categoryId, async (newQuestion) => {
qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null); qParams.append("features", selectedFilters.value.length > 0 ? selectedFilters.value : null);
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
`http://127.0.0.1:4000/api/public/products/category/${categoryId.value}?${qParams.toString()}`, `api/public/products/category/${categoryId.value}?${qParams.toString()}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
} }
); );
const data = await res.json(); products.value = data.items;
products.value = data.data.items; maxElements.value = data.items_count;
maxElements.value = data.data.items_count;
} catch (error) { } catch (error) {
console.error("getCategory error:", error); console.error("getCategory error:", error);

View File

@ -1,7 +1,7 @@
import { ofetch } from "ofetch"; import { ofetch } from "ofetch";
export interface RequestOptions<T> extends RequestInit { export interface RequestOptions<T> extends RequestInit {
onError?: (error: Error, statusCode: number) => void; onErrorOccured?: (error: Error, statusCode: number) => Promise<void>;
onSuccess?: (data: T, statusCode: number) => void; onSuccess?: (data: T, statusCode: number) => void;
onStart?: () => void; onStart?: () => void;
} }
@ -24,7 +24,7 @@ export interface RequestOptions<T> extends RequestInit {
export const useMyFetch = async <T>( export const useMyFetch = async <T>(
url: string, url: string,
options?: RequestOptions<T> options?: RequestOptions<T>
): Promise<T | undefined> => { ): Promise<T> => {
if (options?.onStart) options.onStart(); if (options?.onStart) options.onStart();
let response = null; let response = null;
try { try {
@ -50,23 +50,23 @@ export const useMyFetch = async <T>(
} }
// handle errors if any // handle errors if any
if (!response.ok && typeof options.onError == "function") { if (!response.ok && typeof options.onErrorOccured == "function") {
options.onError(new Error(response.statusText), response.status); options.onErrorOccured(new Error(response.statusText), response.status);
} }
// handle success to be able clearly marked that request has finished // handle success to be able clearly marked that request has finished
if (response.ok && typeof options.onSuccess == "function") { if (response.ok && typeof options.onSuccess == "function") {
options.onSuccess(response._data.data, response.status); options.onSuccess(response._data, response.status);
} }
return response._data as T; return response._data as T;
} catch (e) { } catch (e) {
// handle errors if any // handle errors if any
if (typeof options?.onError == "function") { if (typeof options?.onErrorOccured == "function") {
options.onError(e as Error, response?.status || 500); options.onErrorOccured(e as Error, response?.status || 500);
} else { } else {
console.error(e); console.error(e);
} }
return undefined; return {} as T;
} }
}; };

11
error.vue Normal file
View File

@ -0,0 +1,11 @@
<template>
<div class="p-10 text-center">
<h1 class="text-3xl font-bold">Error {{ error?.statusCode }}</h1>
<p class="mt-4 text-gray-600">{{ error?.statusMessage }}</p>
<NuxtLink to="/" class="mt-6 text-blue-500 underline">Go back home</NuxtLink>
</div>
</template>
<script setup lang="ts">
defineProps({ error: Object })
</script>

View File

@ -11,6 +11,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
// import FooterBlock from "~/components/section/FooterBlock.vue";
useHead({ useHead({
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.png" }], link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.png" }],
}); });

View File

@ -42,6 +42,9 @@ export default defineNuxtConfig({
watch: { watch: {
ignored: ["**/backend/pb_data/**"], ignored: ["**/backend/pb_data/**"],
}, },
hmr: {
clientPort: 3000, // useful if proxying
}
}, },
}, },
typescript: { typescript: {

13372
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,11 @@
import { usePB } from "~/composables/usePB"; import { usePB } from "~/composables/usePB";
import type { import type {
CountryList, Country,
Currencies, Currencies,
Currency,
FooterListResponse, FooterListResponse,
GenericResponse,
GenericResponseItems,
MenuListResponse, MenuListResponse,
PBFooterItem, PBFooterItem,
PBMenuItem, PBMenuItem,
@ -10,6 +13,7 @@ import type {
} from "~/types"; } from "~/types";
import { useStore } from "./store"; import { useStore } from "./store";
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import { useMyFetch } from "#imports";
function buildTreeRecursive( function buildTreeRecursive(
data: (PBMenuItem | UIMenuItem)[], data: (PBMenuItem | UIMenuItem)[],
@ -41,8 +45,8 @@ export const useMenuStore = defineStore("menuStore", () => {
const menuItems = ref<MenuListResponse>(); const menuItems = ref<MenuListResponse>();
const footerItems = ref<FooterListResponse>(); const footerItems = ref<FooterListResponse>();
const countryList = ref<CountryList[]>(); const countryList = ref<Country[]>();
const currencies = ref<Currencies[]>(); const currencies = ref<Currency[]>();
// curr/country // curr/country
const selectedCountry = ref(); const selectedCountry = ref();
@ -87,8 +91,8 @@ export const useMenuStore = defineStore("menuStore", () => {
const getCountryList = async () => { const getCountryList = async () => {
try { try {
const res = await fetch( const {data} = await useMyFetch<GenericResponse<Country[]>>(
`http://127.0.0.1:4000/api/public/country/list`, `/api/public/country/list`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -96,12 +100,12 @@ export const useMenuStore = defineStore("menuStore", () => {
} }
); );
if (!res.ok) { // if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`); // throw new Error(`HTTP error: ${res.status}`);
} // }
const data = await res.json(); // const data = await res.json();
countryList.value = data.data countryList.value = data
if (countryList.value) if (countryList.value)
selectedPhoneCountry.value = countryList.value[0] selectedPhoneCountry.value = countryList.value[0]
@ -112,21 +116,25 @@ export const useMenuStore = defineStore("menuStore", () => {
const getCurrencies = async () => { const getCurrencies = async () => {
try { try {
const res = await fetch( const {data} = await useMyFetch<GenericResponseItems<Currency[]>>(
`http://127.0.0.1:4000/api/public/currencies`, `/api/public/currencies`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
} }
); );
if (!res.ok) { // if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`); // throw new Error(`HTTP error: ${res.status}`);
} // }
const data = await res.json(); // const data = await res.json();
currencies.value = data.data.items currencies.value = data.items
// console.log(data.items, "data");
} catch (error) { } catch (error) {
console.error("getList error:", error); console.error("getList error:", error);
} }

View File

@ -1,24 +1,31 @@
import { NuxtErrorBoundary } from "#components";
import { useMyFetch } from "#imports";
import type { GenericResponse, GenericResponseItems, UserCart } from "~/types";
import type { Product } from "~/types/product";
export const useProductStore = defineStore("productStore", () => { export const useProductStore = defineStore("productStore", () => {
const productList = ref(); const productList = ref<Product>();
const modules = ref(); const modules = ref();
async function getList(count: number, categoryId = 1) { async function getList(count: number, categoryId = 1) {
try { try {
const res = await fetch( const { data } = await useMyFetch<GenericResponseItems<Product>>(
`http://127.0.0.1:4000/api/public/products/category/${categoryId}?p=1&elems=${count}`, `/api/public/products/category/${categoryId}?p=1&elems=${count}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: async (_, status) => {
// await navigateTo("/error", { replace: true });
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
},
} }
); );
if (!res.ok) { productList.value = data.items;
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
productList.value = data.data.items;
} catch (error) { } catch (error) {
console.error("getList error:", error); console.error("getList error:", error);
} }
@ -49,7 +56,7 @@ export const useProductStore = defineStore("productStore", () => {
} }
} }
async function addToCart(product) { async function addToCart(product: Product) {
try { try {
const res = await fetch( const res = await fetch(
`http://127.0.0.1:4000/api/public/user/cart/item/add/${product.id}/1`, `http://127.0.0.1:4000/api/public/user/cart/item/add/${product.id}/1`,
@ -72,27 +79,30 @@ export const useProductStore = defineStore("productStore", () => {
} }
} }
const cart = ref(); const cart = ref({} as UserCart);
// async function getCart() { async function getCart() {
// try { try {
// const res = await fetch(`http://127.0.0.1:4000/api/public/user/cart`, { const { data } = await useMyFetch<GenericResponse<UserCart>>(
// headers: { `/api/public/user/cart`,
// "Content-Type": "application/json", {
// }, headers: {
// }); "Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
// if (!res.ok) { // if (!res.ok) {
// throw new Error(`HTTP error: ${res.status}`); // throw new Error(`HTTP error: ${res.status}`);
// } // }
// const data = await res.json(); cart.value = data;
// console.log(data); } catch (error) {
console.error("getList error:", error);
// cart.value = data; }
// } catch (error) { }
// console.error("getList error:", error);
// }
// }
return { return {
productList, productList,

View File

@ -1,5 +1,6 @@
import { useMyFetch } from "#imports";
import { usePB } from "~/composables/usePB"; import { usePB } from "~/composables/usePB";
import type { componentsListType, PBPageItem } from "~/types"; import type { componentsListType, GenericResponse, PBPageItem, PlanPrediction } from "~/types";
// import { useI18n } from "vue-i18n"; // import { useI18n } from "vue-i18n";
export const useStore = defineStore("store", () => { export const useStore = defineStore("store", () => {
@ -10,7 +11,7 @@ export const useStore = defineStore("store", () => {
// calculator // calculator
const monthlySavings = ref(137); const monthlySavings = ref(137);
const storagePeriod = ref(10); const storagePeriod = ref(10);
const totalInvestment = ref() const totalInvestment:Ref<number> = ref(0)
const minValue = ref() const minValue = ref()
// login // login
@ -71,21 +72,17 @@ export const useStore = defineStore("store", () => {
async function getCalculator() { async function getCalculator() {
try { try {
const res = await fetch( const {data} = await useMyFetch<GenericResponse<PlanPrediction>>(
`http://127.0.0.1:4000/api/public/plan-prediction/easy/calculate?monthly_deposit=${monthlySavings.value}&years=${storagePeriod.value}`, `/api/public/plan-prediction/easy/calculate?monthly_deposit=${monthlySavings.value}&years=${storagePeriod.value}`,
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
} }
); );
if (!res.ok) { totalInvestment.value = data.total_investement_value
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
totalInvestment.value = data.data.total_investement_value
} catch (error) { } catch (error) {
console.error("getList error:", error); console.error("getList error:", error);
@ -94,21 +91,22 @@ export const useStore = defineStore("store", () => {
async function getMinValue() { async function getMinValue() {
try { try {
const res = await fetch( const {data} = await useMyFetch<GenericResponse<number>>(
'http://127.0.0.1:4000/api/public/plan-prediction/free/minimum', '/api/public/plan-prediction/free/minimum',
{ {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
} }
); );
if (!res.ok) { // if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`); // throw new Error(`HTTP error: ${res.status}`);
} // }
const data = await res.json(); // const data = await res.json();
minValue.value = data.data minValue.value = data
} catch (error) { } catch (error) {
console.error("getList error:", error); console.error("getList error:", error);

View File

@ -69,29 +69,29 @@ tasks:
desc: "build and watch frontend in dev mode" desc: "build and watch frontend in dev mode"
cmds: cmds:
- | - |
pnpm run dev bun run dev
preview_front: preview_front:
aliases: [pf] aliases: [pf]
desc: "build and preview frontend" desc: "build and preview frontend"
cmds: cmds:
- | - |
pnpm run build && pnpm run preview bun run build && bun run preview
rebuild_front: rebuild_front:
aliases: [rf] aliases: [rf]
desc: "remove all and install all packages" desc: "remove all and install all packages"
cmds: cmds:
- | - |
rm -rf ./node_modules ./pnpm-lock.yaml ./.nuxt ./.output rm -rf ./node_modules ./bun-lock ./.nuxt ./.output
pnpm install bun install
# build_docker_image: # build_docker_image:
# aliases: [bdi] # aliases: [bdi]
# desc: "build docker image" # desc: "build docker image"
# cmds: # cmds:
# - | # - |
# pnpm run build # bun run build
# task compile_gnu # task compile_gnu
# cat <<EOF > temp.Dockerfile # cat <<EOF > temp.Dockerfile
# FROM node:slim # FROM node:slim

View File

@ -1,3 +1,5 @@
import type { DefineComponent } from "vue";
export interface ListResponse { export interface ListResponse {
page: number; page: number;
perPage: number; perPage: number;
@ -42,7 +44,7 @@ export interface PBFooterItem {
}>; }>;
data: Array<{ data: Array<{
title: string; title: string;
items: Array<string> items: Array<string>;
}>; }>;
company_info: Array<{ company_info: Array<{
data: string; data: string;
@ -69,7 +71,6 @@ export interface PBPageItem {
section_name: string; section_name: string;
} }
import type { DefineComponent } from "vue";
export interface SectionLangData { export interface SectionLangData {
title: string; title: string;
description: string; description: string;
@ -97,25 +98,25 @@ export type componentsListType = {
}; };
// menuStore // menuStore
export type CountryList = { // export type CountryList = {
call_prefix: string; // call_prefix: string;
currency_iso_code: string; // currency_iso_code: string;
iso_code: string; // iso_code: string;
name: string; // name: string;
} // }
export type Countries = { export type Countries = {
call_prefix: string; call_prefix: string;
currency_iso_code: string; currency_iso_code: string;
iso_code: string; iso_code: string;
name: string; name: string;
} };
export type PartnersList = { export type PartnersList = {
country_iso: string; country_iso: string;
country_name: string; country_name: string;
total: number; total: number;
} };
export type Currencies = { export type Currencies = {
iso_code: string; iso_code: string;
@ -126,34 +127,88 @@ export type Currencies = {
sign: string; sign: string;
active: boolean; active: boolean;
suffix: boolean; suffix: boolean;
} };
export type FeatureValue = { export type FeatureValue = {
parent: number, parent: number;
products_with_value: number, products_with_value: number;
value: string, value: string;
value_id: number, value_id: number;
} };
export type Feature = { export type Feature = {
feature: string, feature: string;
feature_id: number, feature_id: number;
feature_values: FeatureValue[], feature_values: FeatureValue[];
products_with_feature: number, products_with_feature: number;
} };
export type ProductType = { export type ProductType = {
applied_tax_rate: number, applied_tax_rate: number;
cover_picture_uuid: string, cover_picture_uuid: string;
description: string, description: string;
formatted_price: string, formatted_price: string;
id: number, id: number;
in_stock: number, in_stock: number;
is_sale_active: boolean, is_sale_active: boolean;
link_rewrite: string, link_rewrite: string;
name: string, name: string;
price: number, price: number;
tax_name: string, tax_name: string;
cart_item_id?: number cart_item_id?: number;
product_id?: number product_id?: number;
} };
export interface Country {
iso_code: string;
currency_iso_code: string;
call_prefix: string;
need_postcode: boolean;
postcode_format: string;
is_default: boolean;
active: boolean;
name: string;
}
export interface Currency {
iso_code: string;
name: string;
UpdatedAt: string;
iso_code_num: number;
precision: number;
sign: string;
active: boolean;
suffix: boolean;
}
export interface UserCart {
id: number;
checkout_in_progress: boolean;
total_value: number;
currency_iso: string;
}
export interface GenericResponse<Data> {
data: Data;
message?: string;
status: number;
}
export interface GenericResponseItems<Data> {
data: { items: Data; items_count: number };
message?: string;
status: number;
}
export interface GenericResponseChildren<Data> {
data: { children: Data; items_count: number };
message?: string;
status: number;
}
export type {
InvestmentPiece,
PlanPrediction,
PeriodToFirstPiece,
} from "./planPrediction";
export type { Product } from "./product";

40
types/planPrediction.ts Normal file
View File

@ -0,0 +1,40 @@
export interface PlanPrediction {
total_investement_value: number
total_input_price_increase: number
total_input_price_increase_covered_pieces: number
months_spent_on_plan: number
money_spent: number
bought_pieces: number
annual_investment_return: number
investment_piece: InvestmentPiece
max_pieces_in_package: number
period_to_first_piece: PeriodToFirstPiece
}
export interface InvestmentPiece {
referenced_product_id: number
name: string
cover_picture_uuid: string
weight: string
active: boolean
price: number
price_per_gram: number
currency_iso: string
currency_conversion_rate: string
max_comission_value: number
average_input_price_increase: number
features: Feature[]
}
export interface Feature {
feature_id: number
feature: string
value_id: number
value: string
}
export interface PeriodToFirstPiece {
years: number
months: number
days: number
}

13
types/product.ts Normal file
View File

@ -0,0 +1,13 @@
export interface Product {
id: number;
link_rewrite: string;
name: string;
cover_picture_uuid: string;
description: string;
price: number;
formatted_price: string;
in_stock: number;
is_sale_active: boolean;
applied_tax_rate: number;
tax_name: string;
}