Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2563f9146 | ||
|
|
52c069aca4 | ||
|
|
53c2fc14f5 | ||
|
|
9d3a4d1044 | ||
|
|
1cae84b229 | ||
|
|
57d57a7d74 | ||
|
|
d27bc73b50 | ||
|
|
e265d84cfc | ||
|
|
3fb007bcab | ||
|
|
d087888158 | ||
|
|
1b0892b670 | ||
|
|
91f661361d | ||
|
|
74aa9f4216 | ||
|
|
055ff3bf7b | ||
|
|
7f30d10e1d | ||
|
|
b50b711091 | ||
|
|
064a7fef59 | ||
|
|
4c27a184e4 | ||
|
|
99acf30fb9 | ||
|
|
096c3b0fd5 | ||
|
|
c5ba074c9b | ||
|
|
ed347133ce | ||
|
|
16e22104fb | ||
|
|
e300915144 | ||
|
|
b65f46afd8 | ||
|
|
425169722a | ||
|
|
298adeb146 |
@@ -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
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Guests extends Model
|
||||
{
|
||||
protected $fillable=['access_code', 'email']
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
#[Fillable(['name', 'email', 'oauth_token'])]
|
||||
#[Fillable(['id', 'name', 'email', 'oauth_token'])]
|
||||
#[Hidden(['remember_token'])]
|
||||
class User extends Authenticatable
|
||||
{
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('id', 64)->primary();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$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');
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Wish;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
@@ -16,10 +17,11 @@ class DatabaseSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
Wish::factory(10)->create();
|
||||
|
||||
User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
]);
|
||||
//User::factory()->create([
|
||||
// 'name' => 'Test User',
|
||||
// 'email' => 'test@example.com',
|
||||
//]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,5 +15,10 @@
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@laravel/multiplex": "^0.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^6.0.8",
|
||||
"axios": "^1.20.0",
|
||||
"vue-router": "^5.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
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.
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 137 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 183 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 783 B |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 964 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 909 B |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -7,3 +7,51 @@
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI 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);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<router-view v-slot="{ Component,route }">
|
||||
<component :is="Component" />
|
||||
</router-view>
|
||||
</main>
|
||||
|
||||
</template>
|
||||
@@ -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');
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use \App\Http\Controllers\WishController;
|
||||
|
||||
Route::get('/user', function (Request $request) {
|
||||
return $request->user();
|
||||
})->middleware('auth:api');
|
||||
|
||||
Route::get('/get_wishes', [WishController::class, 'GetOpenWishes']);
|
||||
@@ -4,24 +4,29 @@ use Illuminate\Support\Facades\Route;
|
||||
use Laravel\Socialite\Socialite;
|
||||
use App\Models\User;
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
|
||||
|
||||
Route::get('/auth/login', function () {
|
||||
Route::prefix('auth')->group(function () {
|
||||
Route::get('/login', function () {
|
||||
return Socialite::driver('authentik')->redirect();
|
||||
});
|
||||
});
|
||||
|
||||
Route::get('/auth/redirect', function () {
|
||||
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 view('welcome', ['user'=>$user->name]);
|
||||
return redirect('/')->with(['user' => $new_user]);
|
||||
// $user->token
|
||||
});
|
||||
});
|
||||
|
||||
Route::get('{all}',function(){
|
||||
return view('vue');
|
||||
})->where(['all' => '.*'])->name("vue");
|
||||
|
||||
@@ -1,24 +1,34 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
import { bunny } from 'laravel-vite-plugin/fonts';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { defineConfig } from "vite";
|
||||
import laravel from "laravel-vite-plugin";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
|
||||
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({
|
||||
plugins: [
|
||||
vue(),
|
||||
laravel({
|
||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||
input: ["resources/css/app.css", "resources/js/app.js"],
|
||||
refresh: true,
|
||||
fonts: [
|
||||
bunny('Instrument Sans', {
|
||||
weights: [400, 500, 600],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
tailwindcss(),
|
||||
],
|
||||
server: {
|
||||
watch: {
|
||||
ignored: ['**/storage/framework/views/**'],
|
||||
host: '0.0.0.0',
|
||||
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",
|
||||
},
|
||||
},
|
||||
});
|
||||