Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/phil frontend #532

Merged
merged 13 commits into from
Oct 29, 2023
20 changes: 20 additions & 0 deletions app/Http/Controllers/DashboardAdminRandomGeneratorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,24 @@ public function indexExecuteSubmit(): JsonResponse
'success' => true,
]);
}

/*
* Display the dashboard admin random generator display page
*/
public function display(): Response
{
// get all users except tutors and admins
$users = User::doesntHave('roles')->with('course')->get()->map(function ($user) {
$user->avatarUrl = $user->avatarUrl();

return $user;
});

// shuffle the users
$users = $users->shuffle();

return Inertia::render('Dashboard/Admin/RandomGenerator/Display', [
'users' => $users,
]);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/random-generator/gifs/cat.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/random-generator/gifs/trumpet.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/sounds/random-generator/airhorn.mp3
Binary file not shown.
Binary file added public/sounds/random-generator/running.mp3
Binary file not shown.
2 changes: 2 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import url('https://fonts.cdnfonts.com/css/eighty-miles');
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved

@tailwind base;
@tailwind components;
@tailwind utilities;
Expand Down
31 changes: 31 additions & 0 deletions resources/js/components/card/Avatar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
<div
class="flex h-fit w-[30rem] items-center justify-center border-[16px] border-white bg-[url('/images/random-generator/background/comic-blue.jpg')] bg-cover bg-center"
>
<img v-if="props.src" :src="props.src" class="h-fit" />
<div
v-else
class="flex h-[30rem] transform items-center justify-center text-center font-['EIGHTY_MILES'] text-8xl text-white"
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
>
{{ props.firstname }} <br />
{{ props.lastname }}
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
</div>
</div>
</template>

<script setup lang="ts">
const props = defineProps({
src: {
type: String,
required: false,
},
firstname: {
type: String,
required: true,
},
lastname: {
type: String,
required: true,
},
});
</script>
7 changes: 7 additions & 0 deletions resources/js/layouts/RandomGeneratorLayout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<div class="flex h-full flex-col bg-slate-950">
<div class="flex-grow">
<slot />
</div>
</div>
</template>
172 changes: 172 additions & 0 deletions resources/js/pages/Dashboard/Admin/RandomGenerator/Display.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<template>
<div>
<div
class="h-screen bg-[url('/images/random-generator/background/comic-yellow.jpg')] bg-cover"
>
<div v-if="generatorState.state === 'setup'" class="flex h-screen">
<div
class="m-auto rounded-full bg-gradient-to-r from-pink-600 to-purple-600 bg-clip-text font-['EIGHTY_MILES'] text-[15rem] text-transparent"
>
ZuFHallsgenerator
</div>
</div>
<div
v-if="generatorState.state === 'idle'"
class="flex h-screen w-screen flex-col"
></div>
<Transition>
<div
v-if="generatorState.state === 'running'"
class="flex h-screen w-screen flex-col overflow-hidden"
>
<div class="h-screen flex-1 overflow-hidden">
<div
class="grid h-fit w-screen animate-fly justify-items-center space-y-32 overflow-hidden pt-20"
>
<Avatar
class="animate-wiggle"
v-for="user in users"
:src="user.avatarUrl"
:firstname="user.firstname"
:lastname="user.lastname"
/>
</div>
<audio autoplay>
<source
src="/sounds/random-generator/running.mp3"
type="audio/mpeg"
/>
</audio>
<img
class="absolute left-[10%] top-1/2 h-1/3 -translate-y-1/2 transform"
src="/images/random-generator/gifs/cat.gif"
/>
<img
class="absolute right-[10%] top-1/2 h-1/3 -translate-y-1/2 scale-x-[-1] transform"
src="/images/random-generator/gifs/cat.gif"
/>
</div>
</div>
</Transition>

<Transition name="winner">
<div
v-if="generatorState.state === 'stopped'"
class="flex h-screen items-center justify-center"
>
<Avatar
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
class="scale-[130%]"
:src="generatorState.user?.avatarUrl"
:firstname="generatorState.user?.firstname"
:lastname="generatorState.user?.lastname"
/>
<audio autoplay>
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
<source
src="/sounds/random-generator/airhorn.mp3"
type="audio/mpeg"
/>
</audio>
<img
class="absolute left-0 top-1/2 h-2/3 -translate-y-1/2 transform"
src="/images/random-generator/gifs/trumpet.gif"
/>
<img
class="absolute right-0 top-1/2 h-2/3 -translate-y-1/2 scale-x-[-1] transform"
src="/images/random-generator/gifs/trumpet.gif"
/>
</div>
</Transition>
</div>
</div>
</template>

<style>
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease;
}

.v-enter-from,
.v-leave-to {
opacity: 0;
}

.winner-enter-active {
transition: opacity 2s ease;
transition-delay: 2s;
}

.winner-leave-active {
transition: opacity 0.1s ease;
}

.winner-enter-from,
.winner-leave-to {
opacity: 0;
}
</style>

<script lang="ts">
import RandomGeneratorLayout from "@/layouts/RandomGeneratorLayout.vue";

export default {
layout: RandomGeneratorLayout,
};
</script>

<script setup lang="ts">
import { ref, PropType, onBeforeUnmount, render, createElement } from "vue";
import Avatar from "@/components/card/Avatar.vue";

const props = defineProps({
users: {
type: Array as PropType<App.Models.User[]>,
required: true,
},
});

// locale state variables
const generatorState = ref<{
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
state: "setup" | "idle" | "running" | "stopped";
user?: Models.User;
}>({
state: "setup",
});

const isFetchingGenerator = ref(false);
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved

// functions
const fetchRandomGeneratorState = async () => {
if (isFetchingGenerator.value) {
return;
}

isFetchingGenerator.value = true;

const response = await fetch("/api/random-generator/state", {
method: "GET",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
});

if (response.ok) {
const data = await response.json();

if (generatorState.value.state != "running" && data.state == "running") {
props.users.sort(() => Math.random() - 0.5);
}

generatorState.value = data;
}

isFetchingGenerator.value = false;
};

const generatorInterval = setInterval(fetchRandomGeneratorState, 500);
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved

onBeforeUnmount(() => {
clearInterval(generatorInterval);
});
</script>
2 changes: 2 additions & 0 deletions resources/js/types/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare module "vue" {
AppMessage: typeof import("./../components/app/Message.vue")["default"];
AppNavbar: typeof import("./../components/app/Navbar.vue")["default"];
BoxContainer: typeof import("./../components/box/Container.vue")["default"];
CardAvatar: typeof import("./../components/card/Avatar.vue")["default"];
CardBase: typeof import("./../components/card/Base.vue")["default"];
CardContainer: typeof import("./../components/card/Container.vue")["default"];
CardLayout: typeof import("./../layouts/CardLayout.vue")["default"];
Expand All @@ -29,6 +30,7 @@ declare module "vue" {
GridContainer: typeof import("./../components/grid/Container.vue")["default"];
GroupTable: typeof import("./../components/group/Table.vue")["default"];
LayoutDashboardContent: typeof import("./../components/layout/DashboardContent.vue")["default"];
RandomGeneratorLayout: typeof import("./../layouts/RandomGeneratorLayout.vue")["default"];
RegistrationTable: typeof import("./../components/registration/Table.vue")["default"];
SlotTable: typeof import("./../components/slot/Table.vue")["default"];
UiDateString: typeof import("./../components/ui/DateString.vue")["default"];
Expand Down
1 change: 1 addition & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
], function () {
Route::get('/random-generator', [DashboardAdminRandomGeneratorController::class, 'index'])->name('dashboard.admin.randomGenerator.index');
Route::post('/random-generator', [DashboardAdminRandomGeneratorController::class, 'indexExecuteSubmit'])->name('dashboard.admin.randomGenerator.indexExecuteSubmit');
Route::get('/random-generator/display', [DashboardAdminRandomGeneratorController::class, 'display'])->name('');
PhilPinsdorf marked this conversation as resolved.
Show resolved Hide resolved
});
});

Expand Down
23 changes: 23 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** @type {import('tailwindcss').Config} */

const defaultTheme = require("tailwindcss/defaultTheme");

module.exports = {
Expand All @@ -12,6 +13,28 @@ module.exports = {
darkMode: "class",
theme: {
extend: {
keyframes: {
wiggle: {
"0%, 100%": {
transform: "rotate(-15deg)",
},
"50%": {
transform: "rotate(15deg)",
},
},
fly: {
from: {
transform: "translateY(100vh)",
},
to: {
transform: "translateY(-100%)",
},
},
},
animation: {
wiggle: "wiggle 2s ease-in-out infinite",
fly: "fly 75s infinite linear alternate",
},
colors: {
fhac: {
mint: "#00b5ad",
Expand Down