Compare commits

...
Sign in to create a new pull request.

6 commits

Author SHA1 Message Date
Vincent BRIDIER
b10377bd43 Merge branch 'bugs-fix' into 'main'
fix: multiple bugs #1

See merge request ldc-web/projets/gen-game-web-themes/default-theme!3
2025-08-06 06:38:19 +00:00
Corentin Huet
0d76607889 fix: multiple bugs 2025-08-05 15:58:48 +02:00
Vincent BRIDIER
94049ba518 Merge branch 'newsletters' into 'main'
Added the newsletter field in the footer

See merge request ldc-web/projets/gen-game-web-themes/default-theme!2
2025-06-27 07:35:56 +00:00
Vincent BRIDIER
b42d8f3bd4 Merge branch 'fix-header-count' into 'main'
fix header counter

See merge request ldc-web/projets/gen-game-web-themes/default-theme!1
2025-06-27 07:35:32 +00:00
Noah Lancien
ee86923ac2 Added the newsletter field in the footer 2024-05-06 18:02:23 +02:00
Jérémy Munsch
c2c9fa87e8
fix header counter 2024-01-23 15:16:54 +01:00
12 changed files with 141 additions and 73 deletions

View file

@ -41,53 +41,4 @@ document.addEventListener("DOMContentLoaded", function () {
});
}, 300);
}
const scrollTop = (target: string, offset: number = 0) => {
const targetElement = document.getElementById(target);
if (!targetElement) throw new Error(`scrollTop requires ${target} to exist`);
const top = targetElement.getBoundingClientRect().top,
t = window.scrollY + top - offset;
scrollTo({
top: t,
behavior: "smooth"
});
};
const pageUp = document.getElementById("page-up");
if (pageUp) {
pageUp.addEventListener("click", () => scrollTop("content-container", 250)),
document.addEventListener("scroll", () => {
if (window.scrollY > 250) {
pageUp.classList.add("show");
return;
}
pageUp.classList.remove("show");
});
}
});
// * Input Validation.
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll("input.is-invalid").forEach((input) => {
let timer: NodeJS.Timeout|null = null;
input.addEventListener("change", () => {
const parent = input.parentElement;
input.classList.remove("is-invalid");
if (parent && parent.classList.contains("is-invalid")) {
parent.classList.remove("is-invalid");
}
});
input.addEventListener("input", () => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
const parent = input.parentElement;
input.classList.remove("is-invalid");
if (parent && parent.classList.contains("is-invalid")) {
parent.classList.remove("is-invalid");
}
}, 250);
});
});
});

View file

@ -10,6 +10,11 @@ import "./utilities/vue-fo";
// CUSTOM
import "./base/common";
// PARTIALS
import "./partials/input-errors-removal";
import "./partials/newsletter";
import "./partials/scroll-to-top";
// PAGES
import "./pages/home";
import "./pages/products";

View file

@ -0,0 +1,25 @@
// * Input Validation.
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll("input.is-invalid").forEach((input) => {
let timer: NodeJS.Timeout|null = null;
input.addEventListener("change", () => {
const parent = input.parentElement;
input.classList.remove("is-invalid");
if (parent && parent.classList.contains("is-invalid")) {
parent.classList.remove("is-invalid");
}
});
input.addEventListener("input", () => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
const parent = input.parentElement;
input.classList.remove("is-invalid");
if (parent && parent.classList.contains("is-invalid")) {
parent.classList.remove("is-invalid");
}
}, 250);
});
});
});

49
ts/partials/newsletter.ts Normal file
View file

@ -0,0 +1,49 @@
import route from "../../../../ts/modules/route";
const laravelRoute = route.methods.route;
document.addEventListener("DOMContentLoaded", function () {
// * NEWSLETTERS
// Subscribe to newsletter
const newsletterSubmitBtn = document.getElementById("newsletter-submit");
const newsletterEmailInput = document.getElementById("newsletter-email") as HTMLInputElement;
const newsletterMessageDiv = document.getElementById("newsletter-message");
if (newsletterSubmitBtn && newsletterEmailInput && newsletterMessageDiv) {
// Submit the request
newsletterSubmitBtn.addEventListener("click", function () {
// Reset error field
newsletterMessageDiv.classList.remove("bg-success-subtle", "border-success", "text-success");
newsletterMessageDiv.classList.remove("bg-danger-subtle", "border-danger", "text-danger");
newsletterMessageDiv.textContent = "";
const addSingleOptinRoute = laravelRoute("fo.add-single-optin");
if (addSingleOptinRoute === null) {
return;
}
window.axios.post(addSingleOptinRoute, {
email: newsletterEmailInput.value,
})
.then(function (response) {
newsletterMessageDiv.classList.remove("d-none");
newsletterMessageDiv.classList.add("bg-success-subtle", "border-success", "text-success");
newsletterMessageDiv.textContent = String(response.data);
newsletterEmailInput.value = "";
})
.catch(function (error) {
newsletterMessageDiv.classList.remove("d-none");
newsletterMessageDiv.classList.add("bg-danger-subtle", "border-danger", "text-danger");
if (error.response.status == 422) {
const errors = error.response.data.errors;
for (const errorKey in errors) {
const errorP = document.createElement("p");
errorP.classList.add("m-0");
errorP.textContent = errors[errorKey];
newsletterMessageDiv.appendChild(errorP);
}
} else {
newsletterMessageDiv.textContent = error.response.data;
}
});
});
}
});

View file

@ -0,0 +1,25 @@
// * Scroll to top button.
document.addEventListener("DOMContentLoaded", function () {
const scrollTop = (target: string, offset: number = 0) => {
const targetElement = document.getElementById(target);
if (!targetElement) throw new Error(`scrollTop requires ${target} to exist`);
const top = targetElement.getBoundingClientRect().top,
t = window.scrollY + top - offset;
scrollTo({
top: t,
behavior: "smooth"
});
};
const pageUp = document.getElementById("page-up");
if (pageUp) {
pageUp.addEventListener("click", () => scrollTop("content-container", 250)),
document.addEventListener("scroll", () => {
if (window.scrollY > 250) {
pageUp.classList.add("show");
return;
}
pageUp.classList.remove("show");
});
}
});

View file

@ -4,7 +4,7 @@
{!! nl2br(
clean(
__(
"Le mot de passe doit avoir une longueur de 8 caractères minimum,\n doit contenir une lettre majuscule et une lettre minucule,\n doit contenir un caractère spécial comme une virgule par exemple,\n doit contenir un chiffre.",
"Le mot de passe doit avoir une longueur de 8 caractères minimum,\n doit contenir une lettre majuscule et une lettre minuscule,\n doit contenir un caractère spécial comme une virgule par exemple,\n doit contenir un chiffre.",
),
),
) !!}

View file

@ -0,0 +1,12 @@
{{-- Newsletter form --}}
<div class="d-inline-block fs-3 p-3">
<span>{{ __('Inscrivez-vous à notre newsletter') }}</span>
<div class="d-inline-block">
<div class="d-flex">
<input class="form-control mx-2" id="newsletter-email" type="email" placeholder="mon@email.com">
<button class="btn btn-primary text-uppercase fs-4" id="newsletter-submit" type="submit">{{ __('Valider') }}</button>
{{-- Error/Success message container --}}
</div>
</div>
<div class="d-none fs-6 rounded-2 my-3 border p-3" id="newsletter-message"></div>
</div>

View file

@ -1,6 +1,7 @@
<div class="row text-bg-quad">
<div class="col-12 col-md-9 col-xl-10">
@include('theme::layouts.footer-links')
@include('theme::layouts.footer-newsletter')
{{-- LINKS --}}
<nav class="ms-md-5 footer-nav p-3">

View file

@ -54,22 +54,16 @@
class="rest-in-game-banner flex-column flex-md-row text-bg-quad d-flex flex-grow-1 justify-content-around mt-3 py-1 pe-5 ps-2">
<span
class="d-flex align-items-center fw-bold text-uppercase fs-5 mx-2">{{ __("Encore en jeu\u{00A0}:") }}</span>
@if (Arr::has($prizesGlobal, 0))
@foreach ($prizesGlobal as $prizeModel)
<span class="d-flex justify-content-center">
<span
class="rounded-pill text-tertiary fw-bold fs-4 d-flex align-items-center my-1 bg-white px-3 py-1">{{ Arr::get($prizesGlobal, 0)->quantity - (optional(optional(optional(Arr::get($prizesGlobal, 1))->instantWins)->where('won', true))->count() ?? 0) }}</span>
class="rounded-pill text-tertiary fw-bold fs-4 d-flex align-items-center my-1 bg-white px-3 py-1">
{{ $prizeModel->quantity - \App\Models\InstantWin::query()->whereHas('prize', fn($q) => $q->where('id', $prizeModel->id))->whereHas('participation')->count() }}
</span>
<span
class="fw-bold text-uppercase fs-5 lh-sm d-flex align-items-center mx-2">{!! clean(nl2br(__("Wonderbox \n loisirs"))) !!}</span>
class="fw-bold text-uppercase fs-5 lh-sm d-flex align-items-center mx-2">{{ $prizeModel->label }}</span>
</span>
@endif
@if (Arr::has($prizesGlobal, 1))
<span class="d-flex justify-content-center">
<span
class="rounded-pill text-tertiary fw-bold fs-4 d-flex align-items-center my-1 bg-white px-3 py-1">{{ Arr::get($prizesGlobal, 1)->quantity - (optional(optional(optional(Arr::get($prizesGlobal, 1))->instantWins)->where('won', true))->count() ?? 0) }}</span>
<span
class="fw-bold text-uppercase fs-5 lh-sm d-flex align-items-center mx-2">{!! clean(nl2br(__("Wonderbox \n Happy Day"))) !!}</span>
</span>
@endif
@endforeach
</div>
</div>
@endif

View file

@ -1,6 +1,7 @@
<div class="row text-bg-quad">
<div class="col-12 col-md-9 col-xl-10">
@include('theme::layouts.footer-links')
@include('theme::layouts.footer-newsletter')
{{-- LINKS --}}
<ul class="list-inline ms-md-5 p-3">

View file

@ -14,7 +14,7 @@
<div class="row mb-5">
<div class="col">
<a class="btn btn-lg btn-success" data-bs-toggle="tooltip" href="{{ route('fo.participate') }}"
title="{{ __('Retenter votre change avec un nouveau code unique') }}">{{ __('Rejouer !') }}</a>
title="{{ __('Retenter votre chance avec un nouveau code unique') }}">{{ __('Rejouer !') }}</a>
</div>
</div>
</div>

View file

@ -14,20 +14,25 @@
</div>
<div class="row">
<div class="col">
<div class="d-flex product-list justify-content-center flex-wrap">
@foreach ($rangeModelList as $rangeModel)
@foreach ($rangeModelList as $rangeModel)
<h2 class="text-secondary">{{ $rangeModel->name }}</h2>
<div class="d-flex product-list justify-content-center flex-wrap">
@foreach ($rangeModel->products as $productModel)
<div class="card product m-2">
<a class="card-body glightbox" href="{{ asset($productModel->picture) }}" role="button"
aria-label="{{ __('Afficher l\'image en plein écran') }}" tabindex="0">
<img class="card-img-top" src="{{ asset($productModel->picture) }}"
title="{{ $productModel->picture_title }}" alt="{{ $productModel->picture_alt }}">
<span class="h4 card-title">{{ Str::title($productModel->name) }}</span>
</a>
@if (!empty($productModel->picture))
<a class="card-body glightbox" href="{{ asset($productModel->picture) }}" role="button"
aria-label="{{ __('Afficher l\'image en plein écran') }}" tabindex="0">
<img class="card-img-top" src="{{ asset($productModel->picture) }}"
title="{{ $productModel->picture_title }}" alt="{{ $productModel->picture_alt }}">
<span class="h4 card-title">{{ Str::title($productModel->name) }}</span>
</a>
@else
<span class="h4 card-title p-2">{{ Str::title($productModel->name) }}</span>
@endif
</div>
@endforeach
@endforeach
</div>
</div>
@endforeach
</div>
</div>
</div>