Compare commits

..

1 Commits

Author SHA1 Message Date
49d83493da . 2025-05-19 10:40:08 +03:30
26 changed files with 503 additions and 1061 deletions

4
.env
View File

@ -1,4 +1,4 @@
NUXT_PUBLIC_API_NAME=api/
NUXT_PUBLIC_API_NAME=hapi/
NUXT_PUBLIC_BASE_URL=/
# For more information refere to documents: https://cli.vuejs.org/guide/mode-and-env.html#example-staging-mode
@ -114,5 +114,3 @@ VITE_HELP_PAGE=راهنمای سایت
# modules
# [listRoutes, chatRoutes, tahrirRoutes, jahatRoutes, borhanRoutes, thiqatRoutes]
VITE_BUILD_MODULES=listRoutes,tahrirRoutes,jahatRoutes,thiqatRoutes
NUXT_SESSION_PASSWORD=7a5eb85e8b5b43f6b09b73741bf9f6f9

View File

@ -1,5 +1,4 @@
# NUXT_PUBLIC_BASE_URL=http://192.168.23.161/
NUXT_PUBLIC_BASE_URL=https://hadithai.ir/
NUXT_PUBLIC_BASE_URL=http://192.168.23.161/
VITE_APP_NAME=Hadith

View File

@ -1,9 +1,6 @@
Add new repo:
git submodule add https://git2.tavasi.ir/front/chat_ui.git systems/chat_ui -f
clone from a single branch
git clone --single-branch --branch rezae/feat/add-task-module --recurse-submodules https://git2.tavasi.ir/front/base_ui.git
Cloning a Repository with Submodules
If you clone a repository that contains submodules, you'll need to initialize and update the submodules:
git clone repository-url

View File

@ -1,11 +0,0 @@
import type { UseFetchOptions } from 'nuxt/app'
export function useApi<T>(
url: string | (() => string),
options?: UseFetchOptions<T>,
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api as typeof $fetch
})
}

View File

@ -1,22 +0,0 @@
// // composables/useAuth.js
// export function useAuth() {
// const token = ref(sessionStorage.getItem('id_token'));
// const setToken = (newToken) => {
// token.value = newToken;
// localStorage.setItem('id_token', newToken);
// };
// const clearToken = () => {
// token.value = null;
// localStorage.removeItem('id_token');
// sessionStorage.removeItem('id_token');
// };
// return {
// token,
// setToken,
// clearToken,
// };
// }

View File

@ -1,81 +0,0 @@
import type { FetchOptions } from 'ofetch'
import { useStorage } from '@vueuse/core'
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
interface HttpRequestOptions<T = unknown> extends FetchOptions {
data?: T
}
export const useHttpService = () => {
const config = useRuntimeConfig()
const token = useStorage('id_token', 'GuestAccess')
/**
* Constructs the full API URL
*/
const getFullUrl = (endpoint: string): string => {
return `${config.public.NUXT_PUBLIC_BASE_URL}${config.public.NUXT_PUBLIC_API_NAME}${endpoint}`
}
/**
* Base fetch method with common configuration
*/
const baseFetch = async <T = any>(
method: HttpMethod,
url: string,
options: HttpRequestOptions = {}
) => {
const headers = {
...options.headers,
...(token.value ? { Authorization: token.value } : {})
}
try {
const response = await $fetch<T>(getFullUrl(url), {
method,
headers,
...options,
body: options.data || options.body
})
return response
} catch (error) {
// Handle errors globally or rethrow for specific handling
console.error(`HTTP ${method} error for ${url}:`, error)
throw error
}
}
return {
/**
* GET request
*/
getRequest: <T = any>(url: string, options?: HttpRequestOptions) =>
baseFetch<T>('GET', url, options),
/**
* POST request
*/
postRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
baseFetch<T>('POST', url, { ...options, data }),
/**
* PUT request
*/
putRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
baseFetch<T>('PUT', url, { ...options, data }),
/**
* PATCH request
*/
patchRequest: <T = any>(url: string, data?: any, options?: HttpRequestOptions) =>
baseFetch<T>('PATCH', url, { ...options, data }),
/**
* DELETE request
*/
deleteRequest: <T = any>(url: string, options?: HttpRequestOptions) =>
baseFetch<T>('DELETE', url, options)
}
}

View File

@ -1,118 +0,0 @@
// composables/useInfiniteScroll.ts
import { ref, onMounted, onBeforeUnmount } from "vue";
export default function useInfiniteScroll(
callback: () => Promise<void>,
elementId?: string
) {
const route = useRoute();
const isFetching = ref(false);
const infiniteScroll = ref<HTMLElement | Window | null>(null);
// Throttle function to limit scroll event frequency
const throttle = (func: (...args: any[]) => void, limit: number) => {
let lastFunc: ReturnType<typeof setTimeout>;
let lastRan: number;
return function (this: any, ...args: any[]) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
};
const checkScrollPosition = () => {
if (isFetching.value || !infiniteScroll.value) return;
let scrollPosition: number;
let threshold: number;
let clientHeight: number;
let scrollHeight: number;
if (infiniteScroll.value === window) {
scrollPosition = window.scrollY || window.pageYOffset;
clientHeight = document.documentElement.clientHeight;
scrollHeight = document.documentElement.scrollHeight;
} else {
const el = infiniteScroll.value as HTMLElement;
scrollPosition = el.scrollTop;
clientHeight = el.clientHeight;
scrollHeight = el.scrollHeight;
}
threshold = scrollHeight - 100;
const currentPosition = scrollPosition + clientHeight;
if (currentPosition >= threshold) {
isFetching.value = true;
callback().finally(() => {
isFetching.value = false;
});
}
};
// Throttled version of scroll handler
const throttledScrollHandler = throttle(checkScrollPosition, 200);
const handleTouchEnd = () => {
setTimeout(throttledScrollHandler, 100);
};
onMounted(() => {
console.info(route.name)
if (route.name == "hadithaSearch" || route.name == "hadithaLibrary") {
const targetElement = elementId
? document.getElementById(elementId)
: window;
if (!targetElement) {
console.warn(
`Element ${elementId || "window"} not found for infinite scroll`
);
return;
}
infiniteScroll.value = targetElement;
if (targetElement === window) {
window.addEventListener("scroll", throttledScrollHandler);
window.addEventListener("touchend", handleTouchEnd);
} else {
targetElement.addEventListener("scroll", throttledScrollHandler);
targetElement.addEventListener("touchend", handleTouchEnd);
}
}
});
onBeforeUnmount(() => {
if (route.name == "hadithaSearch" || route.name == "hadithaLibrary") {
if (!infiniteScroll.value) return;
if (infiniteScroll.value === window) {
window.removeEventListener("scroll", throttledScrollHandler);
window.removeEventListener("touchend", handleTouchEnd);
} else {
(infiniteScroll.value as HTMLElement).removeEventListener(
"scroll",
throttledScrollHandler
);
(infiniteScroll.value as HTMLElement).removeEventListener(
"touchend",
handleTouchEnd
);
}
}
});
return { isFetching };
}

View File

@ -1,46 +0,0 @@
// composables/useInfiniteScrollObserver.ts
import { onBeforeUnmount, onMounted, ref } from "vue";
export default function useInfiniteScrollObserver(callback) {
const observer = ref<IntersectionObserver | null>(null);
const isFetching = ref(false);
const infiniteScroll = ref<HTMLElement | null>(null);
console.info("useInfiniteScrollObserver");
const initObserver = () => {
console.info("useInfiniteScrollObserver");
observer.value = new IntersectionObserver(
(entries) => {
console.info("useInfiniteScrollObserver");
if (entries[0].isIntersecting && !isFetching.value) {
isFetching.value = true;
callback().finally(() => {
isFetching.value = false;
});
}
},
{
rootMargin: "200px", // Load when 200px away from viewport
threshold: 0.1,
}
);
if (infiniteScroll.value) {
observer.value.observe(infiniteScroll.value);
}
};
onMounted(() => {
initObserver();
});
onBeforeUnmount(() => {
if (observer.value && infiniteScroll.value) {
observer.value.unobserve(infiniteScroll.value);
}
});
return { isFetching, infiniteScroll };
}

View File

@ -2,16 +2,13 @@ FROM node:22
WORKDIR /app
COPY . .
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build-haditha
RUN npm install -g pm2
RUN pm2 start .output/server/index.mjs --name "nuxt-app"
RUN pm2 save
RUN pm2 startup
EXPOSE 3000
CMD ["pm2-runtime", ".output/server/index.mjs"]
CMD ["node", ".output/server/index.mjs"]

View File

@ -71,7 +71,7 @@ export default defineNuxtConfig({
// "vuejs-paginate",
],
devtools: {
enabled: true,
enabled: process.env.NODE_ENV === "development",
vscode: {
reuseExistingServer: true,
},
@ -80,7 +80,7 @@ export default defineNuxtConfig({
features: {
inlineStyles: false,
},
debug: true,
debug: false,
// Modules and plugins
modules: [
"@pinia/nuxt",
@ -93,10 +93,9 @@ export default defineNuxtConfig({
"@nuxtjs/color-mode",
"@nuxt/test-utils/module",
// 'nuxt-delay-hydration',
"@nuxt/image",
// "@nuxtjs/supabase",
// "@nuxt/icon",
"@nuxt/image",
"nuxt-auth-utils"
],
icon: {
// iconifyApiEndpoint: "iconifyApi",
@ -357,4 +356,4 @@ function customStyleLoader() {
)}_ui/assets/${buildName}/scss/${buildName}.css`;
return mainStyle;
}
}

265
package-lock.json generated
View File

@ -38,7 +38,6 @@
"mitt": "^3.0.1",
"npm": "^11.1.0",
"nuxt": "^3.15.4",
"nuxt-auth-utils": "^0.5.20",
"nuxt-echarts": "^0.2.3",
"pinia-plugin-persistedstate": "^4.1.1",
"qrcode": "^1.5.4",
@ -87,31 +86,6 @@
"vue-tsc": "^2.1.6"
}
},
"node_modules/@adonisjs/hash": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/@adonisjs/hash/-/hash-9.0.5.tgz",
"integrity": "sha512-oY8PafBrdGsr5UY8cAzzxPCtehZDW7KsPcI47dZpjydOdL/PQrT4liX+cGujL6mSbi3JEgQLBgBs/+SlPFvCrg==",
"license": "MIT",
"dependencies": {
"@phc/format": "^1.0.0",
"@poppinss/utils": "^6.8.3"
},
"engines": {
"node": ">=20.6.0"
},
"peerDependencies": {
"argon2": "^0.31.2 || ^0.41.0",
"bcrypt": "^5.1.1"
},
"peerDependenciesMeta": {
"argon2": {
"optional": true
},
"bcrypt": {
"optional": true
}
}
},
"node_modules/@alloc/quick-lru": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
@ -2140,15 +2114,6 @@
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lukeed/ms": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz",
"integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
@ -4487,15 +4452,6 @@
"node": ">=0.10"
}
},
"node_modules/@phc/format": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz",
"integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/@pinia/nuxt": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.5.5.tgz",
@ -4534,60 +4490,6 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@poppinss/exception": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.1.tgz",
"integrity": "sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/@poppinss/object-builder": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@poppinss/object-builder/-/object-builder-1.1.0.tgz",
"integrity": "sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==",
"license": "MIT",
"engines": {
"node": ">=20.6.0"
}
},
"node_modules/@poppinss/string": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@poppinss/string/-/string-1.3.0.tgz",
"integrity": "sha512-8BMX3y6Dr3W8EtF8CbL0uRXxm7Ha48fHVPCfOp667Uh6J7C+d0DzcoBzzNnofnvwdzVMKy0DNZ4KmMioEBj2wQ==",
"license": "MIT",
"dependencies": {
"@lukeed/ms": "^2.0.2",
"@types/bytes": "^3.1.5",
"@types/pluralize": "^0.0.33",
"bytes": "^3.1.2",
"case-anything": "^3.1.2",
"pluralize": "^8.0.0",
"slugify": "^1.6.6",
"truncatise": "^0.0.8"
},
"engines": {
"node": ">=20.6.0"
}
},
"node_modules/@poppinss/utils": {
"version": "6.9.3",
"resolved": "https://registry.npmjs.org/@poppinss/utils/-/utils-6.9.3.tgz",
"integrity": "sha512-K69WMVtmGcl0zJii9Zm5iav5VmxD3hw1JtN5cGqhTMr7UMSLSjeZPuETwZgjKqw86Dd1YcrWLU0+cVCTkemQJg==",
"license": "MIT",
"dependencies": {
"@poppinss/exception": "^1.2.1",
"@poppinss/object-builder": "^1.1.0",
"@poppinss/string": "^1.3.0",
"flattie": "^1.1.1",
"safe-stable-stringify": "^2.5.0",
"secure-json-parse": "^4.0.0"
},
"engines": {
"node": ">=18.16.0"
}
},
"node_modules/@redocly/ajv": {
"version": "8.11.2",
"resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz",
@ -5551,12 +5453,6 @@
"@popperjs/core": "^2.9.2"
}
},
"node_modules/@types/bytes": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.5.tgz",
"integrity": "sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==",
"license": "MIT"
},
"node_modules/@types/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
@ -5641,12 +5537,6 @@
"integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==",
"license": "MIT"
},
"node_modules/@types/pluralize": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/@types/pluralize/-/pluralize-0.0.33.tgz",
"integrity": "sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==",
"license": "MIT"
},
"node_modules/@types/resolve": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
@ -7608,15 +7498,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/c12": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz",
@ -7753,18 +7634,6 @@
],
"license": "CC-BY-4.0"
},
"node_modules/case-anything": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/case-anything/-/case-anything-3.1.2.tgz",
"integrity": "sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/chai": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz",
@ -9996,15 +9865,6 @@
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
"license": "ISC"
},
"node_modules/flattie": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz",
"integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/floating-vue": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/floating-vue/-/floating-vue-5.2.2.tgz",
@ -11370,15 +11230,6 @@
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/jose": {
"version": "5.10.0",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz",
"integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
@ -15638,51 +15489,6 @@
}
}
},
"node_modules/nuxt-auth-utils": {
"version": "0.5.20",
"resolved": "https://registry.npmjs.org/nuxt-auth-utils/-/nuxt-auth-utils-0.5.20.tgz",
"integrity": "sha512-hoXopfYeK4Cdu17WxxDWYc66EH7ZYG8JUodPxxef9vjfXOXqz3s1gxi/JWsiqkwN6s7K1RpKEESZGg1EopCgAA==",
"license": "MIT",
"dependencies": {
"@adonisjs/hash": "^9.0.5",
"@nuxt/kit": "^3.15.4",
"defu": "^6.1.4",
"h3": "^1.14.0",
"hookable": "^5.5.3",
"jose": "^5.9.6",
"ofetch": "^1.4.1",
"openid-client": "^6.1.7",
"pathe": "^2.0.2",
"scule": "^1.3.0",
"uncrypto": "^0.1.3"
},
"peerDependencies": {
"@atproto/api": "^0.13.15",
"@atproto/oauth-client-node": "^0.2.0",
"@simplewebauthn/browser": "^11.0.0",
"@simplewebauthn/server": "^11.0.0"
},
"peerDependenciesMeta": {
"@atproto/api": {
"optional": true
},
"@atproto/oauth-client-node": {
"optional": true
},
"@simplewebauthn/browser": {
"optional": true
},
"@simplewebauthn/server": {
"optional": true
}
}
},
"node_modules/nuxt-auth-utils/node_modules/pathe": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT"
},
"node_modules/nuxt-echarts": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/nuxt-echarts/-/nuxt-echarts-0.2.4.tgz",
@ -15929,15 +15735,6 @@
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT"
},
"node_modules/oauth4webapi": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.1.tgz",
"integrity": "sha512-txg/jZQwcbaF7PMJgY7aoxc9QuCxHVFMiEkDIJ60DwDz3PbtXPQnrzo+3X4IRYGChIwWLabRBRpf1k9hO9+xrQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@ -16110,28 +15907,6 @@
"node": ">=12"
}
},
"node_modules/openid-client": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/openid-client/-/openid-client-6.5.0.tgz",
"integrity": "sha512-fAfYaTnOYE2kQCqEJGX9KDObW2aw7IQy4jWpU/+3D3WoCFLbix5Hg6qIPQ6Js9r7f8jDUmsnnguRNCSw4wU/IQ==",
"license": "MIT",
"dependencies": {
"jose": "^6.0.10",
"oauth4webapi": "^3.5.1"
},
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/openid-client/node_modules/jose": {
"version": "6.0.11",
"resolved": "https://registry.npmjs.org/jose/-/jose-6.0.11.tgz",
"integrity": "sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/option": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz",
@ -18276,15 +18051,6 @@
],
"license": "MIT"
},
"node_modules/safe-stable-stringify": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
@ -18704,22 +18470,6 @@
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
"license": "MIT"
},
"node_modules/secure-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz",
"integrity": "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
@ -19063,15 +18813,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/slugify": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
"license": "MIT",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/smob": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz",
@ -19749,12 +19490,6 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/truncatise": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz",
"integrity": "sha512-cXzueh9pzBCsLzhToB4X4gZCb3KYkrsAcBAX97JnazE74HOl3cpBJYEV7nabHeG/6/WXCU5Yujlde/WPBUwnsg==",
"license": "MIT"
},
"node_modules/ts-api-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",

View File

@ -46,7 +46,6 @@
"mitt": "^3.0.1",
"npm": "^11.1.0",
"nuxt": "^3.15.4",
"nuxt-auth-utils": "^0.5.20",
"nuxt-echarts": "^0.2.3",
"pinia-plugin-persistedstate": "^4.1.1",
"qrcode": "^1.5.4",

View File

@ -1,22 +1,25 @@
import { useAuthStore } from "~/stores/authStore";
import { useStorage } from "@vueuse/core";
// let lsToken = useStorage("token", "GuestAccess");
// if (lsToken == null || lsToken == "" || lsToken == undefined)
// lsToken = "GuestAccess";
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const id_token = useCookie("id_token");
const token = id_token.value ?? "GuestAccess";
const baseUrl =
config.public.NUXT_PUBLIC_BASE_URL + config.public.NUXT_PUBLIC_API_NAME;
// const { session } = useUserSession();
// const authStore = useAuthStore();
let token = useStorage("id_token", "GuestAccess").value;
const api = $fetch.create({
// baseURL: baseUrl,
onRequest({ request, options, error }) {
options.baseURL = baseUrl + options.baseURL;
// options.baseURL = options.baseURL;
options.baseURL =
config.public.NUXT_PUBLIC_BASE_URL +
config.public.NUXT_PUBLIC_API_NAME +
options.baseURL;
if (token) {
const headers = (options.headers ||= {});
if (Array.isArray(headers)) {
headers.push(["Authorization", token]);
} else if (headers instanceof Headers) {

View File

@ -6,10 +6,12 @@ export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig();
const api = $fetch.create({
baseURL: config.public.NUXT_PUBLIC_BASE_URL +
config.public.NUXT_PUBLIC_API_NAME,
onRequest({ request, options, error }) {
options.baseURL =
config.public.NUXT_PUBLIC_BASE_URL +
config.public.NUXT_PUBLIC_API_NAME +
options.baseURL;
if (token) {
const headers = (options.headers ||= {});
if (Array.isArray(headers)) {
@ -36,8 +38,7 @@ export default defineNuxtPlugin((nuxtApp) => {
// Add custom methods for GET, POST, and DELETE
const http = {
getRequest: (url: string, options = {}) =>
api(url, { method: "GET", ...options }),
getRequest: (url: string, options = {}) => api(url, { method: "GET", ...options }),
postRequest: (url: string, body: any, options = {}) =>
api(url, { method: "POST", body, ...options }),
deleteRequest: (url: string, options = {}) =>

View File

@ -1,384 +1,380 @@
export default defineNuxtPlugin(() => {
console.info("persina number plugin");
});
const oneDigit = [
"صفر",
"یک",
"دو",
"سه",
"چهار",
"پنج",
"شش",
"هفت",
"هشت",
"نه",
];
const twoDigits = {
10: "ده",
11: "یازده",
12: "دوازده",
13: "سیزده",
14: "چهارده",
15: "پانزده",
16: "شانزده",
17: "هفده",
18: "هجده",
19: "نوزده",
20: "بیست",
30: "سی",
40: "چهل",
50: "پنجاه",
60: "شصت",
70: "هفتاد",
80: "هشتاد",
90: "نود",
};
const threeDigits = {
100: "صد",
200: "دویست",
300: "سیصد",
400: "چهارصد",
500: "پانصد",
600: "شش صد",
700: "هفت صد",
800: "هشت صد",
900: "نه صد",
};
// const oneDigit = [
// "صفر",
// "یک",
// "دو",
// "سه",
// "چهار",
// "پنج",
// "شش",
// "هفت",
// "هشت",
// "نه",
// ];
// const twoDigits = {
// 10: "ده",
// 11: "یازده",
// 12: "دوازده",
// 13: "سیزده",
// 14: "چهارده",
// 15: "پانزده",
// 16: "شانزده",
// 17: "هفده",
// 18: "هجده",
// 19: "نوزده",
// 20: "بیست",
// 30: "سی",
// 40: "چهل",
// 50: "پنجاه",
// 60: "شصت",
// 70: "هفتاد",
// 80: "هشتاد",
// 90: "نود",
// };
// const threeDigits = {
// 100: "صد",
// 200: "دویست",
// 300: "سیصد",
// 400: "چهارصد",
// 500: "پانصد",
// 600: "شش صد",
// 700: "هفت صد",
// 800: "هشت صد",
// 900: "نه صد",
// };
const types = ["تلیارد", "میلیارد", "میلیون", "هزار", ""];
const decimalTypes = ["دهم", "صدم", "هزارم", "ده هزارم"];
let numbers = [];
let decimals = [];
// const types = ["تلیارد", "میلیارد", "میلیون", "هزار", ""];
// const decimalTypes = ["دهم", "صدم", "هزارم", "ده هزارم"];
// let numbers = [];
// let decimals = [];
//Convert Number To Words
const convert = (number) => {
let negative = "";
let decNumber = "";
let decimal = "";
let percent = "";
// //Convert Number To Words
// const convert = (number) => {
// let negative = "";
// let decNumber = "";
// let decimal = "";
// let percent = "";
if (isPercent(number)) {
number = number.replace("%", "");
percent = " درصد";
}
// if (isPercent(number)) {
// number = number.replace("%", "");
// percent = " درصد";
// }
number = getString(number);
if (number == "") return "";
sliceNumber(number);
if (isNegative(number)) negative = "منفی ";
number = number.replace("-", "");
// number = getString(number);
// if (number == "") return "";
// sliceNumber(number);
// if (isNegative(number)) negative = "منفی ";
// number = number.replace("-", "");
if (isDecimal(number)) {
let index = number.indexOf(".");
let decNumberStr = "";
// if (isDecimal(number)) {
// let index = number.indexOf(".");
// let decNumberStr = "";
decNumber = number.substr(index + 1, number.length);
number = number.substr(0, index);
decNumberStr = parseInt(decNumber).toString();
// decNumber = number.substr(index + 1, number.length);
// number = number.substr(0, index);
// decNumberStr = parseInt(decNumber).toString();
if (decNumberStr.length === 1 && decNumberStr != "0") {
decimal += oneDigit[decNumberStr] + " ";
decimal += decimalTypes[decNumber.length - 1];
} else {
decimal = calculateDigits(decimals);
decimal += " " + decimalTypes[decNumber.length - 1];
}
}
// if (decNumberStr.length === 1 && decNumberStr != "0") {
// decimal += oneDigit[decNumberStr] + " ";
// decimal += decimalTypes[decNumber.length - 1];
// } else {
// decimal = calculateDigits(decimals);
// decimal += " " + decimalTypes[decNumber.length - 1];
// }
// }
if (number.length === 1) {
if (!decimal) {
return negative + oneDigit[number] + percent;
}
// if (number.length === 1) {
// if (!decimal) {
// return negative + oneDigit[number] + percent;
// }
if (number == "0") {
return negative + decimal + percent;
}
// if (number == "0") {
// return negative + decimal + percent;
// }
return negative + oneDigit[number] + " ممیز " + decimal + percent;
}
// return negative + oneDigit[number] + " ممیز " + decimal + percent;
// }
if (!decimal) {
return negative + calculateDigits(numbers) + percent;
}
// if (!decimal) {
// return negative + calculateDigits(numbers) + percent;
// }
return negative + calculateDigits(numbers) + " ممیز " + decimal + percent;
};
// return negative + calculateDigits(numbers) + " ممیز " + decimal + percent;
// };
//split number 3 by 3 with a separator (123456789.3025=>123,456,789.3,025) Do Not Give It Persian Numbers
const sliceNumber = (number, separator = ",") => {
let percent = "";
let neg = "";
let dNum = "";
let n = "";
let d = "";
// //split number 3 by 3 with a separator (123456789.3025=>123,456,789.3,025) Do Not Give It Persian Numbers
// const sliceNumber = (number, separator = ",") => {
// let percent = "";
// let neg = "";
// let dNum = "";
// let n = "";
// let d = "";
if (isPercent(number)) {
number = number.replace("%", "");
percent = "%";
}
// if (isPercent(number)) {
// number = number.replace("%", "");
// percent = "%";
// }
number = getString(number);
// number = getString(number);
if (number == "") return "";
if (isNegative(number)) neg = "-";
// if (number == "") return "";
// if (isNegative(number)) neg = "-";
number = number.replace("-", "");
// number = number.replace("-", "");
if (isDecimal(number)) {
let index = number.indexOf(".");
dNum = number.substr(index + 1, number.length);
number = number.substr(0, index);
}
// if (isDecimal(number)) {
// let index = number.indexOf(".");
// dNum = number.substr(index + 1, number.length);
// number = number.substr(0, index);
// }
n = putSeparator(number, separator);
numbers = n.split(separator);
// n = putSeparator(number, separator);
// numbers = n.split(separator);
if (!dNum) return neg + n + percent;
// if (!dNum) return neg + n + percent;
d = putSeparator(dNum, separator);
decimals = d.split(separator);
// d = putSeparator(dNum, separator);
// decimals = d.split(separator);
return neg + n + "." + d + percent;
};
// return neg + n + "." + d + percent;
// };
//Puts a separator between the chunks of the given numString.
const putSeparator = (numString, separator = ",") => {
if (typeof numString !== "string") return "";
if (numString.length < 4) return numString;
// //Puts a separator between the chunks of the given numString.
// const putSeparator = (numString, separator = ",") => {
// if (typeof numString !== "string") return "";
// if (numString.length < 4) return numString;
let result = "";
for (let i = numString.length - 1, counter = 0; i >= 0; i--) {
if (counter == 3) {
result += separator;
counter = 0;
}
result += numString[i];
counter++;
}
// let result = "";
// for (let i = numString.length - 1, counter = 0; i >= 0; i--) {
// if (counter == 3) {
// result += separator;
// counter = 0;
// }
// result += numString[i];
// counter++;
// }
result = result.split("").reverse().join("");
return result;
};
// result = result.split("").reverse().join("");
// return result;
// };
//Processing on Digits of A Number
const calculateDigits = (arrNum) => {
let result = "";
for (let i = 0; i < arrNum.length; i++) {
let parsedNum = parseInt(arrNum[i]);
let number = parsedNum;
let sadgan = Math.floor(number / 100) * 100;
number = number % 100;
let dahgan = Math.floor(number / 10) * 10;
let yekan = number % 10;
result += i !== 0 && parsedNum ? " و " : "";
// //Processing on Digits of A Number
// const calculateDigits = (arrNum) => {
// let result = "";
// for (let i = 0; i < arrNum.length; i++) {
// let parsedNum = parseInt(arrNum[i]);
// let number = parsedNum;
// let sadgan = Math.floor(number / 100) * 100;
// number = number % 100;
// let dahgan = Math.floor(number / 10) * 10;
// let yekan = number % 10;
// result += i !== 0 && parsedNum ? " و " : "";
result +=
getPersian(sadgan, dahgan, yekan, i, arrNum) + " " + getType(i, arrNum);
}
// result +=
// getPersian(sadgan, dahgan, yekan, i, arrNum) + " " + getType(i, arrNum);
// }
return result.trim();
};
// return result.trim();
// };
//Main Process That Turn a Number Into a String(122=>100+20+2)
const getPersian = (sadgan, dahgan, yekan, index, numbers) => {
let flag = false;
let result = "";
let dahganPlusYekan = dahgan + yekan;
// //Main Process That Turn a Number Into a String(122=>100+20+2)
// const getPersian = (sadgan, dahgan, yekan, index, numbers) => {
// let flag = false;
// let result = "";
// let dahganPlusYekan = dahgan + yekan;
if (threeDigits[sadgan]) {
result +=
yekan > 0 || dahgan > 0
? threeDigits[sadgan] + " و "
: threeDigits[sadgan];
}
// if (threeDigits[sadgan]) {
// result +=
// yekan > 0 || dahgan > 0
// ? threeDigits[sadgan] + " و "
// : threeDigits[sadgan];
// }
if (twoDigits[dahganPlusYekan]) {
result += twoDigits[dahganPlusYekan] + " ";
return result;
}
// if (twoDigits[dahganPlusYekan]) {
// result += twoDigits[dahganPlusYekan] + " ";
// return result;
// }
if (twoDigits[dahgan]) {
result += twoDigits[dahgan] + " و ";
}
// if (twoDigits[dahgan]) {
// result += twoDigits[dahgan] + " و ";
// }
if (
numbers.length === 2 &&
index === 0 &&
yekan === 1 &&
dahgan === 0 &&
sadgan === 0
) {
return result;
}
// if (
// numbers.length === 2 &&
// index === 0 &&
// yekan === 1 &&
// dahgan === 0 &&
// sadgan === 0
// ) {
// return result;
// }
if (
numbers.length > 2 &&
index === numbers.length - 2 &&
yekan === 1 &&
dahgan === 0 &&
sadgan === 0
) {
return result;
}
// if (
// numbers.length > 2 &&
// index === numbers.length - 2 &&
// yekan === 1 &&
// dahgan === 0 &&
// sadgan === 0
// ) {
// return result;
// }
if (yekan > 0) result += oneDigit[yekan] + " ";
// if (yekan > 0) result += oneDigit[yekan] + " ";
return result;
};
// return result;
// };
//getting The Type Of Each Number (Billion, Million,...)
const getType = (i, numbers) => {
let parsedNum = parseInt(numbers[i]);
if (isNaN(parsedNum)) return "";
if (!parsedNum) return "";
let length = numbers.length - i;
let index = types.length - length;
return types[index];
};
// //getting The Type Of Each Number (Billion, Million,...)
// const getType = (i, numbers) => {
// let parsedNum = parseInt(numbers[i]);
// if (isNaN(parsedNum)) return "";
// if (!parsedNum) return "";
// let length = numbers.length - i;
// let index = types.length - length;
// return types[index];
// };
//Calculate if number:String is Negative Or Not
const isNegative = (number) => {
number = getString(number);
if (!number) return false;
if (number[0] != "-") return false;
number = number.replace("-", "");
return number != "0";
};
// //Calculate if number:String is Negative Or Not
// const isNegative = (number) => {
// number = getString(number);
// if (!number) return false;
// if (number[0] != "-") return false;
// number = number.replace("-", "");
// return number != "0";
// };
//Calculate if number:String has '%' as Percent
const isPercent = (string) => {
if (typeof string !== "string") return false;
let index = string.indexOf("%");
let lIndex = string.lastIndexOf("%");
if (index != lIndex) return false;
return index > 0;
};
// //Calculate if number:String has '%' as Percent
// const isPercent = (string) => {
// if (typeof string !== "string") return false;
// let index = string.indexOf("%");
// let lIndex = string.lastIndexOf("%");
// if (index != lIndex) return false;
// return index > 0;
// };
//is number:String:Number is a Valid Number? if type is Number turn it to String And Return it
const getString = (number) => {
if (number === undefined) return "";
if (number === null) return "";
if (isNaN(number)) return "";
if (typeof number === "number") return number.toString();
return number.trim();
};
// //is number:String:Number is a Valid Number? if type is Number turn it to String And Return it
// const getString = (number) => {
// if (number === undefined) return "";
// if (number === null) return "";
// if (isNaN(number)) return "";
// if (typeof number === "number") return number.toString();
// return number.trim();
// };
//Calculate if number:String has Decimal Point Or Not
const isDecimal = (number) => {
number = getString(number);
if (number == "") return false;
let index = number.indexOf(".");
let lIndex = number.lastIndexOf(".");
if (index != lIndex) return false;
return index > 0;
};
//Convert English Numbers To Persian Numbers
const convertEnToPe = (number) => {
if (number == null || number == undefined) return "";
if (typeof number == "number") number = number.toString();
let res = "";
for (let i = 0; i < number.length; i++) {
switch (number[i]) {
case "\u0030":
res += "\u06F0";
break;
case "\u0031":
res += "\u06F1";
break;
case "\u0032":
res += "\u06F2";
break;
case "\u0033":
res += "\u06F3";
break;
case "\u0034":
res += "\u06F4";
break;
case "\u0035":
res += "\u06F5";
break;
case "\u0036":
res += "\u06F6";
break;
case "\u0037":
res += "\u06F7";
break;
case "\u0038":
res += "\u06F8";
break;
case "\u0039":
res += "\u06F9";
break;
default:
res += number[i];
}
}
return res;
};
//Convert Persian Numbers To English Numbers
const convertPeToEn = (number) => {
if (number == null || number == undefined) return "";
let res = "";
for (let i = 0; i < number.length; i++) {
switch (number[i]) {
case "\u06F0":
res += "\u0030";
break;
case "\u06F1":
res += "\u0031";
break;
case "\u06F2":
res += "\u0032";
break;
case "\u06F3":
res += "\u0033";
break;
case "\u06F4":
res += "\u0034";
break;
case "\u06F5":
res += "\u0035";
break;
case "\u06F6":
res += "\u0036";
break;
case "\u06F7":
res += "\u0037";
break;
case "\u06F8":
res += "\u0038";
break;
case "\u06F9":
res += "\u0039";
break;
default:
res += number[i];
}
}
return res;
};
// //Calculate if number:String has Decimal Point Or Not
// const isDecimal = (number) => {
// number = getString(number);
// if (number == "") return false;
// let index = number.indexOf(".");
// let lIndex = number.lastIndexOf(".");
// if (index != lIndex) return false;
// return index > 0;
// };
// //Convert English Numbers To Persian Numbers
// const convertEnToPe = (number) => {
// if (number == null || number == undefined) return "";
// if (typeof number == "number") number = number.toString();
// let res = "";
// for (let i = 0; i < number.length; i++) {
// switch (number[i]) {
// case "\u0030":
// res += "\u06F0";
// break;
// case "\u0031":
// res += "\u06F1";
// break;
// case "\u0032":
// res += "\u06F2";
// break;
// case "\u0033":
// res += "\u06F3";
// break;
// case "\u0034":
// res += "\u06F4";
// break;
// case "\u0035":
// res += "\u06F5";
// break;
// case "\u0036":
// res += "\u06F6";
// break;
// case "\u0037":
// res += "\u06F7";
// break;
// case "\u0038":
// res += "\u06F8";
// break;
// case "\u0039":
// res += "\u06F9";
// break;
// default:
// res += number[i];
// }
// }
// return res;
// };
// //Convert Persian Numbers To English Numbers
// const convertPeToEn = (number) => {
// if (number == null || number == undefined) return "";
// let res = "";
// for (let i = 0; i < number.length; i++) {
// switch (number[i]) {
// case "\u06F0":
// res += "\u0030";
// break;
// case "\u06F1":
// res += "\u0031";
// break;
// case "\u06F2":
// res += "\u0032";
// break;
// case "\u06F3":
// res += "\u0033";
// break;
// case "\u06F4":
// res += "\u0034";
// break;
// case "\u06F5":
// res += "\u0035";
// break;
// case "\u06F6":
// res += "\u0036";
// break;
// case "\u06F7":
// res += "\u0037";
// break;
// case "\u06F8":
// res += "\u0038";
// break;
// case "\u06F9":
// res += "\u0039";
// break;
// default:
// res += number[i];
// }
// }
// return res;
// };
const e2p = (s) => s.replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[d]);
const e2a = (s) => s.replace(/\d/g, (d) => "٠١٢٣٤٥٦٧٨٩"[d]);
// const e2p = (s) => s.replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[d]);
// const e2a = (s) => s.replace(/\d/g, (d) => "٠١٢٣٤٥٦٧٨٩"[d]);
const p2e = (s) => s.replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
const a2e = (s) => s.replace(/[٠-٩]/g, (d) => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
// const p2e = (s) => s.replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d));
// const a2e = (s) => s.replace(/[٠-٩]/g, (d) => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
const p2a = (s) =>
s.replace(/[۰-۹]/g, (d) => "٠١٢٣٤٥٦٧٨٩"["۰۱۲۳۴۵۶۷۸۹".indexOf(d)]);
const a2p = (s) =>
s.replace(/[٠-٩]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"["٠١٢٣٤٥٦٧٨٩".indexOf(d)]);
// const p2a = (s) =>
// s.replace(/[۰-۹]/g, (d) => "٠١٢٣٤٥٦٧٨٩"["۰۱۲۳۴۵۶۷۸۹".indexOf(d)]);
// const a2p = (s) =>
// s.replace(/[٠-٩]/g, (d) => "۰۱۲۳۴۵۶۷۸۹"["٠١٢٣٤٥٦٧٨٩".indexOf(d)]);
// export {
// convert,
// sliceNumber,
// convertEnToPe,
// convertPeToEn,
// e2p,
// e2a,
// p2e,
// a2e,
// p2a,
// a2p,
// };
export {
convert,
sliceNumber,
convertEnToPe,
convertPeToEn,
e2p,
e2a,
p2e,
a2e,
p2a,
a2p,
};

9
server/api/login.ts Normal file
View File

@ -0,0 +1,9 @@
// server/api/login.ts
export default defineEventHandler(async (event) => {
// const body = await readBody(event);
// const response = await $fetch("https://api.example.com/login", {
// method: "POST",
// body,
// });
// return response;
});

View File

@ -0,0 +1,5 @@
// server/api/users/[id].ts
export default defineEventHandler((event) => {
// const id = event.context.params?.id;
// return { userId: id };
});

View File

@ -0,0 +1,7 @@
// server/api/data.ts
export default defineEventHandler(async (event) => {
// const data = await $fetch("https://api.example.com/data", {
// headers: { Authorization: "Bearer my-secret-token" },
// });
// return data;
});

View File

@ -0,0 +1,7 @@
// server/api/data.ts
export default defineEventHandler(async (event) => {
// const data = await $fetch("https://api.example.com/data", {
// headers: { Authorization: "Bearer my-secret-token" },
// });
// return data;
});

View File

@ -0,0 +1,7 @@
// server/api/data.ts
export default defineEventHandler(async (event) => {
// const data = await $fetch("https://api.example.com/data", {
// headers: { Authorization: "Bearer my-secret-token" },
// });
// return data;
});

30
server/api/upload.post.ts Normal file
View File

@ -0,0 +1,30 @@
import { defineEventHandler, readMultipartFormData } from "h3";
import { promises as fs } from "fs";
import sharp from "sharp";
export default defineEventHandler(async (event) => {
const files = await readMultipartFormData(event);
if (!files || files.length === 0) {
return { error: "No files uploaded" };
}
const uploadedFile = files[0];
const fileName = `cropped-${Date.now()}.png`;
const filePath = `./public/uploads/${fileName}`;
// Save the cropped image
await fs.writeFile(filePath, uploadedFile.data);
// Optionally resize the image
const resizedFilePath = `./public/uploads/resized-${fileName}`;
await sharp(uploadedFile.data)
.resize(300, 300) // Adjust dimensions as needed
.toFile(resizedFilePath);
return {
message: "File uploaded successfully",
originalFile: `/uploads/${fileName}`,
resizedFile: `/uploads/resized-${fileName}`,
};
});

70
server/api/users.get.ts Normal file
View File

@ -0,0 +1,70 @@
const users = [
{
user_id: "583c3ac3f38e84297c002546",
email: "test@test.com",
name: "test@test.com",
given_name: "Hello",
family_name: "Test",
nickname: "test",
last_ip: "94.121.163.63",
logins_count: 15,
created_at: "2016-11-28T14:10:11.338Z",
updated_at: "2016-12-02T01:17:29.310Z",
last_login: "2016-12-02T01:17:29.310Z",
email_verified: true,
},
{
user_id: "583c5484cb79a5fe593425a9",
email: "test1@test.com",
name: "test1@test.com",
given_name: "Hello1",
family_name: "Test1",
nickname: "test1",
last_ip: "94.121.168.53",
logins_count: 1,
created_at: "2016-11-28T16:00:04.209Z",
updated_at: "2016-11-28T16:00:47.203Z",
last_login: "2016-11-28T16:00:47.203Z",
email_verified: true,
},
{
user_id: "583c57672c7686377d2f66c9",
email: "aaa@aaa.com",
name: "aaa@aaa.com",
given_name: "John",
family_name: "Dough",
nickname: "aaa",
last_ip: "94.121.168.53",
logins_count: 2,
created_at: "2016-11-28T16:12:23.777Z",
updated_at: "2016-11-28T16:12:52.353Z",
last_login: "2016-11-28T16:12:52.353Z",
email_verified: true,
},
{
user_id: "5840b954da0529cd293d76fe",
email: "a@a.com",
name: "a@a.com",
given_name: "Jane",
family_name: "Dough",
nickname: "a",
last_ip: "94.121.163.63",
logins_count: 3,
created_at: "2016-12-01T23:59:16.473Z",
updated_at: "2016-12-01T23:59:53.474Z",
last_login: "2016-12-01T23:59:53.474Z",
email_verified: true,
},
{
user_id: "584a9d13e808bcf75f05f580",
email: "test9999@test.com",
given_name: "Dummy",
family_name: "User",
created_at: "2016-12-09T12:01:23.787Z",
updated_at: "2016-12-09T12:01:23.787Z",
email_verified: false,
},
];
export default defineEventHandler((event) => {
return users;
});

@ -1 +1 @@
Subproject commit e1047621e2b74024de94331d7a1f424e83214440
Subproject commit c3aa6605ff449226a04817f0fb29a4b0f77654bc

@ -1 +1 @@
Subproject commit f4dbda3abbe6ca4b18fe3e2f452a3684ca13c9ad
Subproject commit 117dc3e4faed749ac4dbfbf0a41899fe22282c84

@ -1 +1 @@
Subproject commit 1c5b1d47a1a07ba1a567e9f11fd60d5408fde883
Subproject commit dce0b4fe6cf7158ac7cb841564e78de33e23d0a3

139
yarn.lock
View File

@ -2,14 +2,6 @@
# yarn lockfile v1
"@adonisjs/hash@^9.0.5":
version "9.0.5"
resolved "https://registry.npmjs.org/@adonisjs/hash/-/hash-9.0.5.tgz"
integrity sha512-oY8PafBrdGsr5UY8cAzzxPCtehZDW7KsPcI47dZpjydOdL/PQrT4liX+cGujL6mSbi3JEgQLBgBs/+SlPFvCrg==
dependencies:
"@phc/format" "^1.0.0"
"@poppinss/utils" "^6.8.3"
"@alloc/quick-lru@^5.2.0":
version "5.2.0"
resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
@ -894,11 +886,6 @@
dependencies:
"@lezer/common" "^1.0.0"
"@lukeed/ms@^2.0.2":
version "2.0.2"
resolved "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz"
integrity sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==
"@mapbox/node-pre-gyp@^1.0.11":
version "1.0.11"
resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz"
@ -1577,11 +1564,6 @@
"@parcel/watcher-win32-ia32" "2.5.0"
"@parcel/watcher-win32-x64" "2.5.0"
"@phc/format@^1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz"
integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==
"@pinia/nuxt@^0.5.4", "@pinia/nuxt@>=0.5.0":
version "0.5.5"
resolved "https://registry.npmjs.org/@pinia/nuxt/-/nuxt-0.5.5.tgz"
@ -1605,42 +1587,6 @@
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
"@poppinss/exception@^1.2.1":
version "1.2.1"
resolved "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.1.tgz"
integrity sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==
"@poppinss/object-builder@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@poppinss/object-builder/-/object-builder-1.1.0.tgz"
integrity sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==
"@poppinss/string@^1.3.0":
version "1.3.0"
resolved "https://registry.npmjs.org/@poppinss/string/-/string-1.3.0.tgz"
integrity sha512-8BMX3y6Dr3W8EtF8CbL0uRXxm7Ha48fHVPCfOp667Uh6J7C+d0DzcoBzzNnofnvwdzVMKy0DNZ4KmMioEBj2wQ==
dependencies:
"@lukeed/ms" "^2.0.2"
"@types/bytes" "^3.1.5"
"@types/pluralize" "^0.0.33"
bytes "^3.1.2"
case-anything "^3.1.2"
pluralize "^8.0.0"
slugify "^1.6.6"
truncatise "^0.0.8"
"@poppinss/utils@^6.8.3":
version "6.9.3"
resolved "https://registry.npmjs.org/@poppinss/utils/-/utils-6.9.3.tgz"
integrity sha512-K69WMVtmGcl0zJii9Zm5iav5VmxD3hw1JtN5cGqhTMr7UMSLSjeZPuETwZgjKqw86Dd1YcrWLU0+cVCTkemQJg==
dependencies:
"@poppinss/exception" "^1.2.1"
"@poppinss/object-builder" "^1.1.0"
"@poppinss/string" "^1.3.0"
flattie "^1.1.1"
safe-stable-stringify "^2.5.0"
secure-json-parse "^4.0.0"
"@redocly/ajv@^8.11.2":
version "8.11.2"
resolved "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz"
@ -1975,11 +1921,6 @@
dependencies:
"@popperjs/core" "^2.9.2"
"@types/bytes@^3.1.5":
version "3.1.5"
resolved "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.5.tgz"
integrity sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==
"@types/cookie@^0.6.0":
version "0.6.0"
resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz"
@ -2042,11 +1983,6 @@
resolved "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz"
integrity sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==
"@types/pluralize@^0.0.33":
version "0.0.33"
resolved "https://registry.npmjs.org/@types/pluralize/-/pluralize-0.0.33.tgz"
integrity sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==
"@types/resolve@1.20.2":
version "1.20.2"
resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz"
@ -3156,11 +3092,6 @@ bundle-name@^4.1.0:
dependencies:
run-applescript "^7.0.0"
bytes@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
c12@^2.0.1, c12@2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz"
@ -3269,11 +3200,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001688:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz"
integrity sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==
case-anything@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/case-anything/-/case-anything-3.1.2.tgz"
integrity sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ==
chai@^5.1.2:
version "5.1.2"
resolved "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz"
@ -4798,11 +4724,6 @@ flatted@^3.2.9, flatted@^3.3.2:
resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz"
integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==
flattie@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz"
integrity sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==
floating-vue@^5.2.2:
version "5.2.2"
resolved "https://registry.npmjs.org/floating-vue/-/floating-vue-5.2.2.tgz"
@ -5712,16 +5633,6 @@ jiti@*, jiti@^2.1.2, jiti@^2.3.0, jiti@^2.4.0, jiti@^2.4.1, jiti@^2.4.2, jiti@>=
resolved "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz"
integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
jose@^5.9.6:
version "5.10.0"
resolved "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz"
integrity sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==
jose@^6.0.10:
version "6.0.11"
resolved "https://registry.npmjs.org/jose/-/jose-6.0.11.tgz"
integrity sha512-QxG7EaliDARm1O1S8BGakqncGT9s25bKL1WSf6/oa17Tkqwi8D2ZNglqCF+DsYF88/rV66Q/Q2mFAy697E1DUg==
jquery@^3.7.1:
version "3.7.1"
resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz"
@ -6932,23 +6843,6 @@ nth-check@^2.0.1:
dependencies:
boolbase "^1.0.0"
nuxt-auth-utils@^0.5.20:
version "0.5.20"
resolved "https://registry.npmjs.org/nuxt-auth-utils/-/nuxt-auth-utils-0.5.20.tgz"
integrity sha512-hoXopfYeK4Cdu17WxxDWYc66EH7ZYG8JUodPxxef9vjfXOXqz3s1gxi/JWsiqkwN6s7K1RpKEESZGg1EopCgAA==
dependencies:
"@adonisjs/hash" "^9.0.5"
"@nuxt/kit" "^3.15.4"
defu "^6.1.4"
h3 "^1.14.0"
hookable "^5.5.3"
jose "^5.9.6"
ofetch "^1.4.1"
openid-client "^6.1.7"
pathe "^2.0.2"
scule "^1.3.0"
uncrypto "^0.1.3"
nuxt-echarts@^0.2.3:
version "0.2.4"
resolved "https://registry.npmjs.org/nuxt-echarts/-/nuxt-echarts-0.2.4.tgz"
@ -7073,11 +6967,6 @@ nypm@^0.6.0:
pkg-types "^2.0.0"
tinyexec "^0.3.2"
oauth4webapi@^3.5.1:
version "3.5.1"
resolved "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-3.5.1.tgz"
integrity sha512-txg/jZQwcbaF7PMJgY7aoxc9QuCxHVFMiEkDIJ60DwDz3PbtXPQnrzo+3X4IRYGChIwWLabRBRpf1k9hO9+xrQ==
object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
@ -7174,14 +7063,6 @@ openapi-typescript@^7.4.2:
supports-color "^9.4.0"
yargs-parser "^21.1.1"
openid-client@^6.1.7:
version "6.5.0"
resolved "https://registry.npmjs.org/openid-client/-/openid-client-6.5.0.tgz"
integrity sha512-fAfYaTnOYE2kQCqEJGX9KDObW2aw7IQy4jWpU/+3D3WoCFLbix5Hg6qIPQ6Js9r7f8jDUmsnnguRNCSw4wU/IQ==
dependencies:
jose "^6.0.10"
oauth4webapi "^3.5.1"
option@~0.2.1:
version "0.2.4"
resolved "https://registry.npmjs.org/option/-/option-0.2.4.tgz"
@ -8294,11 +8175,6 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-stable-stringify@^2.5.0:
version "2.5.0"
resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz"
integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
@ -8363,11 +8239,6 @@ scule@^1.1.1, scule@^1.3.0:
resolved "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz"
integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==
secure-json-parse@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz"
integrity sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==
semver@^6.0.0:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
@ -8578,11 +8449,6 @@ slash@^5.1.0:
resolved "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz"
integrity sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==
slugify@^1.6.6:
version "1.6.6"
resolved "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz"
integrity sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==
smart-buffer@^4.2.0:
version "4.2.0"
@ -9134,11 +9000,6 @@ tr46@~0.0.3:
treeverse@^3.0.0:
version "3.0.0"
truncatise@^0.0.8:
version "0.0.8"
resolved "https://registry.npmjs.org/truncatise/-/truncatise-0.0.8.tgz"
integrity sha512-cXzueh9pzBCsLzhToB4X4gZCb3KYkrsAcBAX97JnazE74HOl3cpBJYEV7nabHeG/6/WXCU5Yujlde/WPBUwnsg==
ts-api-utils@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz"