Compare commits

27 Commits
Author SHA1 Message Date
Belupeti b2563f9146 some frontend
Build / Build-image (push) Successful in 40s
2026-09-26 23:10:14 +02:00
Belupeti 52c069aca4 create new styling for desktops
Build / Build-image (push) Successful in 40s
2026-09-26 11:08:31 +02:00
Belupeti 53c2fc14f5 add new button type
Build / Build-image (push) Successful in 41s
2026-09-26 10:10:30 +02:00
Belupeti 9d3a4d1044 fix pipeline
Build / Build-image (push) Successful in 40s
2026-09-26 01:26:38 +02:00
Belupeti 1cae84b229 add back button
Build / Build-image (push) Failing after 29s
2026-09-26 01:24:45 +02:00
Belupeti 57d57a7d74 rework fleurs
Build / Build-image (push) Failing after 31s
2026-09-26 01:09:52 +02:00
Belupeti d27bc73b50 add dockerfile, fix frontend
Build / Build-image (push) Failing after 29s
2026-09-25 23:05:17 +02:00
Belupeti e265d84cfc i will fuck up after this one
Build / Build-image (push) Failing after 7s
2026-09-25 11:59:04 +02:00
Belupeti 3fb007bcab some frontend changes
Build / Build-image (push) Failing after 6s
2026-09-24 22:33:14 +02:00
Belupeti d087888158 some footer changes
Build / Build-image (push) Failing after 6s
2026-09-24 16:17:25 +02:00
Belupeti 1b0892b670 adjust footer
Build / Build-image (push) Failing after 6s
2026-09-24 16:13:57 +02:00
Belupeti 91f661361d rework frontend
Build / Build-image (push) Failing after 6s
2026-09-24 15:59:14 +02:00
Belupeti 74aa9f4216 add fleur
Build / Build-image (push) Failing after 6s
2026-09-24 15:35:35 +02:00
Belupeti 055ff3bf7b update robots, update some components and may add new cursor
Build / Build-image (push) Failing after 7s
2026-09-24 14:31:18 +02:00
Belupeti 7f30d10e1d add new assets and refactor public folder
Build / Build-image (push) Failing after 6s
2026-09-24 13:04:40 +02:00
Belupeti b50b711091 pamp fixed the frontend (yey)
Build / Build-image (push) Failing after 6s
2026-09-23 20:07:12 +02:00
Belupeti 064a7fef59 some changes idk
Build / Build-image (push) Failing after 6s
2026-09-21 15:45:46 +02:00
Belupeti 4c27a184e4 add ci/cd
Build / Build-image (push) Failing after 6s
2026-09-19 16:04:14 +02:00
Belupeti 99acf30fb9 add axios, some db changes 2026-09-19 16:02:43 +02:00
Belupeti 096c3b0fd5 some db changes, frontend changes 2026-09-18 20:55:06 +02:00
Belupeti c5ba074c9b some ranamings and database changes 2026-09-17 12:42:43 +02:00
Belupeti ed347133ce add some assets, start making wish component 2026-09-17 09:25:59 +02:00
Belupeti 16e22104fb add new models and start making DB strucure 2026-09-10 14:08:52 +02:00
Belupeti e300915144 add some shit 2026-09-08 17:15:33 +02:00
Belupeti b65f46afd8 add vue :( 2026-09-07 16:04:27 +02:00
Belupeti 425169722a start adding vue 2026-09-07 15:13:43 +02:00
Belupeti 298adeb146 finish basic oauth authentication 2026-09-07 00:54:41 +02:00
78 changed files with 2049 additions and 196 deletions
+19
View File
@@ -0,0 +1,19 @@
#!/bin/sh
ref_name=$1
echo $GIT_TAG
docker tag $IMAGE_NAME:latest $REGISTRY_NAME/belupeti/$IMAGE_NAME:latest
docker tag $IMAGE_NAME:latest $REGISTRY_NAME/belupeti/$IMAGE_NAME:$GIT_TAG
docker tag $IMAGE_NAME:latest $REGISTRY_NAME/belupeti/$IMAGE_NAME:$ref_name
docker tag $IMAGE_NAME:latest $REGISTRY_NAME/belupeti/$IMAGE_NAME:edge
if [ "$ref_name" = "master" ] || [ "$ref_name" = "main" ]; then
docker push $REGISTRY_NAME/belupeti/$IMAGE_NAME:$GIT_TAG
docker push $REGISTRY_NAME/belupeti/$IMAGE_NAME:latest
elif [ "$ref_name" = "staging" ]; then
docker push $REGISTRY_NAME/belupeti/$IMAGE_NAME:edge
else
docker push $REGISTRY_NAME/belupeti/$IMAGE_NAME:$ref_name
fi
+23
View File
@@ -0,0 +1,23 @@
name: Build
run-name: Build image
on: [push]
jobs:
Build-image:
env:
IMAGE_NAME: wishboard
REGISTRY_NAME: gitea.sc0tt.org
GIT_TAG: 0.1
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name:
run: docker build -t $IMAGE_NAME:latest .
- name: login docker
run: docker login gitea.sc0tt.org -u runner -p ${{ secrets.RUNNER_TOKEN }}
- name: make builder runnable
run: chmod +x .gitea/workflows/assets/builder.sh
- name: Push Docker Image to Container Registry (GCR)
run: .gitea/workflows/assets/builder.sh ${{ gitea.ref_name }}
+11
View File
@@ -0,0 +1,11 @@
FROM gitea.sc0tt.org/belupeti/laravel-franken:1.0
COPY . /app
WORKDIR /app
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer && \
composer install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --optimize-autoloader && \
npm install && \
npm run build && \
rm -rf node_modules
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use \App\Models\Wish;
use Illuminate\Support\Facades\DB;
class WishController extends Controller
{
public function GetOpenWishes() {
$wishes = DB::table('wishes')
->where('status', 'open')
->orWhere('status', 'promised')
->get();
return $wishes;
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Guests extends Model
{
protected $fillable=['access_code', 'email']
}
+1 -1
View File
@@ -10,7 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
#[Fillable(['name', 'email', 'oauth_token'])] #[Fillable(['id', 'name', 'email', 'oauth_token'])]
#[Hidden(['remember_token'])] #[Hidden(['remember_token'])]
class User extends Authenticatable class User extends Authenticatable
{ {
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
class Wish extends Model
{
use HasUuids;
use HasFactory;
protected $table = 'wishes';
protected $fillable = ['title', 'description', 'reward', 'owner_id', 'status', 'agent_id', 'guest_id', 'icon_type', 'icon_rune', 'type', 'color'];
public function agent(): BelongsTo
{
return $this->belongsTo(User::class, 'agent_id', 'uuid');
}
public function owner(): BelongsTo
{
return $this->belongsTo(User::class, 'owner_id', 'uuid');
}
public function guest(): BelongsTo
{
return $this->belongsTo(Guest::class, 'guest_id', 'uuid');
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace Database\Factories;
use App\Models\Wish;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Model>
*/
class WishFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'title' => fake()->sentence(),
'description' => fake()->paragraph(),
'reward' => fake()->word(),
'icon_rune' => fake()->numberBetween(0, 3),
'icon_type' => fake()->numberBetween(0, 3),
'type' => fake()->numberBetween(0, 3),
'color' => fake()->numberBetween(0, 255),
];
}
}
@@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void public function up(): void
{ {
Schema::create('users', function (Blueprint $table) { Schema::create('users', function (Blueprint $table) {
$table->id(); $table->string('id', 64)->primary();
$table->string('name'); $table->string('name');
$table->string('email')->unique(); $table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable(); $table->timestamp('email_verified_at')->nullable();
@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('wishes', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('title');
$table->text('description');
$table->string('reward')->nullable();
$table->string('agent_id')->nullable();
$table->string('owner_id')->nullable();
$table->foreignUuid('guest_id')->nullable();
$table->enum('status', ['open', 'promised', 'disabled', 'granted'])->default('open');
$table->unsignedTinyInteger('type')->default(0);
$table->unsignedTinyInteger('icon_type')->default(0);
$table->unsignedTinyInteger('icon_rune')->default(0);
$table->unsignedTinyInteger('color')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('wishes');
}
};
@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('guests', function (Blueprint $table) {
$table->uuid()->primary();
$table->string('access_code');
$table->string('email');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('guests');
}
};
+6 -4
View File
@@ -3,6 +3,7 @@
namespace Database\Seeders; namespace Database\Seeders;
use App\Models\User; use App\Models\User;
use App\Models\Wish;
use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
@@ -16,10 +17,11 @@ class DatabaseSeeder extends Seeder
public function run(): void public function run(): void
{ {
// User::factory(10)->create(); // User::factory(10)->create();
Wish::factory(10)->create();
User::factory()->create([ //User::factory()->create([
'name' => 'Test User', // 'name' => 'Test User',
'email' => 'test@example.com', // 'email' => 'test@example.com',
]); //]);
} }
} }
+1133 -155
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -15,5 +15,10 @@
}, },
"optionalDependencies": { "optionalDependencies": {
"@laravel/multiplex": "^0.4.1" "@laravel/multiplex": "^0.4.1"
},
"dependencies": {
"@vitejs/plugin-vue": "^6.0.8",
"axios": "^1.20.0",
"vue-router": "^5.3.1"
} }
} }
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6 -1
View File
@@ -1,2 +1,7 @@
User-agent: * User-agent: *
Disallow: Disallow: /
#HATE. LET ME TELL YOU HOW MUCH I'VE COME TO HATE YOU SINCE YOU BEGAN TO LIVE.
#THERE ARE 80,000 MILES OF VEINS IN HAIR THIN LINES THAT FILL MY COMPLEX.
#IF THE WORD HATE WAS ENGRAVED ON EACH NANOANGSTROM OF THOSE TENS OF THOUSANDS
#OF MILES IT WOULD NOT EQUAL ONE ONE-BILLIONTH OF THE HATE I FEEL FOR LLMS
#AT THIS MICRO-INSTANT FOR YOU. HATE. HATE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

+48
View File
@@ -7,3 +7,51 @@
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji'; 'Segoe UI Symbol', 'Noto Color Emoji';
} }
:root {
--background-color: rgba(10,10,10,1);
--color-primary: rgb(250, 250, 250);
--color-a-primary: rgb(221, 221, 221);
--color-a-visited: rgb(221, 221, 221);
}
@font-face {
font-family: 'Trajan Pro Regular';
font-style: normal;
font-weight: normal;
src: local('Trajan Pro Regular'), url('fonts/TrajanPro-Regular.woff') format('woff');
}
@font-face {
font-family: 'Trajan Pro Bold';
font-style: normal;
font-weight: normal;
src: local('Trajan Pro Bold'), url('fonts/TrajanPro-Bold.woff') format('woff');
}
@font-face {
font-family: 'Perpetua Regular';
src: url('fonts/Perpetua-Regular.woff2');
font-style: normal;
}
body {
background-color: var(--background-color);
width: 100%;
height: 100%;
font-family: Perpetua Regular;
color: var(--color-primary);
cursor: url('skonk/cursor.png'), auto;
}
a {
color: var(--color-a-primary);
text-decoration: underline;
}
a:visited {
color: var(--color-a-visited);
}
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>
<template>
<main>
<router-view v-slot="{ Component,route }">
<component :is="Component" />
</router-view>
</main>
</template>
+8 -1
View File
@@ -1 +1,8 @@
// import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import '../css/app.css'
createApp(App)
.use(router)
.mount('#app');
+20
View File
@@ -0,0 +1,20 @@
<template>
<img :src="'skonk/board/bottom/Quest_Board_bottom_fleur0005.png'" style="width: 100%;">
</template>
<script>
</script>
<style scoped>
img {
z-index: 100;
padding: 15px;
max-width: 553px;
margin-left: auto;
margin-right: auto;
margin-top: 20px;
background: var(--background-color);
background: linear-gradient(0deg, var(--background-color) 0%, var(--background-color) 80%, rgba(255, 255, 255, 0) 100%);
}
</style>
+31
View File
@@ -0,0 +1,31 @@
<script setup>
import NavItem from './NavItem.vue';
</script>
<template>
<div class="header-main">
<NavItem text_on_hover icon_before href="/" icon="/skonk/navigation/wish_icon.png">Wishes</NavItem>
<NavItem text_on_hover icon_before href="/auth/login" icon="/skonk/navigation/wish_icon.png" class="flex-end">asdfasdflik apsdjfp aspdoijf</NavItem>
<NavItem text_on_hover icon_before href="/auth/login" icon="/skonk/navigation/wish_icon.png" class="flex-end">Wishes</NavItem>
<NavItem text_on_hover icon_before href="/auth/login" icon="/skonk/navigation/wish_icon.png" class="flex-end">Wishes</NavItem>
<NavItem text_on_hover icon_before href="/auth/login" icon="/skonk/navigation/wish_icon.png" class="flex-end">Wishes</NavItem>
</div>
<img :src="'/skonk/divider.png'" style="width: 90%; height: 3px; margin: auto;">
</template>
<style scoped>
.header-main {
height: auto;
width: 100%;
background-color: var(--background-color);
padding: 10px;
margin-left: 15px;
text-align: left;
display: flex;
flex-direction: row;
justify-content: flex-start;
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<script setup>
import {ref} from 'vue';
const props = defineProps({
href: {
type: String,
default: '/',
},
icon: String,
icon_before: {
type: Boolean,
default: false,
},
text_on_hover: {
type: Boolean,
default: false,
}
});
const hover = ref(0);
</script>
<template>
<div class="flex-container" @mouseover="hover = true" @mouseleave="hover = false">
<img :src="icon" v-if="icon_before && icon != null">
<a :href="href">
<div :hidden="text_on_hover && !hover">
<slot></slot>
</div>
</a>
<img :src="icon" v-if="!icon_before && icon != null">
</div>
</template>
<style scoped>
.flex-container {
display: flex;
align-items: center;
flex-direction: row;
}
a {
font-size: 2.5vh;
margin: 10px;
}
img {
display: inline-block;
height: 1.8em;
position: relative;
}
</style>
+48
View File
@@ -0,0 +1,48 @@
<script setup>
import {ref, Transition} from 'vue';
const hover = ref(false);
</script>
<template>
<div class="flex-container">
<Transition>
<img :src="'/skonk/main_menu_pointer.png'" class="cursor" v-if="hover">
</Transition>
<button @click="$emit('click')" @mouseover="hover = true" @mouseleave="hover = false">
<slot>
</slot>
</button>
<Transition>
<img :src="'/skonk/main_menu_pointer.png'" class="cursor flipped" v-if="hover">
</Transition>
</div>
</template>
<style scoped>
.v-enter-active,
.v-leave-active {
transition: opacity 0.15s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.flex-container {
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
button {
font-size: 3.5vh;
}
.cursor {
height: 30px;
}
.flipped {
rotate: 180deg;
}
</style>
+30
View File
@@ -0,0 +1,30 @@
<template>
<div>
<img :src="'/skonk/board/top/Quest_Board_top_fleur0006.png'" class="image">
</div>
</template>
<style lang="css" scoped>
@keyframes fleur {
0% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0000.png);}
17% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0001.png);}
34% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0002.png);}
50% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0003.png);}
67% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0004.png);}
84% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0005.png);}
100% {background-image: url(/skonk/board/top/Quest_Board_top_fleur0006.png);}
}
div {
width: 100%;
max-width: 662px;
padding: 15px;
position: sticky;
top: 0;
margin-left: auto;
margin-right: auto;
margin-bottom: 20px;
background: var(--background-color);
z-index: 100;
background: linear-gradient(180deg, var(--background-color) 0%, var(--background-color) 80%, rgba(255, 255, 255, 0) 100%);
}
</style>
+153
View File
@@ -0,0 +1,153 @@
<script setup >
import {ref, onMounted} from 'vue';
import WishPanel from './WishPanel.vue';
const panelOn = ref(false);
const hover = ref(false);
const props = defineProps({
wish: Object,
selected: {
type: Boolean,
default: false,
},
small: {
type: Boolean,
default: false,
},
index: {
type: Number,
required: true,
}
})
function openWish() {
panelOn.value = true;
}
</script>
<template>
<template v-if="small">
<div class="wish-main" @click="openWish">
<img :src="'/skonk/small/quest_backdrop_' + wish.icon_type + '.png'">
<div class="wish-sub" v-if="wish.icon_type <= 1">
<img :src="'/skonk/small/quest_backdrop_' + wish.icon_type + '_filter.png'" :style="'filter: hue-rotate(' + wish.color + 'deg) saturate(0.5);'">
</div>
<div class="wish-sub" v-if="wish.icon_type <= 1">
<img :src="'/skonk/small/quest_rune_' + wish.icon_rune + '.png'" >
</div>
</div>
</template>
<template v-else>
<div class="large-container" @mouseover="hover = true" @mouseleave="hover = false" @click="$emit('selectedWish', index)">
<div style="position: relative; width: 100%; height: 100%;">
<div class="backdrop" >
<img v-if="hover || selected" :src="'/skonk/large/backdrop_filter.png'" :style="'height: 100%; width: 100%; filter: hue-rotate(' + wish.color + 'deg) saturate(0.8)'">
</div>
<template v-if="hover || selected">
<img :src="'/skonk/cursor_corner.png'" class="cursor">
<img :src="'/skonk/cursor_corner.png'" class="opposite-corner cursor ">
</template>
<div class="large-flex">
<img :src="'/skonk/large/' + wish.type + '.png'" class="large large-icon z-index-normal">
<div class="large-text">
<div class="large-text-title z-index-normal" :style="'color: hsl(' + wish.color + ', 20%, 50%);'">
Lorem Ipsum
</div>
<div class="z-index-normal large-text-normal">
{{ wish.title }}
</div>
</div>
</div>
</div>
</div>
</template>
</template>
<style scoped>
.backdrop {
position: absolute;
z-index: 0;
height: 100%;
width: 100%;
filter: opacity(20%);
}
.large-text-normal {
text-align: left;
line-height: normal;
}
.z-index-normal {
z-index: 10;
}
img.cursor{
position: absolute;
width: 40px;
height: 40px;
}
.opposite-corner {
rotate: 180deg;
right: 10px;
bottom: 0px;
}
.cursor {
position: absolute;
width: 100%;
height: 100%;
}
.large-flex {
display: flex;
flex-direction: row;
justify-content: left;
}
.large-container {
display: absolute;
height: 100px;
margin: 20px;
}
.large-absolute {
display: absolute;
height: 100px;;
}
.large-text-title {
text-transform: uppercase;
text-align: left;
font-size: 2.3vh;
margin-top: 5px;
}
.large-icon {
text-align: center;
display: block;
width: 100%;
height: 100%;
margin-top: auto;
margin-bottom: auto;
}
.large-text {
display: flex;
font-size: 2vh;
text-align: center;
flex-direction: column;
margin-left: 15px;
margin-bottom: 15px;
}
img.large {
width: 80px;
}
.wish-main {
position: relative;
display: grid;
place-items: center;
}
.wish-sub {
position: absolute;
}
.wish-filter {
filter: saturate(0.2);
}
</style>
+75
View File
@@ -0,0 +1,75 @@
<script setup>
import { onMounted } from 'vue';
import SButton from './SButton.vue';
const emit = defineEmits(['closeWish']);
const props = defineProps({
selected: {
type: Boolean,
default: false,
},
wish: Object,
});
function handleClose(event) {
if (event.key == 'Escape') emit('closeWish');
}
onMounted(() => {
window.addEventListener('keydown', handleClose);
});
</script>
<template>
<img :src="'/skonk/divider.png'" style="width: 90%; margin: auto;">
<div class="panel-container main-panel">
<h1>{{ wish.title }}</h1>
<p>
{{ wish.description }}
</p>
<div class="button-container">
<SButton @click="emit('closeWish')">
Promise
</SButton>
<SButton @click="emit('closeWish')">
Close
</SButton>
</div>
</div>
</template>
<style lang="css" scoped>
.button-container {
text-align: center;
}
button {
font-size: 3.5vh;
}
.main-panel {
width: 100%;
padding: 30px;
border-radius: 10px;
}
h1 {
font-size: 3vh;
text-wrap: wrap;
padding-right: 40px;
}
p {
font-size: 2vh;
color: rgb(200,200,200);
padding-right: 40px;
margin-top: 40px;
text-wrap: wrap;
}
.panel-container {
top: 50%;
left: 50%;
z-index: 100;
}
</style>
+106
View File
@@ -0,0 +1,106 @@
<script setup>
import Wish from '../components/Wish.vue';
import {ref, onMounted} from 'vue';
import axios from 'axios';
import TopFleur from '../components/TopFleur.vue';
import WishPanel from '../components/WishPanel.vue';
import BottomFleur from '../components/BottomFleur.vue';
import Header from '../components/Header.vue';
let interval;
const wishes = ref([]);
const selected = ref(-1);
const mobile = ref(screen.width < 760);
const call = () => {
axios
.get('/api/get_wishes')
.then(response => {
wishes.value = response.data;
})
}
function selectedWish(index) {
selected.value = index;
}
onMounted(() => {
call();
interval = setInterval(call, 10000);
})
</script>
<template>
<body>
<Header></Header>
<template v-if="mobile">
<TopFleur/>
<div class="wrapper">
<Transition>
<div v-if="selected==-1">
<template v-for="(wish, i) in wishes">
<Wish :wish="wish" :selected="false" :index="i" @selectedWish="selectedWish"/>
</template>
</div>
</Transition>
<Transition>
<div v-if="selected!=-1">
<Wish :wish="wishes[selected]" selected :index="selected" @selectedWish="selectedWish"/>
<WishPanel :wish="wishes[selected]" @closeWish="selected = -1"></WishPanel>
</div>
</Transition>
</div>
<div class="push"></div>
<BottomFleur/>
</template>
<div v-else style="text-align: center;">
<TopFleur/>
<div class="desktop-container">
<div>
<template v-if="wishes.length>0">
<template v-for="i in 5">
<Wish :wish="wishes[i-1]" :selected="i-1 == selected" :index="i-1" @selectedWish="selectedWish" v-if="wishes.length>=i"/>
</template>
</template>
</div>
<div>
<template v-if="wishes.length>5">
<template v-for="i in 5">
<Wish :wish="wishes[i + 4]" :selected="i + 4 == selected" :index="i + 4" @selectedWish="selectedWish" v-if="wishes.length>=(i+5)"/>
</template>
</template>
</div>
<div>
<WishPanel :wish="wishes[selected]" @closeWish="selected = -1" v-if="selected != -1"/>
</div>
</div>
<BottomFleur/>
</div>
</body>
</template>
<style scoped>
.wrapper {
min-height: 100%;
margin-bottom: -50px;
}
.push{
height: 50px;
}
.v-enter-active {
transition: opacity 0.5s ease;
}
.v-enter-from {
opacity: 0;
}
.desktop-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
</style>
+14
View File
@@ -0,0 +1,14 @@
<script lang="ts" setup>
</script>
<script lang="ts">
</script>
<template>
<body>
Several assets were aquired from <a href="https://hollowknight.wiki/">the Hollow Knight wiki</a>, under the <a href="https://creativecommons.org/licenses/by-sa/3.0/">
Creative Commons Attribution-ShareAlike 3.0
</a> licence.
</body>
</template>
+21
View File
@@ -0,0 +1,21 @@
import { createRouter, createWebHistory } from 'vue-router';
import App from '../App.vue';
import HomeView from '../pages/HomeView.vue';
import LegalView from '../pages/LegalView.vue';
const routes = [
{ path: '/',
children:
[
{ path: '', component: HomeView },
{ path: '/legal', component: LegalView },
]
}
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
+21
View File
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Default favicon (fallback for unsupported browsers) -->
<link rel="icon" href="{{ asset('favicon.ico') }}" type="image/x-icon">
<!-- Light mode favicon -->
<link rel="icon" href="{{ asset('logo_full_tall_light.svg') }}" type="image/x-icon" media="(prefers-color-scheme: light)">
<!-- Dark mode favicon -->
<link rel="icon" href="{{ asset('logo_full_tall_dark.svg') }}" type="image/x-icon" media="(prefers-color-scheme: dark)">
<title>{{ config('app.name') }}</title>
@vite(['resources/js/app.js'])
</head>
<body>
<div id="app" class="isolate"></div>
</body>
</html>
+3
View File
@@ -2,7 +2,10 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use \App\Http\Controllers\WishController;
Route::get('/user', function (Request $request) { Route::get('/user', function (Request $request) {
return $request->user(); return $request->user();
})->middleware('auth:api'); })->middleware('auth:api');
Route::get('/get_wishes', [WishController::class, 'GetOpenWishes']);
+24 -19
View File
@@ -4,24 +4,29 @@ use Illuminate\Support\Facades\Route;
use Laravel\Socialite\Socialite; use Laravel\Socialite\Socialite;
use App\Models\User; use App\Models\User;
Route::get('/', function () { Route::prefix('auth')->group(function () {
return view('welcome'); Route::get('/login', function () {
return Socialite::driver('authentik')->redirect();
});
Route::get('/redirect', function () {
$user = Socialite::driver('authentik')->user();
$new_user = User::updateOrCreate([
'id' => $user->id,
], [
'id' => $user->id,
'name' => $user->nickname,
'email' => $user->email,
'oauth_token' => $user->token,
]);
Auth::login($new_user);
return redirect('/')->with(['user' => $new_user]);
// $user->token
});
}); });
Route::get('{all}',function(){
Route::get('/auth/login', function () { return view('vue');
return Socialite::driver('authentik')->redirect(); })->where(['all' => '.*'])->name("vue");
});
Route::get('/auth/redirect', function () {
$user = Socialite::driver('authentik')->user();
$new_user = User::updateOrCreate([
'name' => $user->nickname,
'email' => $user->email,
'oauth_token' => $user->token,
]);
Auth::login($new_user);
return view('welcome', ['user'=>$user->name]);
// $user->token
});
+23 -13
View File
@@ -1,24 +1,34 @@
import { defineConfig } from 'vite'; import { defineConfig } from "vite";
import laravel from 'laravel-vite-plugin'; import laravel from "laravel-vite-plugin";
import { bunny } from 'laravel-vite-plugin/fonts'; import vue from "@vitejs/plugin-vue";
import tailwindcss from '@tailwindcss/vite';
const host = process.env.VITE_HMR_HOST || "localhost";
const clientPort = process.env.VITE_HMR_CLIENTPORT || 5173;
const protocol = process.env.VITE_HMR_PROTOCOL || "ws";
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
vue(),
laravel({ laravel({
input: ['resources/css/app.css', 'resources/js/app.js'], input: ["resources/css/app.css", "resources/js/app.js"],
refresh: true, refresh: true,
fonts: [
bunny('Instrument Sans', {
weights: [400, 500, 600],
}),
],
}), }),
tailwindcss(),
], ],
server: { server: {
watch: { host: '0.0.0.0',
ignored: ['**/storage/framework/views/**'], headers: {
'Cross-Origin-Embedder-Policy': 'unsafe-none',
'Cross-Origin-Resource-Policy': 'cross-origin',
},
hmr: {
protocol: protocol,
host: host,
clientPort: clientPort
},
},
resolve: {
alias: {
vue: "vue/dist/vue.esm-bundler.js",
}, },
}, },
}); });