mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-05 19:20:12 +08:00
feat: add Authentication Page
This commit is contained in:
1 parent
9da4d4edaa
commit
b41343ed68
8 files changed
+159
-9
No files matched your search
+4
-1
@@ -15,12 +15,15 @@ module.exports = {
|
||||
sourceType: 'module',
|
||||
},
|
||||
rules: {
|
||||
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }], // We added this
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'import/extensions': 'off',
|
||||
camelcase: ['error', { properties: 'never', ignoreDestructuring: true }],
|
||||
'no-param-reassign': ['error', { props: false }],
|
||||
'no-underscore-dangle': ['error', { allow: ['_id'] }],
|
||||
/* we added this */
|
||||
'no-var': 'error',
|
||||
'no-plusplus': 'off',
|
||||
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
||||
},
|
||||
}
|
||||
+4
-3
@@ -1,5 +1,8 @@
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import socket from './utils/socket'
|
||||
import sessionManager from './utils/session'
|
||||
|
||||
import CommandlistPart from './components/CommandlistPart.vue'
|
||||
import HeaderPart from './components/HeaderPart.vue'
|
||||
import HintPart from './components/HintPart.vue'
|
||||
@@ -7,8 +10,6 @@ import QuestPart from './components/QuestPart.vue'
|
||||
import TerminalPart from './components/TerminalPart.vue'
|
||||
import VisualizationPart from './components/VisualizationPart.vue'
|
||||
import ControlPalette from './components/ControlPalette.vue'
|
||||
import socket from './utils/socket'
|
||||
import sessionManager from './utils/session'
|
||||
|
||||
onMounted(async () => {
|
||||
await sessionManager.lastOrCreate()
|
||||
@@ -36,7 +37,7 @@ onMounted(async () => {
|
||||
<section id="quest" class="h-2/3 m-3">
|
||||
<QuestPart />
|
||||
</section>
|
||||
<hr class="border-text-line border" />
|
||||
<hr class="border-text-tertiary border" />
|
||||
<section id="cmdlist" class="h-1/3">
|
||||
<CommandlistPart />
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<script setup>
|
||||
import AuthenticationPart from './components/AuthenticationPart.vue'
|
||||
import Background from './components/DynamicBackground.vue'
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative 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">
|
||||
<AuthenticationPart />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script setup></script>
|
||||
<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"
|
||||
>
|
||||
<h1 class="text-text-primary text-3xl font-black mb-8">Linux Odysssey</h1>
|
||||
<form action="" class="w-full">
|
||||
<div class="mb-6">
|
||||
<label for="email" class="text-sm font-semibold text-text">Email</label
|
||||
><input
|
||||
type="email"
|
||||
id="email"
|
||||
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"
|
||||
placeholder="Enter your email address"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="password" class="text-sm font-semibold leading-6 text-text"
|
||||
>Password</label
|
||||
><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"
|
||||
placeholder="Enter your password"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="inline-flex justify-center rounded-lg text-sm font-black py-2 mt-3 bg-text-primary text-background w-full"
|
||||
>
|
||||
<span>Log in / Sign up</span></button
|
||||
><input type="hidden" name="remember" value="true" />
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div id="box">
|
||||
<canvas ref="canvas"></canvas>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const cw = ref(0)
|
||||
const ch = ref(0)
|
||||
const fallingCharArr = ref([])
|
||||
const fontSize = ref(16)
|
||||
const maxColums = ref(0)
|
||||
const charArr = ['0', '1', '', '', '']
|
||||
const ctx = ref(null)
|
||||
|
||||
const randomInt = (min, max) => {
|
||||
return Math.floor(Math.random() * (max - min) + min)
|
||||
}
|
||||
|
||||
const randomFloat = (min, max) => {
|
||||
return Math.random() * (max - min) + min
|
||||
}
|
||||
|
||||
const draw = (point) => {
|
||||
point.value = charArr[randomInt(0, charArr.length)].toUpperCase()
|
||||
if (point.y < 0) point.speed = randomFloat(10, 20)
|
||||
|
||||
ctx.value.fillStyle = '#0F0'
|
||||
ctx.value.font = `${fontSize.value}px san-serif`
|
||||
ctx.value.fillText(point.value, point.x, point.y)
|
||||
|
||||
point.y += point.speed
|
||||
if (point.y > ch.value) {
|
||||
point.y = randomFloat(-100, 0)
|
||||
point.speed = randomFloat(2, 8)
|
||||
}
|
||||
}
|
||||
|
||||
const update = () => {
|
||||
ctx.value.fillStyle = 'rgba(0,0,0,0.05)'
|
||||
ctx.value.fillRect(0, 0, cw.value, ch.value)
|
||||
|
||||
let i = fallingCharArr.value.length
|
||||
while (i--) {
|
||||
draw(fallingCharArr.value[i])
|
||||
}
|
||||
setTimeout(update, 25)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
cw.value = document.documentElement.clientWidth
|
||||
ch.value = document.documentElement.clientHeight
|
||||
maxColums.value = cw.value / fontSize.value
|
||||
|
||||
const canvas = document.querySelector('canvas')
|
||||
ctx.value = canvas.getContext('2d')
|
||||
|
||||
canvas.width = cw.value
|
||||
canvas.height = ch.value
|
||||
|
||||
for (let i = 0; i < maxColums.value; i++) {
|
||||
fallingCharArr.value.push({
|
||||
x: i * fontSize.value,
|
||||
y: randomFloat(-500, 0),
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
cw.value = document.documentElement.clientWidth
|
||||
ch.value = document.documentElement.clientHeight
|
||||
maxColums.value = cw.value / fontSize.value
|
||||
canvas.width = cw.value
|
||||
canvas.height = ch.value
|
||||
})
|
||||
|
||||
update()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#box {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -12,7 +12,7 @@
|
||||
<button id="backward" class="flex items-center">
|
||||
<font-awesome-icon
|
||||
:icon="['fas', 'arrow-left']"
|
||||
class="text-text-line h-5 w-5"
|
||||
class="text-text-tertiary h-5 w-5"
|
||||
/>
|
||||
</button>
|
||||
<button>
|
||||
|
||||
@@ -24,7 +24,7 @@ api
|
||||
<h1 id="topic" class="text-text" v-else-if="questData">
|
||||
{{ questData.title }}
|
||||
</h1>
|
||||
<hr class="border-text-line border-2 my-2" />
|
||||
<hr class="border-text-tertiary border-2 my-2" />
|
||||
<div>
|
||||
<p class="text-red-500" v-if="questErr">{{ questErr.message }}</p>
|
||||
<p class="text-text" v-else-if="questData">{{ questData.instruction }}</p>
|
||||
|
||||
@@ -7,12 +7,12 @@ export default {
|
||||
background: {
|
||||
primary: '#282A33',
|
||||
secondary: '#131313',
|
||||
DEFAULT: '#010103',
|
||||
DEFAULT: '#000000',
|
||||
},
|
||||
text: {
|
||||
primary: '#39FF14',
|
||||
primary: '#00FF00',
|
||||
secondary: '#ADADB5',
|
||||
line: '#4A4B63',
|
||||
tertiary: '#4A4B63',
|
||||
DEFAULT: '#FFFFFF',
|
||||
},
|
||||
disabled: {
|
||||
|
||||
Reference in new issue
Block a user