mirror of
https://ceregatti.org/git/daniel/dayzdockerserver.git
synced 2025-05-06 14:21:18 +00:00
Second working version with vite-express integration.
Replace Bootstrap with Privemue. Add i18n support. English and Brazilian Portuguese to start. New UI with Primevue. Use tabbed menu, nice theme, etc.. WIP with Steam login.
This commit is contained in:
parent
85e59ae8c6
commit
53dea0f45d
23 changed files with 553 additions and 173 deletions
|
@ -19,7 +19,7 @@ services:
|
|||
args:
|
||||
- USER_ID
|
||||
user: ${USER_ID}
|
||||
hostname: web
|
||||
hostname: dayzdockerserver
|
||||
volumes:
|
||||
- homedir_main:/home/user
|
||||
- serverfiles:/serverfiles
|
||||
|
|
|
@ -7,12 +7,12 @@ trap '
|
|||
' SIGINT SIGTERM
|
||||
|
||||
# Set PS1 so we know we're in the container
|
||||
if grep -q "dz-web" .bashrc
|
||||
if ! grep -q "dz-web" .bashrc
|
||||
then
|
||||
echo "Adding PS1 to .bashrc..."
|
||||
cat >> .bashrc <<EOF
|
||||
alias ls='ls --color'
|
||||
export PS1="${debian_chroot:+($debian_chroot)}\u@dz-web:\w\$ "
|
||||
export PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
|
||||
unset DEVELOPMENT
|
||||
export PATH=${PATH}:/usr/local/dotnet
|
||||
EOF
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script setup>
|
||||
import Error from '@/components/Error.vue'
|
||||
import Login from '@/components/Login.vue'
|
||||
import Main from '@/components/Main.vue'
|
||||
import Header from '@/components/Header.vue'
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
|
@ -17,8 +16,7 @@ useFetch('/status', {
|
|||
<Suspense>
|
||||
<main>
|
||||
<Error />
|
||||
<Login v-if="! store.steamStatus.loggedIn" />
|
||||
<Main v-else />
|
||||
<Header />
|
||||
</main>
|
||||
</Suspense>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<script setup>
|
||||
import Mods from '@/components/Mods.vue'
|
||||
import SearchResults from "@/components/SearchResults.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SearchResults />
|
||||
<Mods />
|
||||
</template>
|
|
@ -1,40 +1,11 @@
|
|||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
import { Modal } from 'bootstrap'
|
||||
import Dialog from 'primevue/dialog'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
let modal = {}
|
||||
watch(() => store.errorText, () => {
|
||||
modal = new Modal('#errorModal', {})
|
||||
if (store.errorText) {
|
||||
modal.show()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="modal"
|
||||
id="errorModal"
|
||||
data-bs-backdrop="static"
|
||||
data-bs-keyboard="false"
|
||||
tabindex="-1"
|
||||
aria-labelledby="errorModalLabel"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="errorModalLabel">Error</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{{ store.errorText }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog v-model:visible="store.errorText" modal :header="$t('Error')" :style="{ width: '25rem' }">
|
||||
{{ store.errorText }}
|
||||
</Dialog>
|
||||
</template>
|
||||
|
|
19
web/docroot/src/components/Files.vue
Normal file
19
web/docroot/src/components/Files.vue
Normal file
|
@ -0,0 +1,19 @@
|
|||
<script setup>
|
||||
import Button from 'primevue/button'
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
async function base() {
|
||||
let which = '/installbase'
|
||||
if (store.steamStatus.installed) {
|
||||
which = '/updatebase'
|
||||
}
|
||||
const { data } = await useFetch(which).get().json()
|
||||
store.errorText = data.value.message
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Button @click="base" v-if="store.steamStatus.installed">{{ store.steamStatus.installed ? $t('Update Server Files') : $t('Install Server Files') }}</Button>
|
||||
<span v-else>{{ $t('Server files not installed') }}</span>
|
||||
</template>
|
|
@ -1,45 +1,50 @@
|
|||
<script setup>
|
||||
import Search from '@/components/Search.vue'
|
||||
import Status from '@/components/Status.vue'
|
||||
import Tabs from 'primevue/tabs'
|
||||
import TabList from 'primevue/tablist'
|
||||
import Tab from 'primevue/tab'
|
||||
import TabPanels from 'primevue/tabpanels'
|
||||
import TabPanel from 'primevue/tabpanel'
|
||||
import Files from '@/components/Files.vue'
|
||||
import Home from '@/components/Home.vue'
|
||||
import Steam from '@/components/Steam.vue'
|
||||
import Servers from '@/components/Servers.vue'
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
const set = (w, e) => {
|
||||
store.section = w
|
||||
const active = Array.from(document.getElementsByClassName('active'))
|
||||
active.forEach((a) => a.classList.remove('active'))
|
||||
e.target.classList.add('active')
|
||||
}
|
||||
async function base() {
|
||||
let which = '/installbase'
|
||||
if (store.steamStatus.installed) {
|
||||
which = '/updatebase'
|
||||
}
|
||||
const { data } = await useFetch(which).get().json()
|
||||
store.errorText = data.value.message
|
||||
}
|
||||
import Mods from '@/components/Mods.vue'
|
||||
import Status from '@/components/Status.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="store.steamStatus" class="row">
|
||||
<div class="col-3 text-center">
|
||||
<h1>DayZ Docker Server</h1>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<button
|
||||
@click="base"
|
||||
class="btn btn-sm btn-success"
|
||||
>
|
||||
{{ store.steamStatus.installed ? "Update" : "Install" }} Server Files
|
||||
</button>
|
||||
<button @click="updatemods" class="btn btn-sm btn-outline-success">Update Mods</button>
|
||||
<button type="button" @click="set('servers', $event)" class="btn btn-sm btn-outline-primary">Servers</button>
|
||||
<button type="button" @click="set('mods', $event)" class="btn btn-sm btn-outline-primary active" data-bs-toggle="button">Mods</button>
|
||||
<button type="button" @click="set('search', $event)" class="btn btn-sm btn-outline-primary">Search</button>
|
||||
</div>
|
||||
<Search />
|
||||
<Status />
|
||||
<Servers />
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="col-8 col-offset-2 text-center">
|
||||
<Tabs value="0">
|
||||
<TabList>
|
||||
<Tab value="0">{{ $t('Home') }}</Tab>
|
||||
<Tab value="1">{{ $t('Steam') }}</Tab>
|
||||
<Tab value="2">{{ $t('Files') }}</Tab>
|
||||
<Tab value="3">{{ $t('Mods') }}</Tab>
|
||||
<Tab value="4">{{ $t('Servers') }}</Tab>
|
||||
<Tab value="5">{{ $t('Status') }}</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel value="0">
|
||||
<Home />
|
||||
</TabPanel>
|
||||
<TabPanel value="1">
|
||||
<Steam />
|
||||
</TabPanel>
|
||||
<TabPanel value="2">
|
||||
<Files />
|
||||
</TabPanel>
|
||||
<TabPanel value="3">
|
||||
<Mods />
|
||||
</TabPanel>
|
||||
<TabPanel value="4">
|
||||
<Servers />
|
||||
</TabPanel>
|
||||
<TabPanel value="5">
|
||||
<Status />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
8
web/docroot/src/components/Home.vue
Normal file
8
web/docroot/src/components/Home.vue
Normal file
|
@ -0,0 +1,8 @@
|
|||
<script setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="">
|
||||
<h1>{{ $t('DayZ Docker Server') }}</h1>
|
||||
</div>
|
||||
</template>
|
|
@ -1,34 +0,0 @@
|
|||
<script setup>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="middle">
|
||||
<h1>Login to Steam</h1>
|
||||
<form name="form" method="POST" action="/login" enctype="application/x-www-form-urlencoded">
|
||||
<div>
|
||||
<input type="text" name="username" placeholder="Username" />
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" name="password" placeholder="Password" />
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="guard" placeholder="Steam Guard" />
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="remember" id="remember" />
|
||||
<label for="remember">Remember me</label>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" name="submit">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.middle {
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
|
@ -4,8 +4,6 @@ import Header from './Header.vue'
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container-fluid min-vh-100 d-flex flex-column bg-light">
|
||||
<Header />
|
||||
<Body />
|
||||
</div>
|
||||
<Header />
|
||||
<!-- <Body />-->
|
||||
</template>
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useFetch } from '@vueuse/core'
|
|||
import { useAppStore } from '@/store.js'
|
||||
import ModInfo from '@/components/Modinfo.vue'
|
||||
const store = useAppStore()
|
||||
const { data, error } = useFetch(config.baseUrl + '/mods', {
|
||||
const { data, error } = useFetch('/mods', {
|
||||
afterFetch(ctx) {
|
||||
store.mods = ctx.data.mods
|
||||
return ctx
|
||||
|
@ -13,14 +13,14 @@ const { data, error } = useFetch(config.baseUrl + '/mods', {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row flex-grow-1" v-if="store.section === 'mods'">
|
||||
<div class="row flex-grow-1">
|
||||
<div v-if="error" class="row text-danger">
|
||||
{{ error }}
|
||||
</div>
|
||||
<div v-if="store.mods.length === 0">No mods are installed</div>
|
||||
<div v-if="store.mods.length === 0">{{ $t('No mods are installed') }}</div>
|
||||
<div v-else class="col-md-3 border" v-if="data">
|
||||
<div>
|
||||
<h4 class="text-center">Installed Mods</h4>
|
||||
<h4 class="text-center">{{ $t('Installed Mods') }}</h4>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Steam Link</th>
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
<script setup>
|
||||
import { useAppStore } from '@/store.js'
|
||||
import { useAppStore} from '@/store.js'
|
||||
const store = useAppStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row" v-if="store.section === 'servers'">
|
||||
<div class="col text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2>Servers</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row flex-grow-1">
|
||||
<div class="col-6 justify-content-end">Running</div>
|
||||
<div class="col-6">Stopped</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="store.servers.length > 0">
|
||||
<h1>{{ $t('Servers') }}</h1>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ $t('No servers have been created') }}
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script setup>
|
||||
import Button from 'primevue/button'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
</script>
|
||||
|
@ -6,18 +7,21 @@ const store = useAppStore()
|
|||
<template>
|
||||
<div class="col">
|
||||
<div>
|
||||
Logged into Steam:
|
||||
<span v-if="store.steamStatus.loggedIn" class="bi bi-check h2 text-success"></span>
|
||||
<span v-else class="bi bi-x h2 danger text-danger"></span>
|
||||
{{ $t('Logged into Steam') }}:
|
||||
<span v-if="store.steamStatus.loggedIn" class="pi pi-check" style="color: green"></span>
|
||||
<span v-else class="pi pi-times" style="color: red"></span>
|
||||
</div>
|
||||
<div>
|
||||
Server files installed:
|
||||
<span v-if="store.steamStatus.installed" class="bi bi-check h2 text-success"></span>
|
||||
<span v-else class="bi bi-x h2 danger text-danger"></span>
|
||||
{{ $t('Server files installed') }}:
|
||||
<span v-if="store.steamStatus.installed" class="pi pi-check" style="color: green"></span>
|
||||
<span v-else class="pi pi-times" style="color: red"></span>
|
||||
</div>
|
||||
<div v-if="store.steamStatus.version">
|
||||
Version: <span class="text-success fw-bold">{{ store.steamStatus.version }}</span>
|
||||
<span class="text-success fw-bold">({{ store.steamStatus.appid }})</span>
|
||||
{{ $t('Version') }}: <span style="color: green;">{{ store.steamStatus.version }}</span>
|
||||
<span class="bold">({{ store.steamStatus.appid }})</span>
|
||||
</div>
|
||||
<div>
|
||||
<Button @click="store.errorText = $t('This is an error message')">{{ $t('Test error') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
61
web/docroot/src/components/Steam.vue
Normal file
61
web/docroot/src/components/Steam.vue
Normal file
|
@ -0,0 +1,61 @@
|
|||
<script setup>
|
||||
import { useFetch } from '@vueuse/core'
|
||||
import Checkbox from 'primevue/checkbox'
|
||||
import Button from 'primevue/button'
|
||||
import InputText from 'primevue/inputtext'
|
||||
import Password from 'primevue/password'
|
||||
import { useAppStore } from '@/store.js'
|
||||
const store = useAppStore()
|
||||
async function logOut() {
|
||||
const response = await useFetch('/logout')
|
||||
if (response.ok) {
|
||||
store.steamStatus.loggedIn = false
|
||||
} else if (response.err) {
|
||||
store.errorText = response.err
|
||||
}
|
||||
}
|
||||
function submit(e) {
|
||||
console.log("Submit")
|
||||
}
|
||||
let username = ''
|
||||
let password = ''
|
||||
let remember = false
|
||||
let steamGuardCode = ''
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="store.steamStatus.loggedIn">
|
||||
<div>{{ $t('Already logged in to steam') }}</div>
|
||||
<div>
|
||||
<Button @click="logOut">{{ $t('Log out') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="col-6 col-offset-3">
|
||||
<div class="flex flex-column gap-2">
|
||||
{{ $t('There are no saved Steam credentials. To install the server files and mods, please login to Steam') }}
|
||||
</div>
|
||||
<div class="">
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label for="username">{{ $t('Username') }}</label>
|
||||
<InputText id="username" v-model="username" />
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label for="password">{{ $t('Password') }}</label>
|
||||
<Password id="username" v-model="password" :feedback="false" toggleMask />
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label for="steamGuardCode">{{ $t('Steam Guard Code') }}</label>
|
||||
<InputText id="steamGuardCode" v-model="steamGuardCode" />
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<label for="remember">{{ $t('Remember Credentials') }}</label>
|
||||
<Checkbox v-model="remember" />
|
||||
</div>
|
||||
<div class="flex flex-column gap-2">
|
||||
<Button type="submit" onclick="submit()">{{ $t('Submit') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -1,10 +1,6 @@
|
|||
button {
|
||||
padding: 5px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding-right: 10px
|
||||
.p-tablist-tab-list {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.active {
|
||||
|
|
42
web/docroot/src/locales/en.js
Normal file
42
web/docroot/src/locales/en.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
export const en = {
|
||||
'Already logged in to steam': 'Already logged in to steam',
|
||||
'DayZ': 'DayZ',
|
||||
'DayZ Docker Server': 'DayZ Docker Server',
|
||||
'Error': 'Error',
|
||||
'Experimental': 'Experimental',
|
||||
'Files': 'Files',
|
||||
'Home': 'Home',
|
||||
'Install': 'Install',
|
||||
'Installed mods': 'Installed mods',
|
||||
'Install Server Files': 'Install Server Files',
|
||||
'Log out': 'Log out',
|
||||
'Logged into Steam': 'Logged into Steam',
|
||||
'Mods': 'Mods',
|
||||
'Name': 'Name',
|
||||
'No mods are installed': 'No mods are installed',
|
||||
'No servers have been created': 'No servers have been created',
|
||||
'Not Installed': 'Not Installed',
|
||||
'Password': 'Password',
|
||||
'Release': 'Release',
|
||||
'Remember Credentials': 'Remember Credentials',
|
||||
'Search': 'Search',
|
||||
'Server files installed': 'Server files installed',
|
||||
'Server files not installed': 'Server files not installed',
|
||||
'Servers': 'Servers',
|
||||
'Stable': 'Stable',
|
||||
'Status': 'Status',
|
||||
'Steam': 'Steam',
|
||||
'Steam Guard Code': 'Steam Guard Code',
|
||||
'Submit': 'Submit',
|
||||
'Test error': 'Test error',
|
||||
'There are no saved Steam credentials. To install the server files and mods, please login to Steam': 'There are no saved Steam credentials. To install the server files and mods, please login to Steam',
|
||||
'This is an error message': 'This is an error message',
|
||||
'Total servers': 'Total servers',
|
||||
'Total workshop items': 'Total workshop items',
|
||||
'Up to date': 'Up to date',
|
||||
'Update': 'Update',
|
||||
'Update Server Files': 'Update Server Files',
|
||||
'Username': 'Username',
|
||||
'Version': 'Version',
|
||||
'Workshop': 'Workshop',
|
||||
}
|
16
web/docroot/src/locales/index.js
Normal file
16
web/docroot/src/locales/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { en } from './en.js'
|
||||
import { pt } from './pt.js'
|
||||
|
||||
const messages = {
|
||||
en: en,
|
||||
pt: pt,
|
||||
}
|
||||
|
||||
const locales = {
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
messages: messages
|
||||
}
|
||||
|
||||
export { locales }
|
42
web/docroot/src/locales/pt.js
Normal file
42
web/docroot/src/locales/pt.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
export const pt = {
|
||||
'Already logged in to steam': 'Já registrado com Steam',
|
||||
'DayZ': 'DayZ',
|
||||
'DayZ Docker Server': 'Servidor DayZ de Docker',
|
||||
'Error': 'Erro',
|
||||
'Experimental': 'Experimental',
|
||||
'Files': 'Arquivos',
|
||||
'Home': 'Início',
|
||||
'Install': 'Instalar',
|
||||
'Installed mods': 'Mods instalados',
|
||||
'Install Server Files': 'Instalar Arquivos de Servidor',
|
||||
'Log out': 'Encerrar sessão',
|
||||
'Logged into Steam': 'Registrado com Steam',
|
||||
'Mods': 'Mods',
|
||||
'Name': 'Nome',
|
||||
'No mods are installed': 'Nenhum mod está installado',
|
||||
'No servers have been created': 'Nenhum servidor foi criado',
|
||||
'Not Installed': 'Não Instalado',
|
||||
'Password': 'Senha',
|
||||
'Release': 'Lançado',
|
||||
'Remember Credentials': 'Lembrar Credenciais',
|
||||
'Search': 'Procurar',
|
||||
'Server files installed': 'Arquivos de servidor instalado',
|
||||
'Server files not installed': 'Arquivos de servidor não instalados',
|
||||
'Servers': 'Servidores',
|
||||
'Stable': 'Estável',
|
||||
'Status': 'Estado',
|
||||
'Steam': 'Steam',
|
||||
'Steam Guard Code': 'Còdigo Steam Guard',
|
||||
'Submit': 'Enviar',
|
||||
'Test error': 'Testar erro',
|
||||
'There are no saved Steam credentials. To install the server files and mods, please login to Steam': 'Não existe credencias salvados. Para instalar o servidor, por favor registre-se no Steam',
|
||||
'This is an error message': 'Esta é uma mensagem de erro',
|
||||
'Total servers': 'Total de servidores',
|
||||
'Total workshop items': 'Total de itens de oficina',
|
||||
'Up to date': 'Atualizado',
|
||||
'Update': 'Atualizar',
|
||||
'Update Server Files': 'Atualizer Arquivos de Servidor',
|
||||
'Username': 'Usuário',
|
||||
'Version': 'Versão',
|
||||
'Workshop': 'Oficina',
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
import 'bootstrap/dist/css/bootstrap.min.css'
|
||||
import 'bootstrap'
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||
import 'primeicons/primeicons.css'
|
||||
import 'primeflex/primeflex.css'
|
||||
import './css/index.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import {useAppStore} from '@/store'
|
||||
import { useAppStore } from '@/store'
|
||||
import PrimeVue from 'primevue/config'
|
||||
import Aura from '@primevue/themes/aura'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import { locales } from '@/locales'
|
||||
|
||||
// Create an instance of our Vue app
|
||||
const app = createApp(App)
|
||||
|
@ -14,6 +17,10 @@ const app = createApp(App)
|
|||
// Add the store
|
||||
app.use(createPinia())
|
||||
|
||||
// Add i18n
|
||||
const i18n = createI18n(locales)
|
||||
app.use(i18n)
|
||||
|
||||
// A global error handler
|
||||
app.config.errorHandler = (err, instance, info) => {
|
||||
const store = useAppStore()
|
||||
|
@ -21,5 +28,12 @@ app.config.errorHandler = (err, instance, info) => {
|
|||
console.error('GLOBAL ERROR HANDLER! ', err, instance, info)
|
||||
}
|
||||
|
||||
// Add PrimeVue
|
||||
app.use(PrimeVue, {
|
||||
theme: {
|
||||
preset: Aura
|
||||
}
|
||||
})
|
||||
|
||||
// Mount it
|
||||
app.mount('#app')
|
||||
|
|
|
@ -2,13 +2,13 @@ import { defineStore } from 'pinia'
|
|||
|
||||
export const useAppStore = defineStore('app', {
|
||||
state: () => ({
|
||||
errorText: '',
|
||||
errorText: false,
|
||||
modId: 0,
|
||||
modFile: '',
|
||||
messageText: '',
|
||||
modFile: false,
|
||||
messageText: false,
|
||||
mods: [],
|
||||
searchText: '',
|
||||
section: 'mods',
|
||||
searchText: false,
|
||||
servers: [],
|
||||
steamStatus: {appid: 0, installed: false, loggedIn: false, version: ''},
|
||||
})
|
||||
})
|
||||
|
|
18
web/index.js
18
web/index.js
|
@ -229,15 +229,27 @@ app.post(('/login'), async (req, res) => {
|
|||
let args = `+login "${username}" "${password}"`
|
||||
if (guard) args += ` "${guard}"`
|
||||
const result = await steamcmd(args)
|
||||
console.log(result)
|
||||
if (remember) {
|
||||
fs.writeFileSync(config.loginFile, username)
|
||||
}
|
||||
if (result) {
|
||||
fs.writeFileSync(config.loginFile, username)
|
||||
res.send(1)
|
||||
res.send({"ok": 1})
|
||||
} else {
|
||||
res.send(0)
|
||||
res.send({"ok": 0})
|
||||
}
|
||||
})
|
||||
|
||||
// Logout from Steam
|
||||
app.get(('/logout'), async (req, res) => {
|
||||
fs.unlink(config.loginFile, (err) => {
|
||||
if (err) {
|
||||
return res.send({"ok": 0, "error:": err})
|
||||
}
|
||||
res.send({"ok": 1})
|
||||
})
|
||||
})
|
||||
|
||||
// Get mod metadata by ID
|
||||
app.get('/mod/:modId', (req, res) => {
|
||||
const modId = req.params["modId"]
|
||||
|
|
241
web/package-lock.json
generated
241
web/package-lock.json
generated
|
@ -10,11 +10,16 @@
|
|||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@primevue/themes": "^4.0.2",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"pinia": "^2.2.0",
|
||||
"vue": "^3.4.34"
|
||||
"primeflex": "^3.3.1",
|
||||
"primeicons": "^7.0.0",
|
||||
"primevue": "^4.0.2",
|
||||
"vue": "^3.4.34",
|
||||
"vue-i18n": "^9.13.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.1.1",
|
||||
|
@ -403,6 +408,47 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/core-base": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz",
|
||||
"integrity": "sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==",
|
||||
"dependencies": {
|
||||
"@intlify/message-compiler": "9.13.1",
|
||||
"@intlify/shared": "9.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/message-compiler": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.13.1.tgz",
|
||||
"integrity": "sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==",
|
||||
"dependencies": {
|
||||
"@intlify/shared": "9.13.1",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/shared": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.13.1.tgz",
|
||||
"integrity": "sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
|
@ -417,6 +463,63 @@
|
|||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@primeuix/styled": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.0.5.tgz",
|
||||
"integrity": "sha512-pVoGn/uPkVm/DyF3TR3EmH/pL/dP4nR42FcYbVduFq9VfO3KVeOEqvcCULHXos66RZO9MCbCFUoLy6ctf9GUGQ==",
|
||||
"dependencies": {
|
||||
"@primeuix/utils": "^0.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primeuix/utils": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.0.5.tgz",
|
||||
"integrity": "sha512-ntUiUgtRtkF8KuaxHffzhYxQxoXk6LAPHm7CVlFjdqS8Rx8xRkLkZVyo84E+pO2hcNFkOGVP/GxHhQ2s94O8zA==",
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primevue/core": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.0.2.tgz",
|
||||
"integrity": "sha512-SpCIQ1LG6B66cecmZt1UdFeY7tbdJrgnhncADolfE9fcCyTSBtbaVLLhCV2E4Q9myMwCFE5KQxqazA4rdLWk4w==",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.0.5",
|
||||
"@primeuix/utils": "^0.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primevue/icons": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.0.2.tgz",
|
||||
"integrity": "sha512-S1VEpMsx4uUAsTjZtII03LQqgocYwSKbXMF0YDFWybY8r5LaHaveVZxS/i+KbsCLaL18BXJw0L/7L1eQdJHzaA==",
|
||||
"dependencies": {
|
||||
"@primeuix/utils": "^0.0.5",
|
||||
"@primevue/core": "4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@primevue/themes": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/themes/-/themes-4.0.2.tgz",
|
||||
"integrity": "sha512-DGrdFOWRUb8/qDX+Hjkg0SkU2hvo6EmEE5/fA/+NSlLAemj5fcR8r3wo9jhFMIU0QVNl17jZycuL5taU0H72BA==",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.1.tgz",
|
||||
|
@ -1737,6 +1840,30 @@
|
|||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/primeflex": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/primeflex/-/primeflex-3.3.1.tgz",
|
||||
"integrity": "sha512-zaOq3YvcOYytbAmKv3zYc+0VNS9Wg5d37dfxZnveKBFPr7vEIwfV5ydrpiouTft8MVW6qNjfkaQphHSnvgQbpQ=="
|
||||
},
|
||||
"node_modules/primeicons": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-7.0.0.tgz",
|
||||
"integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw=="
|
||||
},
|
||||
"node_modules/primevue": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/primevue/-/primevue-4.0.2.tgz",
|
||||
"integrity": "sha512-bf5In//ixosZDOcfJ0iaBXhtQSpNC/CuAOE2KHd/SgUKZdij3VRljQ+I9+Be/TTxfikIeKH7eZ4gzDbWiIZurw==",
|
||||
"dependencies": {
|
||||
"@primeuix/styled": "^0.0.5",
|
||||
"@primeuix/utils": "^0.0.5",
|
||||
"@primevue/core": "4.0.2",
|
||||
"@primevue/icons": "4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -2191,6 +2318,25 @@
|
|||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.13.1.tgz",
|
||||
"integrity": "sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==",
|
||||
"dependencies": {
|
||||
"@intlify/core-base": "9.13.1",
|
||||
"@intlify/shared": "9.13.1",
|
||||
"@vue/devtools-api": "^6.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -2360,6 +2506,29 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@intlify/core-base": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz",
|
||||
"integrity": "sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==",
|
||||
"requires": {
|
||||
"@intlify/message-compiler": "9.13.1",
|
||||
"@intlify/shared": "9.13.1"
|
||||
}
|
||||
},
|
||||
"@intlify/message-compiler": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.13.1.tgz",
|
||||
"integrity": "sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==",
|
||||
"requires": {
|
||||
"@intlify/shared": "9.13.1",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"@intlify/shared": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.13.1.tgz",
|
||||
"integrity": "sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ=="
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||
|
@ -2370,6 +2539,45 @@
|
|||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
|
||||
},
|
||||
"@primeuix/styled": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.0.5.tgz",
|
||||
"integrity": "sha512-pVoGn/uPkVm/DyF3TR3EmH/pL/dP4nR42FcYbVduFq9VfO3KVeOEqvcCULHXos66RZO9MCbCFUoLy6ctf9GUGQ==",
|
||||
"requires": {
|
||||
"@primeuix/utils": "^0.0.5"
|
||||
}
|
||||
},
|
||||
"@primeuix/utils": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.0.5.tgz",
|
||||
"integrity": "sha512-ntUiUgtRtkF8KuaxHffzhYxQxoXk6LAPHm7CVlFjdqS8Rx8xRkLkZVyo84E+pO2hcNFkOGVP/GxHhQ2s94O8zA=="
|
||||
},
|
||||
"@primevue/core": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/core/-/core-4.0.2.tgz",
|
||||
"integrity": "sha512-SpCIQ1LG6B66cecmZt1UdFeY7tbdJrgnhncADolfE9fcCyTSBtbaVLLhCV2E4Q9myMwCFE5KQxqazA4rdLWk4w==",
|
||||
"requires": {
|
||||
"@primeuix/styled": "^0.0.5",
|
||||
"@primeuix/utils": "^0.0.5"
|
||||
}
|
||||
},
|
||||
"@primevue/icons": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/icons/-/icons-4.0.2.tgz",
|
||||
"integrity": "sha512-S1VEpMsx4uUAsTjZtII03LQqgocYwSKbXMF0YDFWybY8r5LaHaveVZxS/i+KbsCLaL18BXJw0L/7L1eQdJHzaA==",
|
||||
"requires": {
|
||||
"@primeuix/utils": "^0.0.5",
|
||||
"@primevue/core": "4.0.2"
|
||||
}
|
||||
},
|
||||
"@primevue/themes": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@primevue/themes/-/themes-4.0.2.tgz",
|
||||
"integrity": "sha512-DGrdFOWRUb8/qDX+Hjkg0SkU2hvo6EmEE5/fA/+NSlLAemj5fcR8r3wo9jhFMIU0QVNl17jZycuL5taU0H72BA==",
|
||||
"requires": {
|
||||
"@primeuix/styled": "^0.0.5"
|
||||
}
|
||||
},
|
||||
"@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.1.tgz",
|
||||
|
@ -3286,6 +3494,27 @@
|
|||
"source-map-js": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"primeflex": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/primeflex/-/primeflex-3.3.1.tgz",
|
||||
"integrity": "sha512-zaOq3YvcOYytbAmKv3zYc+0VNS9Wg5d37dfxZnveKBFPr7vEIwfV5ydrpiouTft8MVW6qNjfkaQphHSnvgQbpQ=="
|
||||
},
|
||||
"primeicons": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-7.0.0.tgz",
|
||||
"integrity": "sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw=="
|
||||
},
|
||||
"primevue": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/primevue/-/primevue-4.0.2.tgz",
|
||||
"integrity": "sha512-bf5In//ixosZDOcfJ0iaBXhtQSpNC/CuAOE2KHd/SgUKZdij3VRljQ+I9+Be/TTxfikIeKH7eZ4gzDbWiIZurw==",
|
||||
"requires": {
|
||||
"@primeuix/styled": "^0.0.5",
|
||||
"@primeuix/utils": "^0.0.5",
|
||||
"@primevue/core": "4.0.2",
|
||||
"@primevue/icons": "4.0.2"
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
@ -3577,6 +3806,16 @@
|
|||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
|
||||
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
|
||||
"requires": {}
|
||||
},
|
||||
"vue-i18n": {
|
||||
"version": "9.13.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.13.1.tgz",
|
||||
"integrity": "sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==",
|
||||
"requires": {
|
||||
"@intlify/core-base": "9.13.1",
|
||||
"@intlify/shared": "9.13.1",
|
||||
"@vue/devtools-api": "^6.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,15 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@primevue/themes": "^4.0.2",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootstrap-icons": "^1.11.3",
|
||||
"pinia": "^2.2.0",
|
||||
"vue": "^3.4.34"
|
||||
"primeflex": "^3.3.1",
|
||||
"primeicons": "^7.0.0",
|
||||
"primevue": "^4.0.2",
|
||||
"vue": "^3.4.34",
|
||||
"vue-i18n": "^9.13.1"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue