mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
Fix: UI revise (#50)
* Change tailwind.config.js structure * Fix line break error in QuestPart.vue
This commit is contained in:
16 files changed
+104
-96
No files matched your search
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + Vue</title>
|
||||
<title>Linux Odyssey</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="bg-background-primary h-screen">
|
||||
<div class="bg-bg-primary h-screen">
|
||||
<!-- route outlet -->
|
||||
<!-- component matched by the route will render here -->
|
||||
<router-view></router-view>
|
||||
|
||||
@@ -86,14 +86,21 @@ const handleChange = () => {
|
||||
<template>
|
||||
<!-- login page -->
|
||||
<div
|
||||
class="bg-background border-8 border-background-primary flex flex-1 flex-col items-center justify-center rounded-3xl p-10"
|
||||
class="bg-bg border-8 border-bg-primary flex flex-1 flex-col items-center justify-center rounded-3xl p-10"
|
||||
>
|
||||
<h1 class="text-text-primary text-3xl font-black mb-2">{{ title }}</h1>
|
||||
<div class="text-error inline-flex justify-center items-center xl:hidden">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'circle-exclamation']"
|
||||
class="px-1 text-sm"
|
||||
/>
|
||||
<span>建議使用電腦全螢幕執行</span>
|
||||
</div>
|
||||
<form @submit.prevent="handleSubmit()" class="w-full">
|
||||
<div v-if="socialLogin && hasSocialLogins">
|
||||
<a
|
||||
v-if="availableMethods.google"
|
||||
class="inline-flex justify-center items-center rounded-lg py-2 mt-3 bg-background-primary text-text-secondary w-full border-text-secondary border-2"
|
||||
class="inline-flex justify-center items-center rounded-lg py-2 mt-3 bg-bg-primary text-text-secondary w-full border-text-secondary border-2"
|
||||
href="/api/v1/auth/google"
|
||||
>
|
||||
<font-awesome-icon
|
||||
@@ -104,7 +111,7 @@ const handleChange = () => {
|
||||
</a>
|
||||
<a
|
||||
v-if="availableMethods.github"
|
||||
class="inline-flex justify-center items-center rounded-lg py-2 mt-3 bg-background-primary text-text-secondary w-full border-text-secondary border-2"
|
||||
class="inline-flex justify-center items-center rounded-lg py-2 mt-3 bg-bg-primary text-text-secondary w-full border-text-secondary border-2"
|
||||
href="/api/v1/auth/github"
|
||||
>
|
||||
<font-awesome-icon
|
||||
@@ -113,19 +120,19 @@ const handleChange = () => {
|
||||
/>
|
||||
<span class="font-medium">Continue with GitHub</span>
|
||||
</a>
|
||||
<p
|
||||
class="text-text-secondary flex justify-center mt-3"
|
||||
v-if="type === 'login' || type === 'register'"
|
||||
>
|
||||
or
|
||||
</p>
|
||||
</div>
|
||||
<p
|
||||
class="text-text-secondary flex justify-center mt-3"
|
||||
v-if="type === 'login' || type === 'register'"
|
||||
>
|
||||
or
|
||||
</p>
|
||||
<div class="mb-6">
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
ref="usernameInput"
|
||||
class="my-4 bg-background-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-background-secondary"
|
||||
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||
:placeholder="type === 'login' ? 'Email / Username' : 'Username'"
|
||||
v-model="username"
|
||||
required
|
||||
@@ -136,8 +143,8 @@ const handleChange = () => {
|
||||
class="text-sm font-normal text-text-secondary"
|
||||
v-if="type === 'username' || type === 'register'"
|
||||
>
|
||||
<p>Username must begin with lowercase letter</p>
|
||||
<p>Username can consist of lowercase, numbers, "_", and "-"</p>
|
||||
<p>可用小寫字母、數字、"_"和"-"</p>
|
||||
<p>小寫字母開頭,至多32字元</p>
|
||||
</label>
|
||||
</div>
|
||||
<div class="mb-6" v-if="type === 'register'">
|
||||
@@ -145,7 +152,7 @@ const handleChange = () => {
|
||||
type="email"
|
||||
id="email"
|
||||
ref="emailInput"
|
||||
class="my-4 bg-background-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-background-secondary"
|
||||
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||
placeholder="Email"
|
||||
v-model="email"
|
||||
required
|
||||
@@ -157,7 +164,7 @@ const handleChange = () => {
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
class="my-4 bg-background-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-background-secondary"
|
||||
class="my-4 bg-bg-primary text-text-primary bg- rounded-md block w-full px-3 h-10 shadow-sm focus:outline-none placeholder:text-text-line focus:ring-2 focus:ring-text-primary ring-1 ring-bg-secondary"
|
||||
placeholder="Password"
|
||||
v-model="password"
|
||||
required
|
||||
@@ -168,7 +175,7 @@ const handleChange = () => {
|
||||
{{ errorMessage }}
|
||||
</p>
|
||||
<button
|
||||
class="inline-flex justify-center rounded-lg font-black py-2 bg-text-primary text-background w-full"
|
||||
class="inline-flex justify-center rounded-lg font-black py-2 bg-text-primary text-bg w-full"
|
||||
type="submit"
|
||||
>
|
||||
<span v-if="type === 'login'">Log In</span>
|
||||
|
||||
@@ -17,7 +17,7 @@ setTimeout(() => {
|
||||
|
||||
<template>
|
||||
<div v-if="showModal" class="modal">
|
||||
<div class="modal-content bg-background-secondary rounded-lg">
|
||||
<div class="modal-content bg-bg-secondary rounded-lg">
|
||||
<span class="close text-text" @click="closeModal">×</span>
|
||||
<h2 class="text-2xl text-text mb-5 w-full inline-flex justify-center">
|
||||
Quest Completed!
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
<template>
|
||||
<section class="h-[10%] p-3 grid grid-cols-3 gap-4 place-content-between">
|
||||
<button id="solution" class="bg-disabled-background rounded-lg p-2">
|
||||
<button id="solution" class="bg-bg-disabled rounded-lg p-2">
|
||||
<font-awesome-icon
|
||||
:icon="['far', 'circle-question']"
|
||||
class="text-disabled-text"
|
||||
class="text-text-disabled"
|
||||
/>
|
||||
<p class="text-disabled-text inline">Solution</p>
|
||||
<p class="text-text-disabled inline ml-1">Solution</p>
|
||||
</button>
|
||||
<button
|
||||
id="reset"
|
||||
class="bg-background-secondary rounded-lg p-2"
|
||||
@click="reset"
|
||||
>
|
||||
<button id="reset" class="bg-bg-secondary rounded-lg p-2" @click="reset">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'arrow-rotate-left']"
|
||||
class="text-text-primary"
|
||||
/>
|
||||
<p class="text-text-primary inline">Reset</p>
|
||||
<p class="text-text-primary inline ml-1">Reset</p>
|
||||
</button>
|
||||
<button id="continue" class="bg-disabled-background rounded-lg p-2">
|
||||
<button id="continue" class="bg-bg-disabled rounded-lg p-2">
|
||||
<font-awesome-icon
|
||||
:icon="['far', 'circle-right']"
|
||||
class="text-disabled-text"
|
||||
class="text-text-disabled"
|
||||
/>
|
||||
<p class="text-disabled-text inline">Continue</p>
|
||||
<p class="text-text-disabled inline ml-1">Continue</p>
|
||||
</button>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -11,6 +11,8 @@ const handleLogout = async () => {
|
||||
router.push({ name: 'login' })
|
||||
}
|
||||
|
||||
const bugReportUrl = 'https://www.surveycake.com/s/gOreA'
|
||||
|
||||
const questData = ref(null)
|
||||
const questErr = ref(null)
|
||||
|
||||
@@ -25,22 +27,19 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
id="header"
|
||||
class="bg-background-secondary content-center h-full w-full p-1"
|
||||
>
|
||||
<div id="header" class="bg-bg-secondary content-center h-full w-full p-1">
|
||||
<div class="h-full flex items-center justify-center mx-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<!-- <button id="stream" class="flex items-center">
|
||||
<!-- <button id="stream" class="flex items-center h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'bars']"
|
||||
class="text-text-primary h-5 w-5"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</button>
|
||||
<button id="backward" class="flex items-center">
|
||||
<button id="backward" class="flex items-center h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'arrow-left']"
|
||||
class="text-text-tertiary h-5 w-5"
|
||||
class="text-text-tertiary h-full w-full"
|
||||
/>
|
||||
</button> -->
|
||||
<button>
|
||||
@@ -53,28 +52,39 @@ onMounted(async () => {
|
||||
</button>
|
||||
</div>
|
||||
<div class="h-full w-full flex gap-3 items-center justify-end">
|
||||
<!-- <button id="warning" class="flex items-center">
|
||||
<!-- <button id="warning" class="flex items-center h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'triangle-exclamation']"
|
||||
class="text-text-primary h-5 w-5"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</button>
|
||||
<button id="setting" class="flex items-center">
|
||||
<button id="setting" class="flex items-center h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'gear']"
|
||||
class="text-text-primary h-5 w-5"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</button>
|
||||
<button id="fullscreen" class="flex items-center">
|
||||
<button id="fullscreen" class="flex items-center h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'expand']"
|
||||
class="text-text-primary h-5 w-5"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</button> -->
|
||||
<button @click="handleLogout">
|
||||
<a
|
||||
title="Bug Report"
|
||||
:href="bugReportUrl"
|
||||
target="_blank"
|
||||
class="h-5 w-5"
|
||||
>
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'bug']"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</a>
|
||||
<button title="Sign Out" @click="handleLogout" class="h-5 w-5">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'arrow-right-from-bracket']"
|
||||
class="text-text-primary h-5 w-5"
|
||||
class="text-text-primary h-full w-full"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -55,12 +55,10 @@ const right = () => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hint" class="bg-background flex flex-wrap">
|
||||
<div class="bg-background h-full rounded-lg p-8 m-1">
|
||||
<p class="inline text-text font-xl font-xl">
|
||||
{{ sessionManager.hints.value[current] }}
|
||||
</p>
|
||||
<br />
|
||||
</div>
|
||||
<div id="hint" class="bg-bg flex flex-wrap p-8">
|
||||
<p class="text-text font-xl whitespace-pre-wrap">
|
||||
{{ sessionManager.hints.value[current] }}
|
||||
</p>
|
||||
<br />
|
||||
</div>
|
||||
</template>
|
||||
@@ -26,7 +26,7 @@ onMounted(async () => {
|
||||
</h1>
|
||||
<hr class="border-text-tertiary border-2 my-2" />
|
||||
<div>
|
||||
<div v-if="questData">
|
||||
<div v-if="questData" class="whitespace-pre-wrap">
|
||||
<p class="text-text">{{ questData.instruction }}</p>
|
||||
<br />
|
||||
<p class="text-text">Tasks:</p>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div
|
||||
id="terminal"
|
||||
ref="terminal"
|
||||
class="bg-background-secondary h-[calc(100%-5%)] p-0.5"
|
||||
class="bg-bg-secondary h-[calc(100%-5%)] p-0.5"
|
||||
></div>
|
||||
</template>
|
||||
|
||||
|
||||
+11
-7
@@ -13,6 +13,8 @@ import {
|
||||
faArrowRotateLeft,
|
||||
faArrowRightFromBracket,
|
||||
faArrowRight,
|
||||
faBug,
|
||||
faCircleExclamation,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faLightbulb,
|
||||
@@ -25,17 +27,19 @@ import { faGithub, faGoogle } from '@fortawesome/free-brands-svg-icons'
|
||||
library.add(
|
||||
faBars,
|
||||
faArrowLeft,
|
||||
faTriangleExclamation,
|
||||
faGear,
|
||||
faExpand,
|
||||
faList,
|
||||
faLightbulb,
|
||||
faCircleQuestion,
|
||||
faArrowRotateLeft,
|
||||
faCircleRight,
|
||||
faGear,
|
||||
faTriangleExclamation,
|
||||
faExpand,
|
||||
faTerminal,
|
||||
faArrowRotateLeft,
|
||||
faArrowRightFromBracket,
|
||||
faArrowRight,
|
||||
faBug,
|
||||
faCircleExclamation,
|
||||
faLightbulb,
|
||||
faCircleQuestion,
|
||||
faCircleRight,
|
||||
faGithub,
|
||||
faGoogle
|
||||
)
|
||||
@@ -45,12 +45,12 @@ async function handleSubmit({ username, success, error }) {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative w-screen h-screen">
|
||||
<div class="w-screen h-screen">
|
||||
<Background class="w-full h-full" />
|
||||
<div
|
||||
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
||||
>
|
||||
<div class="h-2/3 w-1/3">
|
||||
<div class="w-fit">
|
||||
<AuthForm
|
||||
@onSubmit="handleSubmit"
|
||||
@onChange="check"
|
||||
|
||||
@@ -21,7 +21,7 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<!-- game header -->
|
||||
<div class="h-[5vh] w-full">
|
||||
<div class="h-[6vh] w-full">
|
||||
<GameHeaderPart />
|
||||
</div>
|
||||
<!-- current status indicator -->
|
||||
@@ -31,9 +31,9 @@ onMounted(async () => {
|
||||
:value="sessionManager.status.value"
|
||||
/>
|
||||
<!-- main -->
|
||||
<div id="main" class="h-[95vh] w-full flex p-3 space-x-3">
|
||||
<div id="main" class="h-[94vh] w-full flex p-3 space-x-3">
|
||||
<!-- Topic and Command List -->
|
||||
<div class="bg-background-secondary h-full w-1/3 rounded-lg">
|
||||
<div class="bg-bg-secondary h-full w-1/3 rounded-lg">
|
||||
<section id="quest" class="h-2/3 p-3">
|
||||
<QuestPart />
|
||||
</section>
|
||||
@@ -43,7 +43,7 @@ onMounted(async () => {
|
||||
</section>
|
||||
</div>
|
||||
<!-- Terminal and Hint -->
|
||||
<div class="bg-background h-full w-1/3 rounded-lg">
|
||||
<div class="bg-bg h-full w-1/3 rounded-lg">
|
||||
<section id="terminal" class="h-3/5">
|
||||
<TerminalPart />
|
||||
</section>
|
||||
@@ -54,11 +54,8 @@ onMounted(async () => {
|
||||
<!-- Visualization -->
|
||||
<div class="h-full w-1/3">
|
||||
<div class="bg-border rounded-xl h-[90%] p-2">
|
||||
<div class="bg-background rounded-lg h-full p-2">
|
||||
<section
|
||||
id="visualization"
|
||||
class="bg-background-primary h-full rounded-md"
|
||||
>
|
||||
<div class="bg-bg rounded-lg h-full p-2">
|
||||
<section id="visualization" class="bg-bg-primary h-full rounded-md">
|
||||
<VisualizationPart />
|
||||
</section>
|
||||
</div>
|
||||
|
||||
@@ -32,12 +32,12 @@ const handleLogin = async ({ username, password, success, error }) => {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative w-screen h-screen">
|
||||
<div class="w-screen h-screen">
|
||||
<Background class="w-full h-full" />
|
||||
<div
|
||||
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
||||
class="w-screen h-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
||||
>
|
||||
<div class="w-1/3">
|
||||
<div class="w-fit">
|
||||
<AuthForm @onSubmit="handleLogin" type="login" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -65,12 +65,12 @@ async function check({ username, email, password, error }) {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative w-screen h-screen">
|
||||
<div class="w-screen h-screen">
|
||||
<Background class="w-full h-full" />
|
||||
<div
|
||||
class="h-screen w-screen absolute top-0 left-0 flex flex-wrap justify-center content-center"
|
||||
>
|
||||
<div class="w-1/3">
|
||||
<div class="w-fit">
|
||||
<AuthForm
|
||||
@onSubmit="handleRegister"
|
||||
@onChange="check"
|
||||
|
||||
@@ -4,21 +4,19 @@ export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
background: {
|
||||
bg: {
|
||||
primary: '#282A33',
|
||||
secondary: '#131313',
|
||||
disabled: '#454552',
|
||||
DEFAULT: '#000000',
|
||||
},
|
||||
text: {
|
||||
primary: '#00FF00',
|
||||
secondary: '#ADADB5',
|
||||
tertiary: '#4A4B63',
|
||||
disabled: '#6A6B8C',
|
||||
DEFAULT: '#FFFFFF',
|
||||
},
|
||||
disabled: {
|
||||
background: '#454552',
|
||||
text: '#6A6B8C',
|
||||
},
|
||||
border: {
|
||||
DEFAULT: '#526B4E',
|
||||
},
|
||||
|
||||
+11
-13
@@ -2,9 +2,7 @@ title: Hello, Linux World!
|
||||
instruction: |
|
||||
你身在一個漆黑寂靜的地方,似乎失去了記憶。
|
||||
你感到腦中有某個聲音跟你說:
|
||||
|
||||
使用 `echo [咒語]` 指令來朗誦以下咒語
|
||||
「 help 」
|
||||
「使用 `echo [ 咒語 ]` 指令來朗誦咒語 "help" 」
|
||||
|
||||
stages:
|
||||
- id: help
|
||||
@@ -30,8 +28,8 @@ stages:
|
||||
- 首先,你必須要學會如何使用指令。
|
||||
- 你要學習的第一個指令,是「搜索」的指令:`ls` (list)。 `ls` 可以用來查看一個目錄中有哪些檔案。
|
||||
- 現在,請你輸入 `ls` 來查看目前的目錄下有哪些檔案。
|
||||
hints:
|
||||
- 使用 `ls` 指令來查看目前的目錄下有哪些檔案。
|
||||
hints: |
|
||||
➤ 使用 `ls` 指令來查看目前的目錄下有哪些檔案。
|
||||
|
||||
- id: find-scroll
|
||||
task: 搜索卷軸
|
||||
@@ -52,13 +50,13 @@ stages:
|
||||
speaker: Unix 精靈
|
||||
content:
|
||||
- 你找到了一個被遺忘的卷軸,上面寫著解除封印的咒語。
|
||||
- 使用指令 `cat [檔案名稱]` (concatenate)來查看檔案內容。
|
||||
- 使用指令 `cat [ 檔案名稱 ]` (concatenate)來查看檔案內容。
|
||||
- 我可以為你提供一些指令的提示,只要輸入指令的前幾個字元,然後按下 `Tab` 鍵,就可以看到提示了。
|
||||
- 例如你只要輸入檔案名稱的前幾個字元,然後按下 `Tab` 鍵,就可以看到提示了。
|
||||
hints:
|
||||
- 使用 `cat [檔案名稱]` 指令來查看檔案內容。
|
||||
- 使用 `Tab` 鍵來取得指令提示。
|
||||
- 如果卡在未知的情況,按下 `Ctrl + C` 嘗試離開。
|
||||
hints: |
|
||||
➤ 使用 `cat [ 檔案名稱 ]` 指令來查看檔案內容。
|
||||
➤ 使用 `Tab` 鍵來取得指令提示。
|
||||
➤ 如果卡在未知的情況,按下 `Ctrl + C` 嘗試離開。
|
||||
|
||||
- id: read-forgotten-scroll
|
||||
task: 查看卷軸
|
||||
@@ -75,9 +73,9 @@ stages:
|
||||
speaker: Unix 精靈
|
||||
content:
|
||||
- 你找到的是一個被遺忘的卷軸,上面寫著解除封印的咒語。
|
||||
- 使用你已經知道的 `echo [咒語]` 指令來詠唱咒語。
|
||||
hints:
|
||||
- 輸入 `echo Hello World` 來詠唱咒語。
|
||||
- 使用你已經知道的 `echo [ 咒語 ]` 指令來詠唱咒語。
|
||||
hints: |
|
||||
➤ 輸入 `echo Hello World` 來詠唱咒語。
|
||||
|
||||
- id: END
|
||||
task: 解除封印
|
||||
|
||||
Reference in new issue
Block a user