[🏕️] Got to work with both frontend and backend

This commit is contained in:
Anthony 2022-11-22 15:54:06 +00:00
parent ca2adc1d28
commit 4a2512d103
42 changed files with 727 additions and 30 deletions

View File

@ -1,29 +1,211 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<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" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<meta content="Apexie's Hub" property="og:title" /> <head>
<meta <meta charset="UTF-8" />
content="We want to deliver the best experiences to you and create the best place to find new friends and play with your friends." <link rel="icon" type="image/png" href="/assets/img/favicon.png" />
property="og:description" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta content="https://apexie.eu" property="og:url" />
<meta content="https://apexie.eu/assets/img/favicon.png" property="og:image" />
<meta content="#1A9EF1" data-react-helmet="true" name="theme-color" />
<title>Apexie's Hub</title> <meta content="Apexie's Hub" property="og:title" />
</head> <meta
<body> content="We want to deliver the best experiences to you and create the best place to find new friends and play with your friends."
<div id="app"></div> property="og:description" />
<script type="module" src="/src/main.ts"></script> <meta content="https://apexie.eu" property="og:url" />
</body> <meta content="/assets/img/favicon.png" property="og:image" />
</html> <meta content="#1A9EF1" data-react-helmet="true" name="theme-color" />
<title>Apexie's Hub</title>
<link rel="stylesheet" href="/assets/css/style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.3/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-lg bg-dark navbar-dark py-3 fixed-top">
<div class="container">
<a class="navbar-brand" href="#">
<img src="assets/img/favicon.png" alt="" width="30" height="30" class="d-inline-block align-text-top">
Apexie's Home
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/apexiedev">GitHub</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://dsc.gg/apexie">Discord</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown"
aria-expanded="false">
Projects
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#osustream">osu!stream revived</a></li>
<li><a class="dropdown-item" href="#plenus">Plenus</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" href="https://video.arcade.apexie.eu">Video to
Arcade</a></li>
<li>
<a class="dropdown-item" href="https://poggit.pmmp.io/p/KnockbackFFA">Knock</a>
</li>
<li><a class="dropdown-item disabled" href="#">Coming soon...</a></li>
</ul>
</li>
<!-- Login button -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown"
aria-expanded="false">
Profile
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" id="login_button" data-bs-toggle="modal"
data-bs-target="#loginModal">Login</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item disabled" href="#">Coming soon...</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled">Coming soon...</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Login to the Apexie World</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="account-email" class="form-label">Email address</label>
<input type="email" class="form-control" id="account-email" aria-describedby="emailHelp">
<div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
</div>
<div class="mb-3">
<label for="account-password" class="form-label">Password</label>
<input type="password" class="form-control" id="account-password">
</div>
</form>
<div id="login-error"></div>
<ul id="login-list">
<li>Loading OAuth2 providers...</li>
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" id="account-register" class="btn btn-primary">Register</button>
<button type="submit" id="account-login" class="btn btn-primary">Login</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="fun" tabindex="-1" aria-labelledby="socials" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="funLabel">Start the fun</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p class="lead">These are the main places where we have fun:</p>
<!-- Clickable Discord button -->
<a href="https://dsc.gg/apexie" class="btn btn-dark btn-lg">
<i class="bi bi-discord"></i>
Discord
</a>
<a href="https://github.com/apexiedev" class="btn btn-dark btn-lg">
<i class="bi bi-github"></i>
GitHub
</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="sessionexpired" tabindex="-2" aria-labelledby="logintime" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="expiredLabel">Login expired</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p class="lead">Hi, it seems like your Discord session on this website has expired, would you like
to login again?</p>
</div>
<div class="modal-footer">
<!-- Yes -->
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="login-yes">
Yes
</button>
<!-- No -->
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="login-no">
No
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="login-dont-show">
Don't show this again
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="gdprconsent" tabindex="-2" aria-labelledby="gdpr" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="expiredLabel">GDPR Consent</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p class="lead">We use cookies in this website to give you the best experience on our
site. To find out more, read our
<a href="https://www.privacypolicygenerator.info/live.php?token=p519PrZBe1HRup8NtyGsCRpByyUSCDM1">privacy
policy</a> and <a
href="https://www.cookiepolicygenerator.com/live.php?token=4XCEj5MsPl1JX41C4R5NtaZ2fRotqRGv">cookie
policy.</a>
</p>
</div>
<div class="modal-footer">
<!-- Yes -->
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="gdpr-button">
Ok
</button>
</div>
</div>
</div>
</div>
<div id="main-app"></div>
<script type="module" src="/src/main.ts"></script>
<script type="module" src="/src/homepage.ts"></script>
</body>
</html>

View File

@ -9,7 +9,15 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"devDependencies": { "devDependencies": {
"@types/bootstrap": "^5.2.6",
"@types/jquery": "^3.5.14",
"bootstrap": "^5.2.3",
"pocketbase": "^0.8.0",
"sass": "^1.56.1",
"typescript": "^4.6.4", "typescript": "^4.6.4",
"vite": "^3.2.3" "vite": "^3.2.3"
},
"dependencies": {
"@popperjs/core": "^2.11.6"
} }
} }

View File

@ -1,12 +1,26 @@
lockfileVersion: 5.4 lockfileVersion: 5.4
specifiers: specifiers:
'@popperjs/core': ^2.11.6
'@types/bootstrap': ^5.2.6
'@types/jquery': ^3.5.14
bootstrap: ^5.2.3
pocketbase: ^0.8.0
sass: ^1.56.1
typescript: ^4.6.4 typescript: ^4.6.4
vite: ^3.2.3 vite: ^3.2.3
dependencies:
'@popperjs/core': 2.11.6
devDependencies: devDependencies:
'@types/bootstrap': 5.2.6
'@types/jquery': 3.5.14
bootstrap: 5.2.3_@popperjs+core@2.11.6
pocketbase: 0.8.0
sass: 1.56.1
typescript: 4.9.3 typescript: 4.9.3
vite: 3.2.4 vite: 3.2.4_sass@1.56.1
packages: packages:
@ -28,6 +42,68 @@ packages:
dev: true dev: true
optional: true optional: true
/@popperjs/core/2.11.6:
resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==}
/@types/bootstrap/5.2.6:
resolution: {integrity: sha512-BlAc3YATdasbHoxMoBWODrSF6qwQO/E9X8wVxCCSa6rWjnaZfpkr2N6pUMCY6jj2+wf0muUtLySbvU9etX6YqA==}
dependencies:
'@popperjs/core': 2.11.6
dev: true
/@types/jquery/3.5.14:
resolution: {integrity: sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==}
dependencies:
'@types/sizzle': 2.3.3
dev: true
/@types/sizzle/2.3.3:
resolution: {integrity: sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==}
dev: true
/anymatch/3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
dev: true
/binary-extensions/2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
dev: true
/bootstrap/5.2.3_@popperjs+core@2.11.6:
resolution: {integrity: sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==}
peerDependencies:
'@popperjs/core': ^2.11.6
dependencies:
'@popperjs/core': 2.11.6
dev: true
/braces/3.0.2:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
dependencies:
fill-range: 7.0.1
dev: true
/chokidar/3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
dependencies:
anymatch: 3.1.3
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.2
dev: true
/esbuild-android-64/0.15.15: /esbuild-android-64/0.15.15:
resolution: {integrity: sha512-F+WjjQxO+JQOva3tJWNdVjouFMLK6R6i5gjDvgUthLYJnIZJsp1HlF523k73hELY20WPyEO8xcz7aaYBVkeg5Q==} resolution: {integrity: sha512-F+WjjQxO+JQOva3tJWNdVjouFMLK6R6i5gjDvgUthLYJnIZJsp1HlF523k73hELY20WPyEO8xcz7aaYBVkeg5Q==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -238,6 +314,13 @@ packages:
esbuild-windows-arm64: 0.15.15 esbuild-windows-arm64: 0.15.15
dev: true dev: true
/fill-range/7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
dependencies:
to-regex-range: 5.0.1
dev: true
/fsevents/2.3.2: /fsevents/2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -250,6 +333,13 @@ packages:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: true dev: true
/glob-parent/5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
dev: true
/has/1.0.3: /has/1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'} engines: {node: '>= 0.4.0'}
@ -257,18 +347,51 @@ packages:
function-bind: 1.1.1 function-bind: 1.1.1
dev: true dev: true
/immutable/4.1.0:
resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==}
dev: true
/is-binary-path/2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
dependencies:
binary-extensions: 2.2.0
dev: true
/is-core-module/2.11.0: /is-core-module/2.11.0:
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
dependencies: dependencies:
has: 1.0.3 has: 1.0.3
dev: true dev: true
/is-extglob/2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
dev: true
/is-glob/4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
dev: true
/is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
dev: true
/nanoid/3.3.4: /nanoid/3.3.4:
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
dev: true dev: true
/normalize-path/3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
dev: true
/path-parse/1.0.7: /path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true dev: true
@ -277,6 +400,15 @@ packages:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true dev: true
/picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
dev: true
/pocketbase/0.8.0:
resolution: {integrity: sha512-LMuV46YcuG4bDZ1DNeUkvbaS5MWLZ1gpmccn6rYIg50n1bQ/BZJ9ip6SMJqo7xRGkPSL4kk1RP/zCkiG6g37Lg==}
dev: true
/postcss/8.4.19: /postcss/8.4.19:
resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
@ -286,6 +418,13 @@ packages:
source-map-js: 1.0.2 source-map-js: 1.0.2
dev: true dev: true
/readdirp/3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
dependencies:
picomatch: 2.3.1
dev: true
/resolve/1.22.1: /resolve/1.22.1:
resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
hasBin: true hasBin: true
@ -303,6 +442,16 @@ packages:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/sass/1.56.1:
resolution: {integrity: sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==}
engines: {node: '>=12.0.0'}
hasBin: true
dependencies:
chokidar: 3.5.3
immutable: 4.1.0
source-map-js: 1.0.2
dev: true
/source-map-js/1.0.2: /source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -313,13 +462,20 @@ packages:
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dev: true dev: true
/to-regex-range/5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
dependencies:
is-number: 7.0.0
dev: true
/typescript/4.9.3: /typescript/4.9.3:
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true
dev: true dev: true
/vite/3.2.4: /vite/3.2.4_sass@1.56.1:
resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
@ -348,6 +504,7 @@ packages:
postcss: 8.4.19 postcss: 8.4.19
resolve: 1.22.1 resolve: 1.22.1
rollup: 2.79.1 rollup: 2.79.1
sass: 1.56.1
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true

View File

@ -0,0 +1,45 @@
body::before {
display: block;
content: '';
height: 60px;
}
@media (min-width: 768px) {
.news-input {
width: 50%;
}
}
@media all and (min-width: 992px) {
.dropdown-menu li {
position: relative;
}
.nav-item .submenu {
display: none;
position: absolute;
left: 100%;
top: -7px;
}
.nav-item .submenu-left {
right: 100%;
left: auto;
}
.dropdown-menu>li:hover {
background-color: #f1f1f1
}
.dropdown-menu>li:hover>.submenu {
display: block;
}
}
@media (max-width: 991px) {
.dropdown-menu .dropdown-menu {
margin-left: 0.7rem;
margin-right: 0.7rem;
margin-bottom: .5rem;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

44
redirect.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OAuth2 redirect page</title>
</head>
<body>
<pre id="content">Authenticating...</pre>
<script src="https://cdn.jsdelivr.net/gh/pocketbase/js-sdk@master/dist/pocketbase.umd.js"></script>
<script type="text/javascript">
const pb = new PocketBase("https://imlighty-redesigned-enigma-75x56qwx6rhrv7v-8090.preview.app.github.dev/");
const redirectUrl = 'https://imlighty-redesigned-enigma-75x56qwx6rhrv7v-5173.preview.app.github.dev/redirect.html';
// parse the query parameters from the redirected url
const params = (new URL(window.location)).searchParams;
// load the previously stored provider's data
const provider = JSON.parse(localStorage.getItem('provider'))
// compare the redirect's state param and the stored provider's one
if (provider.state !== params.get('state')) {
throw "State parameters don't match.";
}
// authenticate
pb.collection('users').authWithOAuth2(
provider.name,
params.get('code'),
provider.codeVerifier,
redirectUrl,
// pass optional user create data
{
emailVisibility: false,
}
).then((authData) => {
// document.getElementById('content').innerText = JSON.stringify(authData, null, 2);
window.location = '/'
}).catch((err) => {
document.getElementById('content').innerText = "Failed to exchange code.\n" + err;
});
</script>
</body>
</html>

142
src/homepage.ts Normal file
View File

@ -0,0 +1,142 @@
import './scss/styles.scss'
document.querySelector<HTMLDivElement>('#main-app')!.innerHTML = `
<section class="bg-dark text-light p-5 p-lg-0 pt-lg-5 text-center text-sm-start">
<div class="container">
<div class="d-sm-flex align-items-center justify-content-between">
<div>
<h1>Join the <span class="text-warning"> best community ever </span></h1>
<p class="lead my-4">
We want to deliver the best experiences to you and
create the best place to find new friends and play with your friends.
</p>
<button class="btn btn-primary btn-lg" data-bs-toggle="modal" data-bs-target="#fun">
Start the fun
</button>
</div>
<img class="img-fluid w-50 d-none d-sm-block" width="477" height="517" src="assets/img/gaming.png"
alt="" />
</div>
</div>
</section>
<!-- Boxes -->
<section class="p-5">
<div class="container">
<div class="row text-center g-4">
<div class="col-md">
<div class="card bg-dark text-light">
<div class="card-body text-center">
<div class="h1 mb-3">
<i class="bi bi-controller"></i>
</div>
<h3 class="card-title mb-3">Gaming</h3>
<p class="card-text">
Our community mostly plays Minecraft, but we like to play other games too.
You can bring new games to life in our community.
</p>
<a href="https://dsc.gg/apexie" class="btn btn-primary">Join the fun</a>
</div>
</div>
</div>
<div class="col-md">
<div class="card bg-dark text-light">
<div class="card-body text-center">
<div class="h1 mb-3">
<i class="bi bi-chat-left-dots"></i>
</div>
<h3 class="card-title mb-3">Chatting</h3>
<p class="card-text">
We also have fun by chatting with other people
in the community. You can talk about anything you want (except, you know...).
</p>
<a href="https://dsc.gg/apexie" class="btn btn-primary">Chat with us</a>
</div>
</div>
</div>
<div class="col-md">
<div class="card bg-dark text-light">
<div class="card-body text-center">
<div class="h1 mb-3">
<i class="bi bi-code-square"></i>
</div>
<h3 class="card-title mb-3">Coding</h3>
<p class="card-text">
We love coding and also open source projects, and that's why we have a
GitHub page where we share most of our projects with you.
</p>
<a href="https://github.com/ApexieCommunity" class="btn btn-primary">Contribute</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Sections -->
<section id="osustream" class="p-5">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md">
<img src="assets/img/osu!stream.jpg" class="img-fluid" alt="" />
</div>
<div class="col-md p-5">
<h2>osu!stream revived</h2>
<p class="lead">
The best take on an osu!stream port
that you can find.
</p>
<p>
This project tries to make the best osu!stream port for Android. Since the source code is
available on GitHub,
we decided to fork the project and optimize it to support multiple feature and to fix some of
the issues of the
original project.
</p>
<a href="https://nightly.link/apexiedev/osu-restream/workflows/main/master/osurestream.zip"
class="btn btn-light mt-3">
<i class="bi bi-chevron-right"></i> Download
</a>
</div>
</div>
</div>
</section>
<section id="plenus" class="p-5 bg-dark text-light">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md p-5">
<h2>Plenus</h2>
<p class="lead">
The best Discord bot that you can find.
It's simple to use and also open source.
</p>
<p>
With Plenus, you can take your Discord server to another level. It offers features like
role buttons, music, moderation, logs, and more. Plenus is also open source, that means we make
money
only from donations from the <a href="https://ko-fi.com/plenus" class="link-primary">Ko-fi
page</a>.
</p>
<a href="https://plenusbot.xyz" class="btn btn-light mt-3">
<i class="bi bi-chevron-right"></i> Learn more
</a>
</div>
<div class="col-md">
<img src="https://raw.githubusercontent.com/ApexieCommunity/Plenus/main/assets/logo.png"
class="img-fluid" alt="" />
</div>
</div>
</div>
</section>
<footer class="p-5 bg-dark text-white text-center position-relative">
<div class="container">
<p class="lead">Copyright &copy; 2022 Apexie Community</p>
<a href="#" class="position-absolute bottom-0 end-0 p-5">
<i class="bi bi-arrow-up-circle h1"></i>
</a>
</div>
</footer>
`

View File

@ -1,4 +1,60 @@
import './style.css' import './scss/styles.scss'
import * as bootstrap from 'bootstrap'
import pocketbase from 'pocketbase'
document.querySelector<HTMLDivElement>('#app')!.innerHTML = ` const pb_url = 'https://imlighty-redesigned-enigma-75x56qwx6rhrv7v-8090.preview.app.github.dev/'
` const pb = new pocketbase(pb_url)
const redirectUrl = 'https://imlighty-redesigned-enigma-75x56qwx6rhrv7v-5173.preview.app.github.dev/redirect.html'
// Warning for users who open the DevTools console of the website
console.log("%cWARNING!!!" +
"\n\n%cThis console is meant to be used by developers to debug their code. If someone else tells you to open the DevTools and paste code here, please do not do so.",
"color: red; font-size: 30px;",
"color: black; font-size: 15px;")
let gdprConsent = localStorage.getItem("apexie-gdprconsent")!
let gdprConsentModal = new bootstrap.Modal(document.getElementById("gdprconsent")!)
async function loadLinks() {
const authMethods = await pb.collection('users').listAuthMethods()
const listItems: any = []
for (const provider of authMethods.authProviders) {
const $li = $(`<li><a>Login with ${provider.name}</a></li>`)
$li.find('a')
.attr('href', provider.authUrl + redirectUrl)
.data('provider', provider)
.on('click', function () {
// store provider's data on click for verification in the redirect page
localStorage.setItem('provider', JSON.stringify($(this).data('provider')))
})
listItems.push($li)
}
$('#login-list').html(listItems.length ? listItems : '<li>No OAuth2 providers.</li>')
}
document.getElementById('login_button')!.addEventListener('click', () => loadLinks())
let login_error = document.querySelector<HTMLDivElement>('#login-error')!
document.getElementById('account-login')!.addEventListener('click', async () => {
login_error.innerHTML = ''
await pb.collection('users').authWithPassword((<HTMLInputElement>document.getElementById('account-email')!).value, (<HTMLInputElement>document.getElementById('account-password')!).value).catch((err) => {
login_error.innerHTML = 'Failed to authenticate. Please try again.<p>'
document.querySelector<HTMLInputElement>('#account-password')!.value = ''
})
})
if (!gdprConsent) {
gdprConsentModal.show()
const gdprConsentButton = document.getElementById("gdpr-button")!
gdprConsentButton.addEventListener("click", () => {
localStorage.setItem("apexie-gdprconsent", "true")
gdprConsentModal.hide()
})
}

51
src/scss/styles.scss Normal file
View File

@ -0,0 +1,51 @@
@import "~bootstrap/scss/bootstrap";
body::before {
display: block;
content: '';
height: 60px;
}
@media (min-width: 768px) {
.news-input {
width: 50%;
}
}
@media all and (min-width: 992px) {
.dropdown-menu li {
position: relative;
}
.nav-item .submenu {
display: none;
position: absolute;
left: 100%;
top: -7px;
}
.nav-item .submenu-left {
right: 100%;
left: auto;
}
.dropdown-menu>li:hover {
background-color: #f1f1f1
}
.dropdown-menu>li:hover>.submenu {
display: block;
}
}
@media (max-width: 991px) {
.dropdown-menu .dropdown-menu {
margin-left: 0.7rem;
margin-right: 0.7rem;
margin-bottom: .5rem;
}
}
#login-error {
color: red;
}

View File

12
vite.config.js Normal file
View File

@ -0,0 +1,12 @@
import path from 'path'
export default {
resolve: {
alias: {
'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
}
},
server: {
cors: true
}
}