mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-24 00:01:03 +08:00
feat: update environment variables, enhance login functionality with password hashing, and improve UI components for better user experience
This commit is contained in:
parent
26d3998a70
commit
98869d5fce
@ -12,8 +12,7 @@ POSTGRES_URL=
|
|||||||
|
|
||||||
GROQ_API_KEY=
|
GROQ_API_KEY=
|
||||||
|
|
||||||
NUXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
PASSWORD_HASH_SALT=""
|
||||||
NUXT_CLERK_SECRET_KEY=
|
|
||||||
|
|
||||||
# SCRAPING
|
# SCRAPING
|
||||||
POSTGRES_DB=""
|
POSTGRES_DB=""
|
||||||
|
@ -28,6 +28,10 @@ App Design: [Freeform](https://www.icloud.com/freeform/026AxB798cViZ9jJ2DkNsXUCQ
|
|||||||
- Ground.news
|
- Ground.news
|
||||||
- 台灣新聞
|
- 台灣新聞
|
||||||
- Threads
|
- Threads
|
||||||
|
- xfce's Desktop Interface
|
||||||
|
- juice website
|
||||||
|
- MacOS
|
||||||
|
- Windows XP style X - UI
|
||||||
|
|
||||||
## Stack:
|
## Stack:
|
||||||
|
|
||||||
|
18
bun.lock
18
bun.lock
@ -18,10 +18,12 @@
|
|||||||
"@uploadthing/nuxt": "^7.1.7",
|
"@uploadthing/nuxt": "^7.1.7",
|
||||||
"@vueuse/core": "^13.1.0",
|
"@vueuse/core": "^13.1.0",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
|
"argon2": "^0.43.0",
|
||||||
"bootstrap-icons": "^1.12.1",
|
"bootstrap-icons": "^1.12.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
"emoji-js": "^3.8.1",
|
||||||
"groq-sdk": "^0.21.0",
|
"groq-sdk": "^0.21.0",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
"html-to-json-parser": "^2.0.1",
|
"html-to-json-parser": "^2.0.1",
|
||||||
@ -460,6 +462,8 @@
|
|||||||
|
|
||||||
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
||||||
|
|
||||||
|
"@phc/format": ["@phc/format@1.0.0", "", {}, "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ=="],
|
||||||
|
|
||||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||||
|
|
||||||
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||||
@ -812,6 +816,8 @@
|
|||||||
|
|
||||||
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
|
||||||
|
|
||||||
|
"argon2": ["argon2@0.43.0", "", { "dependencies": { "@phc/format": "^1.0.0", "node-addon-api": "^8.3.1", "node-gyp-build": "^4.8.4" } }, "sha512-u/HKLcbWShVDhkfwI4hWyiUf3qyX8QhTfaIv2cWE18uqhXCmR5hb6Ed7oqYi2KCQegeAnRhiFzbjzm7i5yl1GA=="],
|
||||||
|
|
||||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
|
|
||||||
"aria-hidden": ["aria-hidden@1.2.4", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A=="],
|
"aria-hidden": ["aria-hidden@1.2.4", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A=="],
|
||||||
@ -1118,6 +1124,10 @@
|
|||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.151", "", {}, "sha512-Rl6uugut2l9sLojjS4H4SAr3A4IgACMLgpuEMPYCVcKydzfyPrn5absNRju38IhQOf/NwjJY8OGWjlteqYeBCA=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.151", "", {}, "sha512-Rl6uugut2l9sLojjS4H4SAr3A4IgACMLgpuEMPYCVcKydzfyPrn5absNRju38IhQOf/NwjJY8OGWjlteqYeBCA=="],
|
||||||
|
|
||||||
|
"emoji-datasource": ["emoji-datasource@15.0.1", "", {}, "sha512-aF5Q6LCKXzJzpG4K0ETiItuzz0xLYxNexR9qWw45/shuuEDWZkOIbeGHA23uopOSYA/LmeZIXIFsySCx+YKg2g=="],
|
||||||
|
|
||||||
|
"emoji-js": ["emoji-js@3.8.1", "", { "dependencies": { "emoji-datasource": "15.0.1" } }, "sha512-yyXMnZLXgqQHAhEm2DKK4Nrca+jbLQfNOP2mLcNTS6XxzzbQLDFHAguPQrtJS4Udot0Pvomwmh1ckQzhrePhKw=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
|
"emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
|
||||||
|
|
||||||
"enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="],
|
"enabled": ["enabled@2.0.0", "", {}, "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="],
|
||||||
@ -1366,6 +1376,8 @@
|
|||||||
|
|
||||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||||
|
|
||||||
|
"idb-keyval": ["idb-keyval@5.1.5", "", { "dependencies": { "safari-14-idb-fix": "^1.0.6" } }, "sha512-J1utxYWQokYjy01LvDQ7WmiAtZCGUSkVi9EIBfUSyLOr/BesnMIxNGASTh9A1LzeISSjSqEPsfFdTss7EE7ofQ=="],
|
||||||
|
|
||||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||||
|
|
||||||
"ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
"ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
||||||
@ -1674,7 +1686,7 @@
|
|||||||
|
|
||||||
"node-abi": ["node-abi@3.75.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg=="],
|
"node-abi": ["node-abi@3.75.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg=="],
|
||||||
|
|
||||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
"node-addon-api": ["node-addon-api@8.3.1", "", {}, "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA=="],
|
||||||
|
|
||||||
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
|
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
|
||||||
|
|
||||||
@ -2018,6 +2030,8 @@
|
|||||||
|
|
||||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||||
|
|
||||||
|
"safari-14-idb-fix": ["safari-14-idb-fix@1.0.6", "", {}, "sha512-oTEQOdMwRX+uCtWCKT1nx2gAeSdpr8elg/2gcaKUH00SJU2xWESfkx11nmXwTRHy7xfQoj1o4TTQvdmuBosTnA=="],
|
||||||
|
|
||||||
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
|
"safe-regex-test": ["safe-regex-test@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-regex": "^1.2.1" } }, "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw=="],
|
||||||
@ -2466,6 +2480,8 @@
|
|||||||
|
|
||||||
"@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
"@parcel/watcher/detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||||
|
|
||||||
|
"@parcel/watcher/node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||||
|
|
||||||
"@parcel/watcher-wasm/napi-wasm": ["napi-wasm@1.1.3", "", { "bundled": true }, "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg=="],
|
"@parcel/watcher-wasm/napi-wasm": ["napi-wasm@1.1.3", "", { "bundled": true }, "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg=="],
|
||||||
|
|
||||||
"@poppinss/colors/kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
"@poppinss/colors/kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||||
|
@ -13,9 +13,10 @@ const emit = defineEmits(["close"]);
|
|||||||
|
|
||||||
const isDragging = ref(false);
|
const isDragging = ref(false);
|
||||||
const position = ref({
|
const position = ref({
|
||||||
x: props.initialX || Math.floor(window.innerWidth / 2) - Math.random() * 200,
|
x: props.initialX || Math.floor(window.innerWidth / 2 - (parseInt(props.width || '400') / 2)),
|
||||||
y: props.initialY || Math.floor(window.innerHeight / 2) - Math.random() * 10,
|
y: props.initialY || Math.floor(window.innerHeight / 2 - (parseInt(props.height || '300') / 2)),
|
||||||
});
|
});
|
||||||
|
|
||||||
const offset = ref({ x: 0, y: 0 });
|
const offset = ref({ x: 0, y: 0 });
|
||||||
|
|
||||||
const doDrag = useThrottleFn((e: MouseEvent) => {
|
const doDrag = useThrottleFn((e: MouseEvent) => {
|
||||||
|
@ -14,7 +14,7 @@ const submitUserPassword = async () => {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
username: userAccount.value,
|
username: userAccount.value,
|
||||||
pcssword: password,
|
password: password,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
const res = await sendData.json();
|
const res = await sendData.json();
|
||||||
@ -45,7 +45,7 @@ const submitUserPassword = async () => {
|
|||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Your Email"
|
placeholder="Username"
|
||||||
class="mb-2 p-2 border rounded"
|
class="mb-2 p-2 border rounded"
|
||||||
v-model="userAccount"
|
v-model="userAccount"
|
||||||
/>
|
/>
|
||||||
|
@ -13,7 +13,7 @@ const { data: source, pending, error } = await useFetch("/api/getData/fetchSourc
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div >
|
<div >
|
||||||
<div v-for="item in source.data" :key="item.id">
|
<div v-for="item in source?.data" :key="item.id">
|
||||||
<h1>{{ item.title }}</h1>
|
<h1>{{ item.title }}</h1>
|
||||||
<span>{{ item.description }}</span>
|
<span>{{ item.description }}</span>
|
||||||
<a :href="item.url">{{ item.url }}</a>
|
<a :href="item.url">{{ item.url }}</a>
|
||||||
|
@ -27,10 +27,12 @@
|
|||||||
"@uploadthing/nuxt": "^7.1.7",
|
"@uploadthing/nuxt": "^7.1.7",
|
||||||
"@vueuse/core": "^13.1.0",
|
"@vueuse/core": "^13.1.0",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
|
"argon2": "^0.43.0",
|
||||||
"bootstrap-icons": "^1.12.1",
|
"bootstrap-icons": "^1.12.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
|
"emoji-js": "^3.8.1",
|
||||||
"groq-sdk": "^0.21.0",
|
"groq-sdk": "^0.21.0",
|
||||||
"gsap": "^3.13.0",
|
"gsap": "^3.13.0",
|
||||||
"html-to-json-parser": "^2.0.1",
|
"html-to-json-parser": "^2.0.1",
|
||||||
|
@ -123,21 +123,20 @@ const toggleLangMenu = () => {
|
|||||||
|
|
||||||
// values
|
// values
|
||||||
const activeWindows = ref<associAppWindowInterface>([]);
|
const activeWindows = ref<associAppWindowInterface>([]);
|
||||||
const currentApplication = ref();
|
|
||||||
|
|
||||||
// ?opemapp= component
|
// ?opemapp= component
|
||||||
const openApp = ref(false);
|
const openApp = ref(false);
|
||||||
const openAppId = ref();
|
const openAppId = ref();
|
||||||
watch(() => route.query.openapp, (newVal) => {
|
const openAppNameQuery = ref();
|
||||||
if (newVal) {
|
|
||||||
openApp.value = true;
|
onMounted(() => {
|
||||||
openAppId.value = newVal;
|
openApp.value = route.query.openapp;
|
||||||
router.replace({
|
openAppId.value = route.query.id;
|
||||||
path: route.path,
|
openAppNameQuery.value = route.query.name;
|
||||||
query: {},
|
if (openApp.value) {
|
||||||
});
|
openWindow(openApp.value);
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const associAppWindow = [
|
const associAppWindow = [
|
||||||
{
|
{
|
||||||
@ -149,9 +148,11 @@ const associAppWindow = [
|
|||||||
height: "500px",
|
height: "500px",
|
||||||
},
|
},
|
||||||
{ name: "login", id: "2", title: t("app.login") , component: LoginWindow },
|
{ name: "login", id: "2", title: t("app.login") , component: LoginWindow },
|
||||||
{ name: "sources", id: "3", title: t("app.sources"), component: SourcesWindow },
|
{ name: "sources", id: "3", title: t("app.sources"), component: SourcesWindow }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const currentOpenAppId = ref(0);
|
||||||
|
|
||||||
const findAndOpenWindow = (windowName: string) => {
|
const findAndOpenWindow = (windowName: string) => {
|
||||||
const app = associAppWindow.find((app) => app.name === windowName)
|
const app = associAppWindow.find((app) => app.name === windowName)
|
||||||
|
|
||||||
@ -166,13 +167,14 @@ const findAndOpenWindow = (windowName: string) => {
|
|||||||
const windowComponent = shallowRef(app.component)
|
const windowComponent = shallowRef(app.component)
|
||||||
|
|
||||||
activeWindows.value.push({
|
activeWindows.value.push({
|
||||||
id: `${windowName}-${Date.now()}`,
|
id: currentOpenAppId.value,
|
||||||
component: windowComponent,
|
component: windowComponent,
|
||||||
name: windowName,
|
name: windowName,
|
||||||
title: app.title,
|
title: app.title,
|
||||||
width: app.width || "400px",
|
width: app.width || "400px",
|
||||||
height: app.height || "300px",
|
height: app.height || "300px",
|
||||||
})
|
})
|
||||||
|
currentOpenAppId.value++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,8 +185,18 @@ const closeWindow = (windowId: string) => {
|
|||||||
console.log("activeWindows.value", activeWindows.value);
|
console.log("activeWindows.value", activeWindows.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const topWindow = (windowId: string) => {
|
||||||
|
const windowIndex = activeWindows.value.findIndex(
|
||||||
|
(window) => window.id === windowId,
|
||||||
|
);
|
||||||
|
if (windowIndex !== -1) {
|
||||||
|
const [window] = activeWindows.value.splice(windowIndex, 1);
|
||||||
|
activeWindows.value.push(window);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: currentApplication.value.title + " - " + t("app.title"),
|
title: "hi" + " - Desktop",
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@ -249,9 +261,10 @@ useSeoMeta({
|
|||||||
</Transition>
|
</Transition>
|
||||||
<!--Main desktop contents-->
|
<!--Main desktop contents-->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0 z-[-1]"
|
class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0 z-[-10]"
|
||||||
id="desktop"
|
id="desktop"
|
||||||
></div>
|
></div>
|
||||||
|
<Transition>
|
||||||
<div>
|
<div>
|
||||||
<DraggableWindow
|
<DraggableWindow
|
||||||
v-for="window in activeWindows"
|
v-for="window in activeWindows"
|
||||||
@ -260,6 +273,7 @@ useSeoMeta({
|
|||||||
@close="closeWindow(window.id)"
|
@close="closeWindow(window.id)"
|
||||||
:width="window.width"
|
:width="window.width"
|
||||||
:height="window.height"
|
:height="window.height"
|
||||||
|
@clicked="topWindow(window.id)"
|
||||||
>
|
>
|
||||||
<Suspense>
|
<Suspense>
|
||||||
<Component
|
<Component
|
||||||
@ -269,9 +283,10 @@ useSeoMeta({
|
|||||||
</Suspense>
|
</Suspense>
|
||||||
</DraggableWindow>
|
</DraggableWindow>
|
||||||
</div>
|
</div>
|
||||||
|
</Transition>
|
||||||
<!--Footer-->
|
<!--Footer-->
|
||||||
<div
|
<div
|
||||||
class="absolute w-[calc(100% - 5px)] inset-x-0 bottom-0 mx-[1.5px] p-3 justify-between align-center flex flex-row"
|
class="absolute w-[calc(100% - 5px)] inset-x-0 bottom-0 mx-[1.5px] p-3 justify-between align-center flex flex-row z-0"
|
||||||
>
|
>
|
||||||
<div class="">
|
<div class="">
|
||||||
<!--Lang-->
|
<!--Lang-->
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import EmojiConvertor from "emoji-js";
|
||||||
import { gsap } from "gsap";
|
import { gsap } from "gsap";
|
||||||
import { TextPlugin } from "gsap/TextPlugin";
|
import { TextPlugin } from "gsap/TextPlugin";
|
||||||
gsap.registerPlugin(TextPlugin);
|
gsap.registerPlugin(TextPlugin);
|
||||||
@ -15,6 +16,8 @@ const messages = [
|
|||||||
"BlindSpec",
|
"BlindSpec",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const emoji = new EmojiConvertor();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const tl = gsap.timeline({ repeat: -1 });
|
const tl = gsap.timeline({ repeat: -1 });
|
||||||
messages.forEach((message) => {
|
messages.forEach((message) => {
|
||||||
@ -76,7 +79,7 @@ onMounted(() => {
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||||
>
|
>
|
||||||
<h1 class="text-8xl mt-0">🤔</h1>
|
<h1 class="text-8xl mt-0">{{ emoji.replace_colons(':thinking_face:') }}</h1>
|
||||||
<h2 class="text-xl font-bold">Why?</h2>
|
<h2 class="text-xl font-bold">Why?</h2>
|
||||||
<span class="text-sm"
|
<span class="text-sm"
|
||||||
>{{ t("home.whydes")}}</span
|
>{{ t("home.whydes")}}</span
|
||||||
@ -85,7 +88,7 @@ onMounted(() => {
|
|||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
class="flex flex-col justify-center items-center align-middle bg-[#C9C9C9]/60 rounded-xl shadow-lg p-5 m-5 w-[300px] h-[200px]"
|
||||||
>
|
>
|
||||||
<h1 class="text-8xl mt-0">🧐</h1>
|
<h1 class="text-8xl mt-0">{{ emoji.replace_colons(':face_with_monocle:') }}</h1>
|
||||||
<h2 class="text-xl font-bold">How?</h2>
|
<h2 class="text-xl font-bold">How?</h2>
|
||||||
<span class="text-sm"
|
<span class="text-sm"
|
||||||
>{{ t("home.howdes")}}</span
|
>{{ t("home.howdes")}}</span
|
||||||
|
36
server/api/user/login.ts
Normal file
36
server/api/user/login.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import sql from "~/server/components/postgres";
|
||||||
|
import argon2 from "argon2";
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const salt = process.env.PASSWORD_HASH_SALT;
|
||||||
|
if (!salt) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
message: 'Internal server error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const body = await readBody(event);
|
||||||
|
const { username, password } = body;
|
||||||
|
if (!username || !password) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 400,
|
||||||
|
message: 'Username and password are required'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const USERNAME_PATTERN = /^[a-zA-Z0-9_]{3,20}$/;
|
||||||
|
if (!USERNAME_PATTERN.test(username)) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 400,
|
||||||
|
message: 'Invalid username.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Server side hashing
|
||||||
|
const hashedPassword = await argon2.hash(salt, password);
|
||||||
|
|
||||||
|
// Check if user exists, if not, create a user
|
||||||
|
try {
|
||||||
|
console.log(username);
|
||||||
|
console.log(hashedPassword);
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user