Clean the code via prettier.

This commit is contained in:
yuanhau 2025-05-12 21:05:45 +08:00
parent 57aa0aba18
commit eaa9b15b2d
10 changed files with 177 additions and 165 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { useThrottleFn } from '@vueuse/core'
import { useThrottleFn } from "@vueuse/core";
const props = defineProps<{
title: string;
@ -10,44 +10,52 @@ const props = defineProps<{
}>();
const emit = defineEmits(["close", "min", "maximize", "restore"]);
const title = computed(() => props.title || 'Draggable Window');
const title = computed(() => props.title || "Draggable Window");
const isDragging = ref(false);
const position = ref({
x: props.initialX || Math.floor(window.innerWidth / 2 - (parseInt(props.width || '400') / 2)),
y: props.initialY || Math.floor(window.innerHeight / 2 - (parseInt(props.height || '300') / 2)),
x:
props.initialX ||
Math.floor(window.innerWidth / 2 - parseInt(props.width || "400") / 2),
y:
props.initialY ||
Math.floor(window.innerHeight / 2 - parseInt(props.height || "300") / 2),
});
const offset = ref({ x: 0, y: 0 });
const doDrag = useThrottleFn((e: MouseEvent) => {
if (!isDragging.value) return
if (!isDragging.value) return;
requestAnimationFrame(() => {
position.value = {
x: Math.max(0, Math.min(window.innerWidth - 400, e.clientX - offset.value.x)),
y: Math.max(0, Math.min(window.innerHeight - 300, e.clientY - offset.value.y))
}
})
x: Math.max(
0,
Math.min(window.innerWidth - 400, e.clientX - offset.value.x),
),
y: Math.max(
0,
Math.min(window.innerHeight - 300, e.clientY - offset.value.y),
),
};
});
}, 16);
const startDrag = (e: MouseEvent) => {
isDragging.value = true
isDragging.value = true;
offset.value = {
x: e.clientX - position.value.x,
y: e.clientY - position.value.y
}
document.addEventListener('mousemove', doDrag)
document.addEventListener('mouseup', stopDrag)
}
y: e.clientY - position.value.y,
};
document.addEventListener("mousemove", doDrag);
document.addEventListener("mouseup", stopDrag);
};
const stopDrag = () => {
isDragging.value = false
document.removeEventListener('mousemove', doDrag)
document.removeEventListener('mouseup', stopDrag)
}
isDragging.value = false;
document.removeEventListener("mousemove", doDrag);
document.removeEventListener("mouseup", stopDrag);
};
</script>
<template>

View file

@ -11,7 +11,6 @@ try {
} catch (error) {
console.error("Error:", error);
}
</script>
<template>
<div

View file

@ -3,36 +3,36 @@ import sha512 from "crypto-js/sha512";
const userAccount = ref("");
const userPassword = ref("");
const submitUserPassword = async () => {
// Encrypt password during transit
const password = sha512(userPassword.value).toString();
// Encrypt password during transit
const password = sha512(userPassword.value).toString();
// Send data.
const sendData = await fetch("/api/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: userAccount.value,
password: password,
}),
})
const res = await sendData.json();
// Send data.
const sendData = await fetch("/api/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: userAccount.value,
password: password,
}),
});
const res = await sendData.json();
if (res.status === "ok") {
// Store the token in local storage
localStorage.setItem("token", res.token);
// Redirect to the home page
window.location.href = "/";
success.value = true;
} else {
alert("Login failed");
error.value = true;
}
// Clear the input fields
userAccount.value = "";
userPassword.value = "";
}
if (res.status === "ok") {
// Store the token in local storage
localStorage.setItem("token", res.token);
// Redirect to the home page
window.location.href = "/";
success.value = true;
} else {
alert("Login failed");
error.value = true;
}
// Clear the input fields
userAccount.value = "";
userPassword.value = "";
};
</script>
<template>
<div class="flex flex-col items-center justify-center h-full">

View file

@ -1,22 +1,26 @@
<script setup lang="ts">
const { t, locale } = useI18n();
const { data: source, pending, error } = await useFetch("/api/getData/fetchSources", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: {
lang: locale,
},
const {
data: source,
pending,
error,
} = await useFetch("/api/getData/fetchSources", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: {
lang: locale,
},
});
</script>
<template>
<div >
<div v-for="item in source?.data" :key="item.id">
<h1>{{ item.title }}</h1>
<span>{{ item.description }}</span>
<a :href="item.url">{{ item.url }}</a>
</div>
<div>
<div v-for="item in source?.data" :key="item.id">
<h1>{{ item.title }}</h1>
<span>{{ item.description }}</span>
<a :href="item.url">{{ item.url }}</a>
</div>
</div>
</template>

View file

@ -18,7 +18,7 @@
"startusing": "開始使用!",
"learnmore": "了解更多",
"whydes": "台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。",
"howdes":" 我們使用使用 Python 寫的網頁爬蟲來搜尋最新的新聞並將其存入Postgres資料庫中。"
"howdes": " 我們使用使用 Python 寫的網頁爬蟲來搜尋最新的新聞並將其存入Postgres資料庫中。"
},
"dailybriefing": "今日報導",
"Welcome": "歡迎",

View file

@ -135,7 +135,7 @@ onMounted(async () => {
if (openApp.value) {
openWindow(openApp.value);
}
})
});
const associAppWindow = [
{
@ -146,24 +146,31 @@ const associAppWindow = [
width: "700px",
height: "500px",
},
{ name: "login", id: "2", title: t("app.login") , component: LoginWindow },
{ name: "sources", id: "3", title: t("app.sources"), component: SourcesWindow }
{ name: "login", id: "2", title: t("app.login"), component: LoginWindow },
{
name: "sources",
id: "3",
title: t("app.sources"),
component: SourcesWindow,
},
];
const currentOpenAppId = ref(0);
const findAndOpenWindow = (windowName: string) => {
const app = associAppWindow.find((app) => app.name === windowName)
const app = associAppWindow.find((app) => app.name === windowName);
// Prevent dual logins
if (windowName === "login" &&
activeWindows.value.some((window) => window.name === "login")) {
return
if (
windowName === "login" &&
activeWindows.value.some((window) => window.name === "login")
) {
return;
}
if (app) {
// Use shallowRef for better performance with components
const windowComponent = shallowRef(app.component)
const windowComponent = shallowRef(app.component);
activeWindows.value.push({
id: currentOpenAppId.value,
@ -172,10 +179,10 @@ const findAndOpenWindow = (windowName: string) => {
title: app.title,
width: app.width || "400px",
height: app.height || "300px",
})
});
currentOpenAppId.value++;
}
}
};
const closeWindow = (windowId: string) => {
activeWindows.value = activeWindows.value.filter(
@ -196,7 +203,7 @@ const topWindow = (windowId: string) => {
useSeoMeta({
title: "hi" + " - Desktop",
})
});
</script>
<template>
<div
@ -263,27 +270,27 @@ useSeoMeta({
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"
></div>
<Transition>
<div>
<DraggableWindow
v-for="window in activeWindows"
:key="window.id"
:title="window.title"
@close="closeWindow(window.id)"
@min="unMinWindow(window.id)"
:width="window.width"
:height="window.height"
@clicked="topWindow(window.id)"
>
<Transition>
<div>
<DraggableWindow
v-for="window in activeWindows"
:key="window.id"
:title="window.title"
@close="closeWindow(window.id)"
@min="unMinWindow(window.id)"
:width="window.width"
:height="window.height"
@clicked="topWindow(window.id)"
>
<Suspense>
<Component
:is="window.component"
@error="console.error('Error:', $event)"
/>
</Suspense>
</DraggableWindow>
</div>
</Transition>
<Component
:is="window.component"
@error="console.error('Error:', $event)"
/>
</Suspense>
</DraggableWindow>
</div>
</Transition>
<!--Footer-->
<div
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"

View file

@ -1,6 +1,6 @@
<template>
<div class="justify-center align-center text-center">
<span class="text-6xl text-bold">目前沒有手機版本</span>
<span class="text-xl">請使用電腦版</span>
</div>
<div class="justify-center align-center text-center">
<span class="text-6xl text-bold">目前沒有手機版本</span>
<span class="text-xl">請使用電腦版</span>
</div>
</template>

View file

@ -78,18 +78,14 @@ onMounted(() => {
>
<h1 class="text-8xl mt-0">🤔</h1>
<h2 class="text-xl font-bold">Why?</h2>
<span class="text-sm"
>{{ t("home.whydes")}}</span
>
<span class="text-sm">{{ t("home.whydes") }}</span>
</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]"
>
<h1 class="text-8xl mt-0">🧐</h1>
<h2 class="text-xl font-bold">How?</h2>
<span class="text-sm"
>{{ t("home.howdes")}}</span
>
<span class="text-sm">{{ t("home.howdes") }}</span>
</div>
</div>
<br />

View file

@ -1,25 +1,25 @@
import sql from "~/server/components/postgres";
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const query = getQuery(event);
/*const sources = await sql`SELECT * FROM sources`;
const body = await readBody(event);
const query = getQuery(event);
/*const sources = await sql`SELECT * FROM sources`;
return sources;*/
// Fake data
return {
status: "ok",
data: [
{
id: 1,
title: "Source 1",
url: "https://source1.com",
description: "Description for Source 1",
},
{
id: 2,
title: "Source 2",
url: "https://source2.com",
description: "Description for Source 2",
}
]
}
})
// Fake data
return {
status: "ok",
data: [
{
id: 1,
title: "Source 1",
url: "https://source1.com",
description: "Description for Source 1",
},
{
id: 2,
title: "Source 2",
url: "https://source2.com",
description: "Description for Source 2",
},
],
};
});

View file

@ -1,36 +1,34 @@
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);
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) {
}
})
// Check if user exists, if not, create a user
try {
console.log(username);
console.log(hashedPassword);
} catch (e) {}
});