Initial commit

This commit is contained in:
root
2026-05-09 17:28:23 +02:00
commit 9d73f82529
5575 changed files with 281989 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
<x-app-layout>
@push('title', __('Welcome to the best hotel on the web!'))
<div class="col-span-12 md:col-span-6 min-h-[250px] bg-gray-900/50 rounded-xl flex flex-col py-6 px-8 text-white">
<h2 class="text-2xl">{{ __('Login') }}</h2>
<form action="{{ route('login') }}" method="POST">
@csrf
<div class="relative w-full overflow-hidden text-black">
<input id="username-input" type="text" placeholder="{{ __('Enter your username') }}" name="username" class="relative py-2 rounded-md mt-3 w-full">
<img id="user-avatar" class="absolute right-0 -top-4" src="{{ asset('/assets/images/dusk/ghost.png') }}" alt="">
</div>
<input type="password" placeholder="{{ __('Enter your password') }}" name="password" class="relative py-2 rounded-md mt-3 text-black w-full">
<x-site-captchas />
<div class="mt-4 flex gap-4">
<button type="submit" class="py-2 px-4 text-white bg-yellow-500 border-2 border-yellow-300 w-full rounded-md transition duration-300 ease-in-out hover:scale-[102%]">{{ __('Login') }}</button>
<a href="{{ route('register') }}" class="w-full">
<button type="button" class="py-2 px-4 text-white bg-gray-700 border-2 border-gray-600 w-full rounded-md transition duration-300 ease-in-out hover:scale-[102%]">{{ __('Register') }}</button>
</a>
</div>
</form>
</div>
{{-- Articles --}}
<div class="col-span-12 md:col-span-6 h-[250px]">
<!-- Slider main container -->
<div class="swiper h-[250px] rounded-md">
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- Additional required wrapper -->
<div class="swiper-wrapper" style="z-index: 14;">
@foreach($articles as $article)
<x-article-card :article="$article" />
@endforeach
</div>
</div>
</div>
<div class="col-span-12 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
@foreach($photos as $photo)
<a href="{{ $photo->url }}" data-fancybox="gallery" class="cursor-pointer relative transition duration-300 ease-in-out hover:scale-[102%]">
<div class="photo-overlay"></div>
<img class="h-[250px] w-full object-cover object-center rounded-md custom-shadow" src="{{ $photo->url }}" alt="">
<div class="absolute right-2 bottom-2 bg-black/70 p-2 rounded-md text-white flex gap-x-2 z-[5]">
<img class="self-center" src="{{ asset('/assets/images/dusk/author_camera_icon.png') }}" alt="">
<small>
{{ $photo->user->username }}
</small>
</div>
</a>
@endforeach
</div>
<script>
function debounce(func, wait) {
let timeout;
return function() {
const context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
const avatar = document.getElementById('user-avatar');
const usernameInput = document.getElementById('username-input');
const updateAvatar = debounce(async () => {
const username = usernameInput.value;
if (!username) return;
try {
const response = await fetch(`/api/user/${username}`);
if (!response.ok) {
console.error('Failed to fetch avatar');
return;
}
const data = await response.json();
if (!data.data.look) {
avatar.src = "/assets/images/dusk/ghost.png";
return;
}
avatar.src = '{{ setting('avatar_imager') }}' + '/' + data.data.look + '&direction=4&action=wav&head_direction=3';
} catch (error) {
console.error('An error occurred:', error);
}
}, 200);
usernameInput.addEventListener('keyup', updateAvatar);
</script>
</x-app-layout>
@@ -0,0 +1,53 @@
<x-app-layout>
@push('title', __('Two factor'))
<div class="col-span-12 flex flex-col gap-y-3 md:col-span-3">
<x-user.settings.settings-navigation />
</div>
<div class="col-span-12 flex flex-col gap-y-3 md:col-span-9">
<x-content.content-card icon="hotel-icon" classes="border dark:border-gray-900">
<x-slot:title>
{{ __('Confirm your password') }}
</x-slot:title>
<x-slot:under-title>
{{ __('You must confirm your password to continue') }}
</x-slot:under-title>
<form method="POST" action="/user/confirm-password">
@csrf
<!-- Password -->
<div class="flex flex-col gap-y-2 mb-3">
<div>
<x-form.label for="password">
{{ __('Password') }}
<x-slot:info>
{{ __('You must confirm your current password before being able to toggle 2FA.') }}
</x-slot:info>
</x-form.label>
<x-form.input name="password" type="password"
placeholder="{{ __('Enter your current password') }}" />
</div>
</div>
@if (setting('google_recaptcha_enabled'))
<div class="mt-4 g-recaptcha" data-sitekey="{{ config('habbo.site.recaptcha_site_key') }}"></div>
@endif
@if (setting('cloudflare_turnstile_enabled'))
<x-turnstile />
@endif
<div class="mt-4">
<x-form.primary-button>
{{ __('Confirm password') }}
</x-form.primary-button>
</div>
</form>
</x-content.content-card>
</div>
</x-app-layout>
@@ -0,0 +1,40 @@
<x-app-layout>
@push('title', __('Forgot password'))
<div class="col-span-12">
<x-content.content-card icon="hotel-icon" classes="max-w-[640px] mx-auto">
<x-slot:title>
{{ __('Did you forget your password?') }}
</x-slot:title>
<x-slot:under-title>
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
</x-slot:under-title>
<form method="POST" action="{{ route('forgot.password.post') }}">
@csrf
<!-- Email Address -->
<div>
<div class="flex flex-col gap-y-2">
<x-form.label for="mail">
{{ __('Email') }}
<x-slot:info>
{{ __('Enter your email') }}
</x-slot:info>
</x-form.label>
</div>
<x-form.input name="mail" type="email" placeholder="{{ __('Enter your email') }}"/>
</div>
<div class="mt-4">
<x-form.primary-button>
{{ __('Email Password Reset Link') }}
</x-form.primary-button>
</div>
</form>
</x-content.content-card>
</div>
</x-app-layout>
+50
View File
@@ -0,0 +1,50 @@
<x-app-layout>
@push('title', __('Reset Password'))
<div class="col-span-12">
<x-content.content-card icon="hotel-icon" classes="max-w-[640px] mx-auto">
<x-slot:title>
{{ __('Reset Password') }}
</x-slot:title>
<x-slot:under-title>
{{ __('Choose a new password for your Account.') }}
</x-slot:under-title>
<form method="POST" action="{{ route('reset.password.post', $token) }}">
@csrf
<!-- Password -->
<div class="bg-[#efefef] rounded-md p-3 flex flex-col gap-y-6 dark:bg-gray-900">
<div>
<x-form.label for="password">
{{ __('Password') }}
<x-slot:info>
{{ __('Your password must contain atleast 8 characters. Make sure to use a unique & secure password.') }}
</x-slot:info>
</x-form.label>
<x-form.input name="password" type="password" placeholder="{{ __('Choose a secure password') }}"/>
</div>
<hr class="dark:border-gray-700">
<!-- Confirm Password -->
<div>
<x-form.label for="password_confirmation">
{{ __('Repeat Password') }}
</x-form.label>
<x-form.input name="password_confirmation" type="password" placeholder="{{ __('Repeat your chosen password') }}"/>
</div>
</div>
<div class="mt-4">
<x-form.primary-button>
{{ __('Reset Password') }}
</x-form.primary-button>
</div>
</form>
</x-content.content-card>
</div>
</x-app-layout>
+188
View File
@@ -0,0 +1,188 @@
<x-app-layout>
@push('title', __('Welcome to the best hotel on the web!'))
<div class="col-span-12 md:col-span-6 bg-gray-900/50 rounded-xl flex flex-col py-6 px-8 text-white self-start">
<h2 class="text-2xl">{{ __('Create a new account') }}</h2>
<form action="{{ route('register') }}" method="POST">
@csrf
<div class="grid grid-cols-12 gap-3 mt-4">
<div class="relative w-full overflow-hidden text-black col-span-12">
<input id="username-input" type="text" placeholder="Enter your username" name="username" value="{{ old('username') }}" class="relative py-2 rounded-md w-full" required>
</div>
<div class="relative w-full overflow-hidden text-black col-span-12">
<input id="username-input" type="email" placeholder="Enter your e-mail" name="mail" value="{{ old('mail') }}" class="relative py-2 rounded-md w-full" required>
</div>
<div class="col-span-12">
<input type="password" placeholder="Enter your password" name="password" class="relative py-2 rounded-md text-black w-full" required>
</div>
<div class="col-span-12">
<input type="password" placeholder="Confirm your password" name="password_confirmation" class="relative py-2 rounded-md text-black w-full" required>
</div>
@if (setting('requires_beta_code'))
<div class="col-span-12">
<input type="text" placeholder="Beta code" name="beta_code" class="relative py-2 rounded-md text-black w-full" required>
</div>
@endif
<div class="col-span-12 mt-2">
<label class="text-sm text-white mb-1 block">{{ __('Choose avatar') }}</label>
<div class="grid grid-cols-5 gap-1">
@php
$femaleFigures = array_slice(array_filter(array_map('trim', explode(',', setting('register_female_figures', 'hr-100-45.hd-180-1.ch-215-62.lg-270-62.sh-290-62,hr-130-45.hd-180-2.ch-220-62.lg-270-62.sh-305-62,hr-140-45.hd-180-3.ch-225-62.lg-270-62.sh-310-62,hr-165-45.hd-180-1.ch-210-62.lg-270-62.sh-290-62,hr-190-45.hd-180-2.ch-215-62.lg-270-62.sh-305-62')))), 0, 5);
$maleFigures = array_slice(array_filter(array_map('trim', explode(',', setting('register_male_figures', 'hr-100-61.hd-180-1.ch-210-66.lg-270-110.sh-305-62,hr-105-61.hd-190-2.ch-215-66.lg-280-110.sh-310-62,hr-110-61.hd-200-3.ch-220-66.lg-290-110.sh-320-62,hr-115-61.hd-185-1.ch-210-66.lg-275-110.sh-315-62,hr-120-61.hd-180-2.ch-205-66.lg-285-110.sh-305-62')))), 0, 5);
$allFigures = array_merge($femaleFigures, $maleFigures);
@endphp
@foreach($allFigures as $index => $figure)
<label class="cursor-pointer relative group">
<input type="radio" name="look" value="{{ $figure }}"
class="peer sr-only" {{ $index === 5 ? 'checked' : '' }}>
<div class="p-0.5 rounded border-2 border-gray-600
peer-checked:border-yellow-400 peer-checked:bg-yellow-400/20
hover:border-gray-500 transition-all duration-300
peer-checked:scale-110 peer-checked:shadow-lg peer-checked:shadow-yellow-400/30"
onmouseover="this.querySelector('img').src='https://www.habbo.nl/habbo-imaging/avatarimage?figure={{ $figure }}&size=s&action=wav'"
onmouseout="if(!this.previousElementSibling.checked) this.querySelector('img').src='https://www.habbo.nl/habbo-imaging/avatarimage?figure={{ $figure }}&size=s'">
<img src="https://www.habbo.nl/habbo-imaging/avatarimage?figure={{ $figure }}&size=s"
class="w-full h-auto transition-transform duration-300" alt="Avatar">
</div>
</label>
@endforeach
</div>
</div>
</div>
<div class="flex items-center gap-x-3 mt-2">
<input id="terms" type="checkbox" name="terms"
class="mt-1 rounded ring-0 focus:ring-0">
<a href="{{ route('help-center.rules.index') }}" target="_blank"
class="mt-1 text-sm font-semibold text-white hover:text-gray-900 hover:underline hover:text-gray-200">
{{ __('I accept the :hotel terms & rules.', ['hotel' => setting('hotel_name')]) }}
</a>
</div>
{{-- Used to determine the refer --}}
<input type="hidden" name="referral_code" value="{{ $referral_code }}">
<x-site-captchas />
<div class="mt-4 grid grid-cols-2 gap-3">
<button type="submit" class="py-2 px-4 text-white bg-yellow-500 border-2 border-yellow-300 w-full rounded-md transition duration-300 ease-in-out hover:scale-[102%]">{{ __('Register') }}</button>
<a href="{{ route('login') }}" class="w-full">
<button type="button" class="py-2 px-4 text-white bg-gray-700 border-2 border-gray-600 w-full rounded-md transition duration-300 ease-in-out hover:scale-[102%]">{{ __('Back to login') }}</button>
</a>
</div>
</form>
</div>
{{-- Articles --}}
<div class="col-span-12 md:col-span-6 ">
<!-- Slider main container -->
<div class="swiper h-[250px] rounded-md">
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- Additional required wrapper -->
<div class="swiper-wrapper" style="z-index: 14;">
@foreach($articles as $article)
<div class="swiper-slide relative article-image" style="background-image: url({{ $article->image }})">
<div class="absolute h-[90px] w-full left-0 bottom-0 bg-[#171a23]/95 text-white py-2 px-4">
<h2 class="text-3xl font-bold">
{{ $article->title }}
</h2>
<div class="flex justify-between items-center">
<div class="py-1 px-2 rounded-md bg-black/60 text-sm mt-2 flex gap-1 items-center">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
</svg>
{{ $article->user->username }}
</div>
<a href="{{ route('article.show', $article->slug) }}" class="text-sm read-more-link hover:underline">
Read more
</a>
</div>
</div>
</div>
@endforeach
</div>
</div>
<div class="col-span-12 grid grid-cols-1 sm:grid-cols-2 gap-4 mt-4">
@foreach($photos as $photo)
<a href="{{ $photo->url }}" data-fancybox="gallery" class="cursor-pointer relative transition duration-300 ease-in-out hover:scale-[102%]">
<div class="photo-overlay"></div>
<img class="h-[250px] w-full object-cover object-center rounded-md custom-shadow" src="{{ $photo->url }}" alt="">
<div class="absolute right-2 bottom-2 bg-black/70 p-2 rounded-md text-white flex gap-x-2 z-[5]">
<img class="self-center" src="{{ asset('/assets/images/dusk/author_camera_icon.png') }}" alt="">
<small>
{{ $photo->user->username }}
</small>
</div>
</a>
@endforeach
</div>
</div>
<script>
function debounce(func, wait) {
let timeout;
return function() {
const context = this, args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
const avatar = document.getElementById('user-avatar');
const usernameInput = document.getElementById('username-input');
const updateAvatar = debounce(async () => {
const username = usernameInput.value;
if (!username) return;
try {
const response = await fetch(`/api/user/${username}`);
if (!response.ok) {
console.error('Failed to fetch avatar');
return;
}
const data = await response.json();
if (!data.data.look) {
avatar.src = "/assets/images/dusk/ghost.png";
return;
}
avatar.src = '{{ setting('avatar_imager') }}' + '/' + data.data.look + '&direction=4&action=wav&head_direction=3';
} catch (error) {
console.error('An error occurred:', error);
}
}, 200);
usernameInput.addEventListener('keyup', updateAvatar);
</script>
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@4.0/dist/fancybox.umd.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.css" />
</x-app-layout>
@@ -0,0 +1,57 @@
<x-app-layout>
@push('title', __('Two-Factor Authentication'))
<div class="col-span-12 flex flex-col gap-y-3 md:col-span-9 md:col-start-4">
<x-content.content-card icon="hotel-icon" classes="border dark:border-gray-900">
<x-slot:title>
{{ __('Two-Factor Authentication') }}
</x-slot:title>
<x-slot:under-title>
{{ __('Please enter your two-factor authentication code or one of your recovery codes.') }}
</x-slot:under-title>
@if (session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
<form method="POST" action="{{ route('two-factor.login') }}">
@csrf
<!-- Two-Factor Code -->
<div>
<x-form.label for="code">
{{ __('Code') }}
<x-slot:info>
{{ __('Enter the two-factor authentication code from your authenticator app.') }}
</x-slot:info>
</x-form.label>
<x-form.input id="code" name="code" type="text" placeholder="{{ __('Code') }}" class="mb-3" />
</div>
<!-- Recovery Code -->
<div class="mt-4">
<x-form.label for="recovery_code">
{{ __('Recovery Code') }}
<x-slot:info>
{{ __('Enter one of your recovery codes if you cannot access your authenticator app.') }}
</x-slot:info>
</x-form.label>
<x-form.input id="recovery_code" name="recovery_code" type="text" placeholder="{{ __('Recovery Code') }}" class="mb-3" />
</div>
@if (setting('google_recaptcha_enabled'))
<div class="g-recaptcha" data-sitekey="{{ config('habbo.site.recaptcha_site_key') }}"></div>
@endif
@if (setting('cloudflare_turnstile_enabled'))
<x-turnstile />
@endif
<x-form.secondary-button type="submit" class="mt-4">
{{ __('Verify') }}
</x-form.secondary-button>
</form>
</x-content.content-card>
</div>
</x-app-layout>
+35
View File
@@ -0,0 +1,35 @@
<x-guest-layout>
<div class="flex flex-col items-center min-h-screen pt-6 bg-gray-100 sm:justify-center sm:pt-0">
<div class="w-full px-6 py-4 mt-6 overflow-hidden bg-white shadow-md sm:max-w-md sm:rounded-lg">
<div class="mb-4 text-sm text-gray-600">
{{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
</div>
@if (session('status') == 'verification-link-sent')
<div class="mb-4 text-sm font-medium text-green-600">
{{ __('A new verification link has been sent to the email address you provided during registration.') }}
</div>
@endif
<div class="flex items-center justify-between mt-4">
<form method="POST" action="{{ route('verification.send') }}">
@csrf
<div>
<button type="submit" class="inline-flex items-center px-4 py-2 ml-4 text-xs font-semibold tracking-widest text-white uppercase transition duration-150 ease-in-out bg-gray-800 border border-transparent rounded-md hover:bg-gray-700 active:bg-gray-900 focus:outline-hidden focus:border-gray-900 focus:ring-3 ring-gray-300 disabled:opacity-25">
{{ __('Resend Verification Email') }}
</button>
</div>
</form>
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="text-sm text-gray-600 underline hover:text-gray-900">
{{ __('Log Out') }}
</button>
</form>
</div>
</div>
</div>
</x-guest-layout>