Initial commit — Diabetix V2

Application Laravel 12 + Inertia + Vue 3 + Tailwind.
Fonctionnalités : dashboard glycémique, saisie de mesures, courbe SVG,
statistiques (jour/semaine/mois/trimestre), défis & badges, chat coach IA
(Gemini), paramètres profil avec palette de couleurs, pages auth redessinées,
emails transactionnels via Resend avec thème Diabetix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jeremy bayse
2026-04-29 07:01:41 +02:00
commit 26c6d8031c
150 changed files with 19863 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title inertia>{{ config('app.name', 'Diabetix') }}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Lora:wght@400;500;600;700&display=swap" rel="stylesheet">
@routes
@vite(['resources/js/app.js', "resources/js/Pages/{$page['component']}.vue"])
@inertiaHead
</head>
<body style="background:#eeece8;font-family:'Plus Jakarta Sans',sans-serif;-webkit-font-smoothing:antialiased;margin:0;">
@inertia
</body>
</html>

View File

@@ -0,0 +1,24 @@
@props([
'url',
'color' => 'primary',
'align' => 'center',
])
<table class="action" align="{{ $align }}" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="{{ $align }}">
<table width="100%" border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="{{ $align }}">
<table border="0" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td>
<a href="{{ $url }}" class="button button-{{ $color }}" target="_blank" rel="noopener">{!! $slot !!}</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>

View File

@@ -0,0 +1,12 @@
<tr>
<td>
<table class="footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="content-cell" align="center" style="padding:24px 40px 32px;">
<p style="color:#7a9c97;font-size:12px;margin:0 0 4px;">© {{ date('Y') }} {{ config('app.name') }} · Tous droits réservés</p>
<p style="color:#7a9c97;font-size:12px;margin:0;">Cet e-mail a été envoyé depuis une adresse de notification automatique.</p>
</td>
</tr>
</table>
</td>
</tr>

View File

@@ -0,0 +1,16 @@
@props(['url'])
<tr>
<td>
<table class="header" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td style="text-align:center;padding:32px 0 16px;">
<a href="{{ $url }}" style="text-decoration:none;">
<div style="display:inline-block;width:52px;height:52px;border-radius:50%;background:#d4ede8;border:2px solid #7bbfb5;text-align:center;line-height:50px;font-size:24px;margin-bottom:10px;">🩺</div>
<div style="font-size:20px;font-weight:700;color:#2a3533;letter-spacing:-0.3px;">{{ config('app.name') }}</div>
<div style="font-size:12px;color:#7a9c97;margin-top:2px;">Votre coach glycémique personnel</div>
</a>
</td>
</tr>
</table>
</td>
</tr>

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<title>{{ config('app.name') }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="color-scheme" content="light">
<meta name="supported-color-schemes" content="light">
<style>
@media only screen and (max-width: 600px) {
.inner-body {
width: 100% !important;
}
.footer {
width: 100% !important;
}
}
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
}
}
</style>
{!! $head ?? '' !!}
</head>
<body>
<table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
{!! $header ?? '' !!}
<!-- Email Body -->
<tr>
<td class="body" width="100%" cellpadding="0" cellspacing="0" style="border: hidden !important;">
<table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
{!! Illuminate\Mail\Markdown::parse($slot) !!}
{!! $subcopy ?? '' !!}
</td>
</tr>
</table>
</td>
</tr>
{!! $footer ?? '' !!}
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,27 @@
<x-mail::layout>
{{-- Header --}}
<x-slot:header>
<x-mail::header :url="config('app.url')">
{{ config('app.name') }}
</x-mail::header>
</x-slot:header>
{{-- Body --}}
{!! $slot !!}
{{-- Subcopy --}}
@isset($subcopy)
<x-slot:subcopy>
<x-mail::subcopy>
{!! $subcopy !!}
</x-mail::subcopy>
</x-slot:subcopy>
@endisset
{{-- Footer --}}
<x-slot:footer>
<x-mail::footer>
© {{ date('Y') }} {{ config('app.name') }}. {{ __('All rights reserved.') }}
</x-mail::footer>
</x-slot:footer>
</x-mail::layout>

View File

@@ -0,0 +1,14 @@
<table class="panel" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="panel-content">
<table width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td class="panel-item">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
</td>
</tr>
</table>

View File

@@ -0,0 +1,7 @@
<table class="subcopy" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td>
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>

View File

@@ -0,0 +1,3 @@
<div class="table">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</div>

View File

@@ -0,0 +1,272 @@
/* Diabetix email theme — palette mint */
body,
body *:not(html):not(style):not(br):not(tr):not(code) {
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
position: relative;
}
body {
-webkit-text-size-adjust: none;
background-color: #eeece8;
color: #2a3533;
height: 100%;
line-height: 1.5;
margin: 0;
padding: 0;
width: 100% !important;
}
p, ul, ol, blockquote {
line-height: 1.5;
text-align: start;
}
a { color: #7bbfb5; }
a img { border: none; }
h1 {
color: #2a3533;
font-size: 22px;
font-weight: 700;
margin-top: 0;
text-align: start;
}
h2 {
color: #2a3533;
font-size: 17px;
font-weight: 600;
margin-top: 0;
}
h3 {
color: #2a3533;
font-size: 14px;
font-weight: 600;
margin-top: 0;
}
p {
font-size: 15px;
line-height: 1.6;
margin-top: 0;
color: #2a3533;
}
p.sub { font-size: 12px; color: #7a9c97; }
img { max-width: 100%; }
/* Layout */
.wrapper {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
background-color: #eeece8;
margin: 0;
padding: 0;
width: 100%;
}
.content {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
margin: 0;
padding: 0;
width: 100%;
}
/* Header */
.header {
padding: 32px 0 20px;
text-align: center;
}
.header a {
color: #2a3533;
font-size: 20px;
font-weight: 700;
text-decoration: none;
}
/* Body */
.body {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
background-color: #eeece8;
border-bottom: 1px solid #eeece8;
border-top: 1px solid #eeece8;
margin: 0;
padding: 0;
width: 100%;
}
.inner-body {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 570px;
background-color: #ffffff;
border-color: #ddeae7;
border-radius: 20px;
border-width: 1px;
box-shadow: 0 4px 24px rgba(42, 53, 51, 0.08);
margin: 0 auto;
padding: 0;
width: 570px;
}
.inner-body a { word-break: break-all; }
/* Subcopy */
.subcopy {
border-top: 1px solid #ddeae7;
margin-top: 25px;
padding-top: 25px;
}
.subcopy p {
font-size: 13px;
color: #7a9c97;
}
/* Footer */
.footer {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 570px;
margin: 0 auto;
padding: 0;
text-align: center;
width: 570px;
}
.footer p {
color: #7a9c97;
font-size: 12px;
text-align: center;
}
.footer a {
color: #7a9c97;
text-decoration: underline;
}
/* Tables */
.table table {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
margin: 30px auto;
width: 100%;
}
.table th {
border-bottom: 1px solid #ddeae7;
margin: 0;
padding-bottom: 8px;
color: #7a9c97;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.6px;
}
.table td {
color: #2a3533;
font-size: 15px;
line-height: 18px;
margin: 0;
padding: 10px 0;
border-bottom: 1px solid #f0ede6;
}
.content-cell {
max-width: 100vw;
padding: 36px 40px;
}
/* Buttons */
.action {
-premailer-cellpadding: 0;
-premailer-cellspacing: 0;
-premailer-width: 100%;
margin: 30px auto;
padding: 0;
text-align: center;
width: 100%;
float: unset;
}
.button {
-webkit-text-size-adjust: none;
border-radius: 14px;
color: #fff;
display: inline-block;
overflow: hidden;
text-decoration: none;
font-weight: 600;
}
.button-blue,
.button-primary {
background-color: #7bbfb5;
border-bottom: 10px solid #7bbfb5;
border-left: 22px solid #7bbfb5;
border-right: 22px solid #7bbfb5;
border-top: 10px solid #7bbfb5;
}
.button-green,
.button-success {
background-color: #5ca89d;
border-bottom: 10px solid #5ca89d;
border-left: 22px solid #5ca89d;
border-right: 22px solid #5ca89d;
border-top: 10px solid #5ca89d;
}
.button-red,
.button-error {
background-color: #d4826a;
border-bottom: 10px solid #d4826a;
border-left: 22px solid #d4826a;
border-right: 22px solid #d4826a;
border-top: 10px solid #d4826a;
}
/* Panels */
.panel {
border-left: #7bbfb5 solid 4px;
margin: 21px 0;
border-radius: 0 8px 8px 0;
}
.panel-content {
background-color: #d4ede8;
color: #2a3533;
padding: 16px 20px;
border-radius: 0 8px 8px 0;
}
.panel-content p { color: #2a3533; }
.panel-item { padding: 0; }
.panel-item p:last-of-type {
margin-bottom: 0;
padding-bottom: 0;
}
/* Utilities */
.break-all { word-break: break-all; }

View File

@@ -0,0 +1 @@
{{ $slot }}: {{ $url }}

View File

@@ -0,0 +1 @@
{{ $slot }}

View File

@@ -0,0 +1 @@
{{ $slot }}: {{ $url }}

View File

@@ -0,0 +1,9 @@
{!! strip_tags($header ?? '') !!}
{!! strip_tags($slot) !!}
@isset($subcopy)
{!! strip_tags($subcopy) !!}
@endisset
{!! strip_tags($footer ?? '') !!}

View File

@@ -0,0 +1,27 @@
<x-mail::layout>
{{-- Header --}}
<x-slot:header>
<x-mail::header :url="config('app.url')">
{{ config('app.name') }}
</x-mail::header>
</x-slot:header>
{{-- Body --}}
{{ $slot }}
{{-- Subcopy --}}
@isset($subcopy)
<x-slot:subcopy>
<x-mail::subcopy>
{{ $subcopy }}
</x-mail::subcopy>
</x-slot:subcopy>
@endisset
{{-- Footer --}}
<x-slot:footer>
<x-mail::footer>
© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
</x-mail::footer>
</x-slot:footer>
</x-mail::layout>

View File

@@ -0,0 +1 @@
{{ $slot }}

View File

@@ -0,0 +1 @@
{{ $slot }}

View File

@@ -0,0 +1 @@
{{ $slot }}