Sync 1 Front compilation ok

This commit is contained in:
Jérémy Munsch 2023-11-20 17:05:59 +01:00
parent 53b40f32ba
commit 890152e46c
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
24 changed files with 801 additions and 0 deletions

View file

@ -0,0 +1,4 @@
.nav-link.active {
color: $primary;
font-weight: bold;
}

1
sass/base/_common.scss Normal file
View file

@ -0,0 +1 @@
// Empty.

1
sass/base/_fonts.scss Normal file
View file

@ -0,0 +1 @@
// Empty.

12
sass/fo.scss Normal file
View file

@ -0,0 +1,12 @@
@charset "UTF-8";
// * UTILITIES
@import "./utilities/variables";
// * VENDOR
@import "./vendor/bootstrap";
// * BASE
@import "./base/bootstrap-overload";
@import "./base/fonts";
@import "./base/common";

313
sass/mail-theme.scss Normal file
View file

@ -0,0 +1,313 @@
@use "sass:color";
@import "utilities/variables";
// 1. Include new custom variables
@import "utilities/bootstrap-variables";
// 2. Include functions first (so you can manipulate colors, SVGs, calc, etc)
@import "bootstrap/scss/functions";
// 3. Include remainder of required Bootstrap stylesheets
@import "bootstrap/scss/variables";
// * Laravel mail vendor
/* Base */
body,
body *:not(html, style, br, tr, code) {
position: relative;
box-sizing: border-box;
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
Helvetica,
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol";
}
body {
width: 100% !important;
height: 100%;
padding: 0;
margin: 0;
background-color: $body-bg;
color: $body-color;
line-height: 1.4;
text-size-adjust: none;
}
p,
ul,
ol,
blockquote {
line-height: 1.4;
text-align: left;
}
img {
max-width: 100%;
}
a {
color: $link-color;
}
a img {
border: 0;
}
/* Typography */
h1 {
margin-top: 0;
color: $color-primary;
font-size: 18px;
font-weight: bold;
text-align: left;
}
h2 {
margin-top: 0;
font-size: 16px;
font-weight: bold;
text-align: left;
}
h3 {
margin-top: 0;
font-size: 14px;
font-weight: bold;
text-align: left;
}
p {
margin-top: 0;
font-size: 16px;
line-height: 1.5em;
text-align: left;
}
.sub {
font-size: 12px;
}
/* Layout */
.wrapper {
-premailer-width: 100%;
width: 100%;
padding: 0;
margin: 0;
background-color: $bg-lightened;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.content {
-premailer-width: 100%;
width: 100%;
padding: 0;
margin: 0;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Header */
.header {
padding: 25px 0;
text-align: center;
}
.header a {
color: $color-primary;
font-size: 19px;
font-weight: bold;
text-decoration: none;
}
/* Logo */
.logo {
width: 75px;
height: 75px;
max-height: 75px;
}
/* Body */
.body {
-premailer-width: 100%;
width: 100%;
padding: 0;
border-top: 1px solid #{$bg-lightened};
border-bottom: 1px solid #{$bg-lightened};
margin: 0;
background-color: $bg-lightened;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.inner-body {
-premailer-width: 570px;
width: 570px;
padding: 0;
border-width: 1px;
border-color: color.scale($body-bg, $lightness: -30%);
border-radius: 2px;
margin: 0 auto;
background-color: $body-bg;
box-shadow: 0 2px 0 rgb(0 0 150 / 2.5%), 2px 4px 0 rgb(0 0 150 / 1.5%);
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
/* Subcopy */
.subcopy {
padding-top: 25px;
border-top: 1px solid color.scale($body-bg, $lightness: -30%);
margin-top: 25px;
}
.subcopy p {
font-size: 14px;
}
/* Footer */
.footer {
-premailer-width: 570px;
width: 570px;
padding: 0;
margin: 0 auto;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.footer p {
color: #b0adc5;
font-size: 12px;
text-align: center;
}
.footer a {
color: #b0adc5;
text-decoration: underline;
}
/* Tables */
.table table {
-premailer-width: 100%;
width: 100%;
margin: 30px auto;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
}
.table th {
padding-bottom: 8px;
border-bottom: 1px solid #edeff2;
margin: 0;
}
.table td {
padding: 10px 0;
margin: 0;
color: #74787e;
font-size: 15px;
line-height: 18px;
}
.content-cell {
max-width: 100vw;
padding: 32px;
}
/* Buttons */
.action {
-premailer-width: 100%;
width: 100%;
padding: 0;
margin: 30px auto;
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
text-align: center;
}
.button {
display: inline-block;
overflow: hidden;
border-radius: 4px;
color: $body-bg;
text-decoration: none;
text-size-adjust: none;
}
.button-blue,
.button-primary {
border-top: 8px solid #{$color-primary};
border-right: 18px solid #{$color-primary};
border-bottom: 8px solid #{$color-primary};
border-left: 18px solid #{$color-primary};
background-color: #{$color-primary};
}
.button-green,
.button-success {
border-top: 8px solid #{$color-success};
border-right: 18px solid #{$color-success};
border-bottom: 8px solid #{$color-success};
border-left: 18px solid #{$color-success};
background-color: #{$color-success};
}
.button-red,
.button-error {
border-top: 8px solid #{$color-danger};
border-right: 18px solid #{$color-danger};
border-bottom: 8px solid #{$color-danger};
border-left: 18px solid #{$color-danger};
background-color: #{$color-danger};
}
/* Panels */
.panel {
border-left: $color-primary solid 4px;
margin: 21px 0;
}
.panel-content {
padding: 16px;
background-color: $bg-lightened;
color: $body-color;
}
.panel-content p {
color: $body-color;
}
.panel-item {
padding: 0;
}
.panel-item p:last-of-type {
padding-bottom: 0;
margin-bottom: 0;
}
/* Utilities */
.break-all {
word-break: break-all;
}

0
sass/pages/.gitkeep Normal file
View file

0
sass/partials/.gitkeep Normal file
View file

View file

@ -0,0 +1,44 @@
@use "sass:list";
@import "mixins";
// SET SOME CLASSES WITH BOOTSTRAP BREAKPOINTS
// * Reponsive borders
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
@include generate-bs-borders($infix, $prefix);
@each $color, $value in $theme-colors {
@include generate-bs-borders($infix, $prefix, $color);
}
}
}
// * Responsive sizings (used in laravel errors layouts)
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.w#{$infix}-25 {
width: 25% !important;
}
.w#{$infix}-50 {
width: 50% !important;
}
.w#{$infix}-75 {
width: 75% !important;
}
.w#{$infix}-100 {
width: 100% !important;
}
@each $prop, $unit in (width: vw, height: vh) {
@each $size in [25, 50, 75, 100] {
.#{$unit}#{$infix}-#{$size} {
#{$prop}: #{$size}#{$unit} !important;
}
}
}
}
}

View file

@ -0,0 +1,24 @@
// Override bootstrap colors
$primary: $color-primary;
$secondary: $color-secondary;
$success: $color-success;
$info: $color-info;
$warning: $color-warning;
$danger: $color-danger;
$light: $color-light;
$dark: $color-dark;
$theme-colors: (
primary: $primary,
secondary: $secondary,
success: $success,
info: $info,
warning: $warning,
danger: $danger,
light: $light,
dark: $dark,
);
// Override bootstrap vars
$font-family-base: $font-default-family-base;
$font-size-base: $font-default-size-base;
$line-height-base: $line-default-height-base;

View file

@ -0,0 +1,54 @@
@mixin generate-bs-borders($infix, $prefix, $color:null) {
$color-var: var(--#{$prefix}border-color);
@if $color {
$color-var: rgba(var(--#{$prefix}#{$color}-rgb));
$color: "-#{$color}";
}
.border#{$infix}#{$color}-top {
border-top: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-end {
border-right: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-bottom {
border-bottom: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-start {
border-left: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-0 { border: 0 !important; }
.border#{$infix}#{$color}-top-0 { border-top: 0 !important; }
.border#{$infix}#{$color}-end-0 { border-right: 0 !important; }
.border#{$infix}#{$color}-bottom-0 { border-bottom: 0 !important; }
.border#{$infix}#{$color}-start-0 { border-left: 0 !important; }
@each $idx, $b-width in $border-widths {
$pidx: list.index(($border-widths), ($idx $b-width));
.border#{$infix}#{$color}-top-#{$idx} {
border-top: $b-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-end-#{$idx} {
border-right: $b-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-bottom-#{$idx} {
border-bottom: $b-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-start-#{$idx} {
border-left: $b-width var(--#{$prefix}border-style) #{$color-var} !important;
}
}
.border#{$infix}#{$color}-x {
border-right: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
border-left: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
.border#{$infix}#{$color}-y {
border-top: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
border-bottom: $border-width var(--#{$prefix}border-style) #{$color-var} !important;
}
}

View file

@ -0,0 +1,24 @@
// * COLORS
$color-white: #fff;
$color-light: #f8f9fa;
$color-dark: #212529;
$color-success: #198754;
$color-danger: #dc3545;
$color-info: #0dcaf0;
$color-warning: #ffc107;
$color-primary: #0d6efd;
$color-secondary: #6c757d;
// * BACKGROUNDS COLORS
$bg-lightened: $color-light;
$bg-darkened: $color-dark;
$bg-action: $color-primary;
// * FONTS COLORS
$color-default-titles: $color-primary;
$color-default-texts: $color-dark;
// * FONTS
$font-default-family-base: "Imprima Regular", sans-serif; // - The default site font family.
$font-default-size-base: 1rem; // Assumes the browser default, typically `16px`
$line-default-height-base: 1.65;

44
sass/vendor/_bootstrap.scss vendored Normal file
View file

@ -0,0 +1,44 @@
// 1. Include new custom variables
@import "./../utilities/bootstrap-variables";
// 2. Include functions first (so you can manipulate colors, SVGs, calc, etc)
@import "bootstrap/scss/functions";
// 3. Include remainder of required Bootstrap stylesheets
@import "bootstrap/scss/variables";
@import "bootstrap/scss/variables-dark";
// 4. Include remainder of required parts
@import "bootstrap/scss/maps";
@import "bootstrap/scss/mixins";
@import "bootstrap/scss/root";
// 5. Optionally include any other parts as needed
@import "bootstrap/scss/alert";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/button-group";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/dropdown";
@import "bootstrap/scss/forms";
@import "bootstrap/scss/grid";
@import "bootstrap/scss/helpers";
@import "bootstrap/scss/images";
@import "bootstrap/scss/list-group";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/pagination";
@import "bootstrap/scss/spinners";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/tables";
@import "bootstrap/scss/tooltip";
@import "bootstrap/scss/transitions";
@import "bootstrap/scss/type";
@import "bootstrap/scss/utilities";
@import "bootstrap/scss/close";
@import "bootstrap/scss/breadcrumb";
// 6. Optionally include utilities API last to generate classes based on the Sass map in `_utilities.scss`
@import "bootstrap/scss/utilities/api";
// 7 Overload bootstrap classes
@import "./../utilities/bootstrap-custom";

44
ts/base/common.ts Normal file
View file

@ -0,0 +1,44 @@
// * Video frames.
document.addEventListener("DOMContentLoaded", function () {
const videoFrameList = document.querySelectorAll(
".video-frame"
) as NodeListOf<HTMLLinkElement>;
for (const videoLink of videoFrameList) {
if (!videoLink.dataset.type) {
throw new Error("Missing dataset type");
}
if (!videoLink.dataset.frame) {
throw new Error("Missing dataset frame");
}
// @ts-ignore
window.__CN_VIDEO = window.__CN_VIDEO ?? {};
const newIframe = document.createElement("iframe");
newIframe.frameBorder = "0";
newIframe.allow = "fullscreen";
newIframe.width = "1920px";
newIframe.height = "1080px";
newIframe.setAttribute("allowfullscreen", "allowfullscreen");
// @ts-ignore
const instance = new FsLightbox();
instance.props.sources = [newIframe];
setTimeout(() => {
videoLink.addEventListener("click", (e) => {
e.preventDefault();
// * This comes fslightbox lib
// @ts-ignore
instance.open();
setTimeout(function () {
// @ts-ignore
newIframe.src = window.__CN_VIDEO[videoLink.dataset.type]
? String(videoLink.href)
: String(videoLink.dataset.frame);
}, 50);
return false;
});
}, 300);
}
});

5
ts/components/shims-vue.d.ts vendored Normal file
View file

@ -0,0 +1,5 @@
declare module "*.vue" {
import type { DefineComponent } from "vue";
const component: DefineComponent<{}, {}, any>;
export default component;
}

8
ts/env.d.ts vendored Normal file
View file

@ -0,0 +1,8 @@
/// <reference types="vite/client" />
declare module "*.vue" {
import type { DefineComponent } from "vue";
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>;
export default component;
}

15
ts/fo.ts Normal file
View file

@ -0,0 +1,15 @@
// ASSETS
/// <reference types="vite/client" />
import.meta.glob(["./../../assets/images/**"]);
// UTILITIES
import "./utilities/bootstrap";
import "./utilities/fontawesome";
import "./utilities/vue-fo";
// CUSTOM
import "./base/common";
// Cookies
import CookieNotice from "@ldc-web/cookie-notice";
window.CookieNotice = CookieNotice;

15
ts/index.d.ts vendored Normal file
View file

@ -0,0 +1,15 @@
export { };
import type CookieNotice from "@ldc-web/cookie-notice";
import { AxiosStatic } from "axios";
// import type {
// Axios
// } from "./../../../ts/front-definition.d.ts";
declare global {
interface Window {
CookieNotice: typeof CookieNotice;
axios: AxiosStatic;
}
}

26
ts/modules/bsTooltips.ts Normal file
View file

@ -0,0 +1,26 @@
import type * as bootstrap from "bootstrap";
let tooltips: Array<bootstrap.Tooltip> = [];
export default {
methods: {
initTooltips() {
// Disable tooltips on reboot.
tooltips.forEach((tooltip) => {
tooltip.disable();
tooltip.hide();
});
tooltips = [].slice
.call(document.querySelectorAll("[data-bs-toggle=\"tooltip\"]"))
.map(function (tooltipTriggerEl) {
return new window.bootstrap.Tooltip(tooltipTriggerEl, {
customClass: "large-tooltip",
delay: {
show: 1250,
hide: 0,
},
});
});
},
},
};

0
ts/pages/.gitkeep Normal file
View file

0
ts/partials/.gitkeep Normal file
View file

0
ts/types/.gitkeep Normal file
View file

21
ts/utilities/bootstrap.ts Normal file
View file

@ -0,0 +1,21 @@
import axios from "axios";
import * as bootstrap from "bootstrap";
import bsTooltips from "./../modules/bsTooltips";
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
axios.defaults.headers.common = {
Accept: "application/json, text/plain, */*",
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-TOKEN": document
.querySelector("meta[name=\"csrf-token\"]")!
.getAttribute("content"),
};
window.axios = axios;
window.bootstrap = bootstrap;
bsTooltips.methods.initTooltips();

View file

@ -0,0 +1,90 @@
import { config, dom, library } from "@fortawesome/fontawesome-svg-core";
import {
faArrowAltCircleDown,
faArrowAltCircleUp,
faArrowDown,
faArrowLeft,
faArrowLeftLong,
faArrowRight,
faArrowRightFromBracket,
faArrowUp,
faArrowsAltH,
faArrowsAltV,
faBackspace,
faBan,
faCheck,
faChevronLeft,
faChevronRight,
faCircleCheck,
faCircleExclamation,
faCircleInfo,
faCircleNotch,
faCircleXmark,
faCopy,
faCrop,
faEraser,
faEye,
faEyeSlash,
faFolderOpen,
faListUl,
faPencil,
faPlus,
faQuestionCircle,
faRedoAlt,
faSearch,
faSearchMinus,
faSearchPlus,
faSliders,
faSyncAlt,
faTimes,
faTrash,
faUndoAlt,
faWandMagic
} from "@fortawesome/free-solid-svg-icons";
config.autoReplaceSvg = false;
library.add(faEraser);
library.add(faArrowLeftLong);
library.add(faPlus);
library.add(faTrash);
library.add(faEye);
library.add(faEyeSlash);
library.add(faFolderOpen);
library.add(faCrop);
library.add(faQuestionCircle);
library.add(faCheck);
library.add(faUndoAlt);
library.add(faRedoAlt);
library.add(faSyncAlt);
library.add(faSearchPlus);
library.add(faSearchMinus);
library.add(faArrowLeft);
library.add(faArrowRight);
library.add(faArrowUp);
library.add(faArrowDown);
library.add(faArrowsAltH);
library.add(faArrowsAltV);
library.add(faWandMagic);
library.add(faPencil);
library.add(faTimes);
library.add(faBackspace);
library.add(faSearch);
library.add(faArrowRightFromBracket);
library.add(faArrowAltCircleDown);
library.add(faArrowAltCircleUp);
library.add(faCircleCheck);
library.add(faCircleXmark);
library.add(faCopy);
library.add(faListUl);
library.add(faBan);
library.add(faCircleExclamation);
library.add(faCircleInfo);
// Front
library.add(faChevronLeft);
library.add(faChevronRight);
library.add(faCircleXmark);
library.add(faCircleNotch);
library.add(faSliders);
dom.watch();

56
ts/utilities/vue-fo.ts Normal file
View file

@ -0,0 +1,56 @@
import type { App, Component } from "vue";
import { createApp } from "vue";
document.addEventListener("DOMContentLoaded", () => {
const setupApp = (app: App<Element>) => {
app.config.globalProperties.window = window;
app.config.globalProperties.document = document;
};
// Register components
/// <reference types="vite/client" />
const vues = import.meta.glob("./../components/*.vue") as Record<
string,
() => Promise<{ default: Component }>
>;
for (const vueCptName in vues) {
const vueCptPromise = vues[vueCptName];
let htmlKey = vueCptName.split("/").pop();
if (!htmlKey) {
throw new Error(`Cannot load ${vueCptName}`);
}
htmlKey = htmlKey
.split(".")[0]
.replace(/\.?([A-Z])/g, function (x, y) {
return "-" + y.toLowerCase();
})
.replace(/^-/, "")
.replace("-component", "");
const el = document.getElementById(htmlKey),
elGroup = document.getElementsByClassName(htmlKey);
// * Init using ID
if (el) {
vueCptPromise().then((vueParsedFile) => {
const app = createApp(vueParsedFile.default, {
json: el.dataset.json ?? {},
});
setupApp(app);
app.mount(el);
});
}
// * Init Using class
for (const grpEl of elGroup) {
// * Hack to prevent loop weirdness
vueCptPromise().then((vueParsedFile) => {
setTimeout(() => {
const app = createApp(vueParsedFile.default, {
json: (grpEl as HTMLElement).dataset.json ?? {},
});
setupApp(app);
app.mount(grpEl);
}, 500);
});
}
}
});