mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 21:14:23 +00:00
Clean the code via prettier.
This commit is contained in:
parent
57aa0aba18
commit
eaa9b15b2d
10 changed files with 177 additions and 165 deletions
|
@ -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>
|
||||
|
|
|
@ -11,7 +11,6 @@ try {
|
|||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
}
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
|
@ -18,7 +18,7 @@
|
|||
"startusing": "開始使用!",
|
||||
"learnmore": "了解更多",
|
||||
"whydes": "台灣的新聞是要痲是來自中國控制的媒體,或是來自只想獲得點閱的記者。",
|
||||
"howdes":" 我們使用使用 Python 寫的網頁爬蟲來搜尋最新的新聞,並將其存入Postgres資料庫中。"
|
||||
"howdes": " 我們使用使用 Python 寫的網頁爬蟲來搜尋最新的新聞,並將其存入Postgres資料庫中。"
|
||||
},
|
||||
"dailybriefing": "今日報導",
|
||||
"Welcome": "歡迎",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
||||
|
|
|
@ -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) {}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue