shaapi 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. shaapi/__init__.py +3 -0
  2. shaapi/cli.py +97 -0
  3. shaapi/generator.py +114 -0
  4. shaapi/template/.dockerignore +37 -0
  5. shaapi/template/.env.template +59 -0
  6. shaapi/template/.gitattributes +12 -0
  7. shaapi/template/.gitignore +170 -0
  8. shaapi/template/.gitlab-ci.yml +89 -0
  9. shaapi/template/Dockerfile +59 -0
  10. shaapi/template/LICENSE +21 -0
  11. shaapi/template/README.md +206 -0
  12. shaapi/template/backend/.gitignore +164 -0
  13. shaapi/template/backend/__init__.py +0 -0
  14. shaapi/template/backend/alembic/README +1 -0
  15. shaapi/template/backend/alembic/env.py +102 -0
  16. shaapi/template/backend/alembic/script.py.mako +26 -0
  17. shaapi/template/backend/alembic/versions/2026_06_08_1024-64524c63b666_initial.py +143 -0
  18. shaapi/template/backend/alembic.ini +117 -0
  19. shaapi/template/backend/app/__init__.py +55 -0
  20. shaapi/template/backend/app/admin/__init__.py +1 -0
  21. shaapi/template/backend/app/admin/api/v1/__init__.py +0 -0
  22. shaapi/template/backend/app/admin/api/v1/auth.py +59 -0
  23. shaapi/template/backend/app/admin/api/v1/casbin.py +218 -0
  24. shaapi/template/backend/app/admin/api/v1/login_log.py +63 -0
  25. shaapi/template/backend/app/admin/api/v1/opera_log.py +61 -0
  26. shaapi/template/backend/app/admin/api/v1/role.py +108 -0
  27. shaapi/template/backend/app/admin/api/v1/user.py +47 -0
  28. shaapi/template/backend/app/admin/schema/casbin_rule.py +45 -0
  29. shaapi/template/backend/app/admin/schema/login_log.py +36 -0
  30. shaapi/template/backend/app/admin/schema/opera_log.py +43 -0
  31. shaapi/template/backend/app/admin/schema/role.py +36 -0
  32. shaapi/template/backend/app/admin/schema/sso.py +37 -0
  33. shaapi/template/backend/app/admin/schema/token.py +74 -0
  34. shaapi/template/backend/app/admin/schema/user.py +93 -0
  35. shaapi/template/backend/app/admin/service/auth_service.py +233 -0
  36. shaapi/template/backend/app/admin/service/casbin_service.py +135 -0
  37. shaapi/template/backend/app/admin/service/login_log_service.py +62 -0
  38. shaapi/template/backend/app/admin/service/opera_log_service.py +31 -0
  39. shaapi/template/backend/app/admin/service/role_service.py +79 -0
  40. shaapi/template/backend/app/admin/service/secure_token_service.py +60 -0
  41. shaapi/template/backend/app/admin/service/user_service.py +153 -0
  42. shaapi/template/backend/app/api.py +11 -0
  43. shaapi/template/backend/common/__init__.py +0 -0
  44. shaapi/template/backend/common/cloud_storage/__init__.py +11 -0
  45. shaapi/template/backend/common/cloud_storage/cloud_storage.py +180 -0
  46. shaapi/template/backend/common/dataclasses.py +52 -0
  47. shaapi/template/backend/common/email_conf/email.py +105 -0
  48. shaapi/template/backend/common/enums.py +144 -0
  49. shaapi/template/backend/common/exception/__init__.py +0 -0
  50. shaapi/template/backend/common/exception/errors.py +87 -0
  51. shaapi/template/backend/common/exception/exception_handler.py +280 -0
  52. shaapi/template/backend/common/log.py +123 -0
  53. shaapi/template/backend/common/model.py +68 -0
  54. shaapi/template/backend/common/pagination.py +83 -0
  55. shaapi/template/backend/common/response/__init__.py +0 -0
  56. shaapi/template/backend/common/response/response_code.py +158 -0
  57. shaapi/template/backend/common/response/response_schema.py +110 -0
  58. shaapi/template/backend/common/schema.py +144 -0
  59. shaapi/template/backend/common/security/jwt.py +203 -0
  60. shaapi/template/backend/common/security/rbac.py +98 -0
  61. shaapi/template/backend/common/security/sec_token.py +6 -0
  62. shaapi/template/backend/common/socketio/action.py +11 -0
  63. shaapi/template/backend/common/socketio/server.py +50 -0
  64. shaapi/template/backend/common/sso/base.py +69 -0
  65. shaapi/template/backend/common/sso/google.py +127 -0
  66. shaapi/template/backend/core/conf.py +208 -0
  67. shaapi/template/backend/core/path_conf.py +24 -0
  68. shaapi/template/backend/core/registrar.py +195 -0
  69. shaapi/template/backend/crud/__init__.py +1 -0
  70. shaapi/template/backend/crud/crud_base.py +35 -0
  71. shaapi/template/backend/crud/crud_casbin.py +46 -0
  72. shaapi/template/backend/crud/crud_login_log.py +58 -0
  73. shaapi/template/backend/crud/crud_opera_log.py +58 -0
  74. shaapi/template/backend/crud/crud_role.py +128 -0
  75. shaapi/template/backend/crud/crud_user.py +267 -0
  76. shaapi/template/backend/database/__init__.py +0 -0
  77. shaapi/template/backend/database/db_postgres.py +125 -0
  78. shaapi/template/backend/database/db_redis.py +62 -0
  79. shaapi/template/backend/entrypoint-api.sh +19 -0
  80. shaapi/template/backend/lang/en/app.py +18 -0
  81. shaapi/template/backend/lang/en/auth.py +10 -0
  82. shaapi/template/backend/lang/fr/app.py +18 -0
  83. shaapi/template/backend/lang/fr/auth.py +10 -0
  84. shaapi/template/backend/main.py +54 -0
  85. shaapi/template/backend/middleware/__init__.py +1 -0
  86. shaapi/template/backend/middleware/access_middleware.py +19 -0
  87. shaapi/template/backend/middleware/i18n_middleware.py +19 -0
  88. shaapi/template/backend/middleware/jwt_auth_middleware.py +73 -0
  89. shaapi/template/backend/middleware/opera_log_middleware.py +179 -0
  90. shaapi/template/backend/middleware/state_middleware.py +26 -0
  91. shaapi/template/backend/models/__init__.py +10 -0
  92. shaapi/template/backend/models/associations.py +20 -0
  93. shaapi/template/backend/models/casbin_rule.py +30 -0
  94. shaapi/template/backend/models/login_log.py +28 -0
  95. shaapi/template/backend/models/opera_log.py +36 -0
  96. shaapi/template/backend/models/role.py +27 -0
  97. shaapi/template/backend/models/user.py +30 -0
  98. shaapi/template/backend/seeder/json/admin.json +15 -0
  99. shaapi/template/backend/seeder/json/user.json +15 -0
  100. shaapi/template/backend/seeder/run.py +34 -0
  101. shaapi/template/backend/static/ip2region.xdb +0 -0
  102. shaapi/template/backend/templates/build/meet.html +169 -0
  103. shaapi/template/backend/templates/build/new_account.html +373 -0
  104. shaapi/template/backend/templates/build/reset-password.html +170 -0
  105. shaapi/template/backend/templates/build/test_email.html +25 -0
  106. shaapi/template/backend/templates/build/welcome-one-1.html +160 -0
  107. shaapi/template/backend/templates/build/welcome-one.html +178 -0
  108. shaapi/template/backend/templates/build/welcome-two.html +234 -0
  109. shaapi/template/backend/templates/index.html +0 -0
  110. shaapi/template/backend/templates/src/new_account.mjml +15 -0
  111. shaapi/template/backend/templates/src/reset_password.mjml +19 -0
  112. shaapi/template/backend/templates/src/test_email.mjml +11 -0
  113. shaapi/template/backend/templates/ws/ws.html +70 -0
  114. shaapi/template/backend/utils/demo_site.py +18 -0
  115. shaapi/template/backend/utils/encrypt.py +108 -0
  116. shaapi/template/backend/utils/health_check.py +34 -0
  117. shaapi/template/backend/utils/prometheus.py +135 -0
  118. shaapi/template/backend/utils/request_parse.py +110 -0
  119. shaapi/template/backend/utils/serializers.py +75 -0
  120. shaapi/template/backend/utils/timezone.py +51 -0
  121. shaapi/template/backend/utils/trace_id.py +7 -0
  122. shaapi/template/backend/utils/translator.py +28 -0
  123. shaapi/template/devops/scripts/deploy.sh +7 -0
  124. shaapi/template/devops/scripts/setup_env.sh +62 -0
  125. shaapi/template/docker-compose.monitoring.yml +63 -0
  126. shaapi/template/docker-compose.override.yml +12 -0
  127. shaapi/template/docker-compose.yml +90 -0
  128. shaapi/template/docker-run.sh +99 -0
  129. shaapi/template/etc/dashboards/fastapi-observability.json +1044 -0
  130. shaapi/template/etc/dashboards.yaml +10 -0
  131. shaapi/template/etc/grafana/datasource.yml +79 -0
  132. shaapi/template/etc/prometheus/prometheus.yml +52 -0
  133. shaapi/template/package-lock.json +2102 -0
  134. shaapi/template/package.json +16 -0
  135. shaapi/template/pyproject.toml +78 -0
  136. shaapi/template/uv.lock +2866 -0
  137. shaapi-0.1.0.dist-info/METADATA +92 -0
  138. shaapi-0.1.0.dist-info/RECORD +141 -0
  139. shaapi-0.1.0.dist-info/WHEEL +4 -0
  140. shaapi-0.1.0.dist-info/entry_points.txt +2 -0
  141. shaapi-0.1.0.dist-info/licenses/LICENCE +21 -0
@@ -0,0 +1,170 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Réinitialisation du mot de passe</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
9
+ <style>
10
+ body {
11
+ font-family: "Inter", Arial, sans-serif;
12
+ margin: 0;
13
+ padding: 0;
14
+ color: #4f4d55;
15
+ background-color: #f4f4f4;
16
+ width: 100%;
17
+ }
18
+
19
+ table {
20
+ width: 100%;
21
+ max-width: 640px;
22
+ margin: auto;
23
+ background-color: #ffffff;
24
+ }
25
+
26
+ td {
27
+ padding: 0;
28
+ }
29
+
30
+ img {
31
+ display: block;
32
+ border: 0;
33
+ }
34
+
35
+ .header,
36
+ .footer {
37
+ width: 100%;
38
+ text-align: center;
39
+ padding: 24px;
40
+ }
41
+
42
+ .main {
43
+ padding: 32px 24px;
44
+ }
45
+
46
+ .main p {
47
+ font-size: 16px;
48
+ line-height: 24px;
49
+ margin-bottom: 16px;
50
+ }
51
+
52
+ .button {
53
+ display: inline-block;
54
+ color: #ffffff;
55
+ font-weight: 500;
56
+ font-size: 16px;
57
+ line-height: 24px;
58
+ background-color: #fc5933;
59
+ text-decoration: none;
60
+ padding: 10px 16px;
61
+ border-radius: 99px;
62
+ text-align: center;
63
+ }
64
+
65
+ .social-icons img {
66
+ width: 20px;
67
+ height: 20px;
68
+ }
69
+
70
+ .social-icons {
71
+ float: right;
72
+ }
73
+
74
+ .social-icons a {
75
+ display: inline-block;
76
+ margin-left: 16px;
77
+ text-decoration: none;
78
+ }
79
+
80
+ .footer p {
81
+ font-size: 14px;
82
+ line-height: 20px;
83
+ }
84
+
85
+ .footer span {
86
+ color: #fc5933;
87
+ text-decoration: underline;
88
+ cursor: pointer;
89
+ }
90
+
91
+ .footer-image {
92
+ max-width: 90px;
93
+ }
94
+
95
+ @media (max-width: 600px) {
96
+ .main {
97
+ padding: 16px;
98
+ }
99
+
100
+ .footer {
101
+ padding: 16px;
102
+ }
103
+
104
+ .social-icons {
105
+ text-align: center;
106
+ }
107
+
108
+ .social-icons a {
109
+ display: inline-block;
110
+ margin-left: 8px;
111
+ margin-right: 8px;
112
+ }
113
+ }
114
+ </style>
115
+ </head>
116
+
117
+ <body>
118
+ <table cellpadding="0" cellspacing="0">
119
+ <tr>
120
+ <td class="header">
121
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
122
+ alt="Logo de Boilerplate" width="130" />
123
+ </td>
124
+ </tr>
125
+ <tr>
126
+ <td class="main">
127
+ <p>Bonjour,</p>
128
+ <p>Nous avons reçu une demande de réinitialisation de votre mot de passe Boilerplate. Si vous n'êtes pas à
129
+ l'origine de cette demande, veuillez ignorer ce message.</p>
130
+ <p>Pour réinitialiser votre mot de passe, veuillez cliquer sur le lien ci-dessous :</p>
131
+ <p><a href="{{ link }}" style="color: #fc5933; text-decoration: none;">Réinitialiser mon mot de passe &rarr;</a>
132
+ </p>
133
+ <p>Ce lien expire dans 5 minutes. Passé ce délai, vous devrez faire une nouvelle demande de réinitialisation.
134
+ </p>
135
+ <p>Merci,<br />L'équipe Boilerplate.</p>
136
+ </td>
137
+ </tr>
138
+ <tr>
139
+ <td class="footer">
140
+ <p>Ce courriel a été envoyé à <span>{{ email }}</span>. Si vous préférez ne pas recevoir ce type d'e-mail, vous
141
+ pouvez vous <span>désabonner</span> ou <span>gérer vos préférences en matière d'e-mail</span>.</p>
142
+ <p>&copy; Boilerplate co., 38 Rue Legendre, 75017 Paris, France</p>
143
+ <div class="social" style="width: 100%">
144
+ <div style="float: left">
145
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
146
+ alt="Logo de Boilerplate" class="footer-image" />
147
+ </div>
148
+ <div class="social-icons">
149
+ <a href="https://www.twitter.com/nomdelentreprise" target="_blank">
150
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986108/test/twitter_xnqzgi.png" alt="X" />
151
+ </a>
152
+ <a href="https://www.facebook.com/nomdelentreprise" target="_blank">
153
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986190/test/facebook_yafqw6.png"
154
+ alt="Facebook" />
155
+ </a>
156
+ <a href="https://www.instagram.com/nomdelentreprise" target="_blank">
157
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png" alt="Instagram" />
158
+ </a>
159
+ <a href="https://www.linkedin.com/company/nomdelentreprise" target="_blank">
160
+ <img src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png"
161
+ alt="LinkedIn" />
162
+ </a>
163
+ </div>
164
+ </div>
165
+ </td>
166
+ </tr>
167
+ </table>
168
+ </body>
169
+
170
+ </html>
@@ -0,0 +1,25 @@
1
+ <!doctype html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><title></title><!--[if !mso]><!-- --><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]--><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style type="text/css">#outlook a { padding:0; }
2
+ .ReadMsgBody { width:100%; }
3
+ .ExternalClass { width:100%; }
4
+ .ExternalClass * { line-height:100%; }
5
+ body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; }
6
+ table, td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; }
7
+ img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; }
8
+ p { display:block;margin:13px 0; }</style><!--[if !mso]><!--><style type="text/css">@media only screen and (max-width:480px) {
9
+ @-ms-viewport { width:320px; }
10
+ @viewport { width:320px; }
11
+ }</style><!--<![endif]--><!--[if mso]>
12
+ <xml>
13
+ <o:OfficeDocumentSettings>
14
+ <o:AllowPNG/>
15
+ <o:PixelsPerInch>96</o:PixelsPerInch>
16
+ </o:OfficeDocumentSettings>
17
+ </xml>
18
+ <![endif]--><!--[if lte mso 11]>
19
+ <style type="text/css">
20
+ .outlook-group-fix { width:100% !important; }
21
+ </style>
22
+ <![endif]--><!--[if !mso]><!--><link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700" rel="stylesheet" type="text/css"><style type="text/css">@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);</style><!--<![endif]--><style type="text/css">@media only screen and (min-width:480px) {
23
+ .mj-column-per-100 { width:100% !important; max-width: 100%; }
24
+ }</style><style type="text/css"></style></head><body style="background-color:#ffffff;"><div style="background-color:#ffffff;"><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="Margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 outlook-group-fix" style="font-size:13px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tr><td style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 4px #555555;font-size:1;margin:0px auto;width:100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 4px #555555;font-size:1;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;"> &nbsp;
25
+ </td></tr></table><![endif]--></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:helvetica;font-size:20px;line-height:1;text-align:left;color:#555555;">{{ project_name }}</div></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#555555;">Test email for: {{ email }}</div></td></tr></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
@@ -0,0 +1,160 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Email de Bienvenue</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
9
+ <style type="text/css">
10
+ body {
11
+ font-family: "Inter", Arial, sans-serif;
12
+ width: 100%;
13
+ max-width: 640px;
14
+ margin: 0;
15
+ padding: 0;
16
+ color: #4f4d55;
17
+ background-color: #f4f4f4;
18
+ }
19
+
20
+ header img {
21
+ max-width: 130px;
22
+ }
23
+
24
+ main {
25
+ padding: 32px 24px;
26
+ }
27
+
28
+ main p {
29
+ font-size: 16px;
30
+ line-height: 24px;
31
+ margin-bottom: 16px;
32
+ }
33
+
34
+ main div {
35
+ margin-top: 32px;
36
+ }
37
+
38
+ footer {
39
+ width: 100%;
40
+ font-size: 14px;
41
+ line-height: 20px;
42
+ }
43
+
44
+ footer p span {
45
+ color: #fc5933;
46
+ text-decoration: underline;
47
+ cursor: pointer;
48
+ }
49
+
50
+ footer div.social {
51
+ margin-top: 48px;
52
+
53
+ }
54
+
55
+ .footer-image {
56
+ max-width: 90px;
57
+ }
58
+
59
+ .social-icons img {
60
+ width: 20px;
61
+ height: 20px;
62
+ }
63
+
64
+ .social-icons {
65
+ float: right;
66
+ }
67
+
68
+ .social-icons a {
69
+ margin-left: 16px;
70
+ text-decoration: none;
71
+ }
72
+
73
+ @media (max-width: 600px) {
74
+ main {
75
+ padding: 16px;
76
+ }
77
+
78
+ footer {
79
+ padding: 16px;
80
+ }
81
+
82
+ footer div {
83
+ flex-direction: column;
84
+ gap: 16px;
85
+ }
86
+ }
87
+ </style>
88
+ </head>
89
+
90
+ <body>
91
+ <header>
92
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
93
+ alt="Logo de Boilerplate" />
94
+ </header>
95
+ <main>
96
+ <p>Bienvenue sur Boilerplate!</p>
97
+ <p>
98
+ Nous sommes ravis de vous compter parmi nous ! Vous êtes déjà sur la
99
+ bonne voie pour développer vos compétences et atteindre de nouveaux
100
+ sommets dans votre carrière.
101
+ </p>
102
+ <p>
103
+ Que ce soit pour évoluer dans votre entreprise, acquérir de nouvelles
104
+ compétences, ou simplement pour le plaisir d'apprendre, bienvenue dans
105
+ notre communauté ! Si vous avez besoin de quoi que ce soit, nous serons
106
+ là à chaque étape du processus.
107
+ </p>
108
+ <p>Merci,<br />L'équipe Boilerplate.</p>
109
+ <div>
110
+ <a href="{{ url }}" style="
111
+ color: #ffffff;
112
+ font-weight: 500;
113
+ size: 16px;
114
+ line-height: 24px;
115
+ background-color: #fc5933;
116
+ text-decoration: none;
117
+ width: 134px;
118
+ height: 44px;
119
+ padding: 10px 16px;
120
+ border: 1.5px;
121
+ border-radius: 99px;
122
+ ">Se connecter</a>
123
+ </div>
124
+ </main>
125
+ <footer>
126
+ <div>
127
+ <p>
128
+ Ce courriel a été envoyé à <span>{{ email }}</span>. Si vous préférez
129
+ ne pas recevoir ce type d'e-mail, vous pouvez vous
130
+ <span>désabonner</span> ou
131
+ <span>gérer vos préférences en matière d'e-mail</span>.
132
+ </p>
133
+ <p>&copy; Boilerplate co., 38 Rue Legendre, 75017 Paris, France</p>
134
+ </div>
135
+
136
+ <div class="social" style="width: 100%">
137
+ <div style="float: left">
138
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
139
+ alt="Logo de Boilerplate" class="footer-image" />
140
+ </div>
141
+ <div class="social-icons">
142
+ <a href="https://www.twitter.com/nomdelentreprise" target="_blank">
143
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986108/test/twitter_xnqzgi.png" alt="X" />
144
+ </a>
145
+ <a href="https://www.facebook.com/nomdelentreprise" target="_blank">
146
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986190/test/facebook_yafqw6.png"
147
+ alt="Facebook" />
148
+ </a>
149
+ <a href="https://www.instagram.com/nomdelentreprise" target="_blank">
150
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png" alt="Instagram" />
151
+ </a>
152
+ <a href="https://www.linkedin.com/company/nomdelentreprise" target="_blank">
153
+ <img src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png" alt="LinkedIn" />
154
+ </a>
155
+ </div>
156
+ </div>
157
+ </footer>
158
+ </body>
159
+
160
+ </html>
@@ -0,0 +1,178 @@
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Email de Bienvenue</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet" />
9
+ <style type="text/css">
10
+ body {
11
+ font-family: "Inter", Arial, sans-serif;
12
+ width: 100%;
13
+ margin: 0;
14
+ padding: 0;
15
+ color: #4f4d55;
16
+ background-color: #f4f4f4;
17
+ }
18
+
19
+ table {
20
+ width: 100%;
21
+ max-width: 640px;
22
+ margin: auto;
23
+ background-color: #ffffff;
24
+ }
25
+
26
+ td {
27
+ padding: 0;
28
+ }
29
+
30
+ img {
31
+ display: block;
32
+ border: 0;
33
+ }
34
+
35
+ .header,
36
+ .footer {
37
+ width: 100%;
38
+ padding-top: 20px;
39
+ }
40
+
41
+ .main p {
42
+ font-size: 16px;
43
+ line-height: 24px;
44
+ margin-bottom: 16px;
45
+ }
46
+
47
+ .button {
48
+ display: inline-block;
49
+ color: #ffffff;
50
+ font-weight: 500;
51
+ font-size: 16px;
52
+ line-height: 24px;
53
+ background-color: #fc5933;
54
+ text-decoration: none;
55
+ padding: 10px 16px;
56
+ border-radius: 99px;
57
+ text-align: center;
58
+ }
59
+
60
+ .footer-image {
61
+ max-width: 90px;
62
+ }
63
+
64
+ .social-icons img {
65
+ width: 20px;
66
+ height: 20px;
67
+ }
68
+
69
+ .social-icons a {
70
+ display: inline-block;
71
+ margin-left: 16px;
72
+ text-decoration: none;
73
+ }
74
+
75
+ .social-icons {
76
+ float: right;
77
+ }
78
+
79
+ .footer p {
80
+ font-size: 14px;
81
+ line-height: 20px;
82
+ }
83
+
84
+ .footer span {
85
+ color: #fc5933;
86
+ text-decoration: underline;
87
+ cursor: pointer;
88
+ }
89
+
90
+ @media (max-width: 600px) {
91
+ .social-icons {
92
+ text-align: center;
93
+ }
94
+
95
+ .social-icons a {
96
+ display: inline-block;
97
+ margin-left: 8px;
98
+ margin-right: 8px;
99
+ }
100
+
101
+ .footer {
102
+ text-align: center;
103
+ }
104
+ }
105
+ </style>
106
+ </head>
107
+
108
+ <body>
109
+ <table cellpadding="0" cellspacing="0">
110
+ <tr>
111
+ <td class="header">
112
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
113
+ alt="Logo de Boilerplate" width="130" />
114
+ </td>
115
+ </tr>
116
+ <tr>
117
+ <td class="main">
118
+ <p>Bienvenue sur Boilerplate!</p>
119
+ <p>
120
+ Nous sommes ravis de vous compter parmi nous ! Vous êtes déjà sur la
121
+ bonne voie pour développer vos compétences et atteindre de nouveaux
122
+ sommets dans votre carrière.
123
+ </p>
124
+ <p>
125
+ Que ce soit pour évoluer dans votre entreprise, acquérir de
126
+ nouvelles compétences, ou simplement pour le plaisir d'apprendre,
127
+ bienvenue dans notre communauté ! Si vous avez besoin de quoi que ce
128
+ soit, nous serons là à chaque étape du processus.
129
+ </p>
130
+ <p>Merci,<br />L'équipe Boilerplate.</p>
131
+ <table cellpadding="0" cellspacing="0" width="100%" style="margin-top: 32px">
132
+ <tr>
133
+ <td align="left">
134
+ <a href="{{ link }}">
135
+ <div class="button">Verifier mon compte</div>
136
+ </a>
137
+ </td>
138
+ </tr>
139
+ </table>
140
+ </td>
141
+ </tr>
142
+ <tr>
143
+ <td class="footer">
144
+ <p>
145
+ Ce courriel a été envoyé à <span>{{ email }}</span>. Si vous
146
+ préférez ne pas recevoir ce type d'e-mail, vous pouvez vous
147
+ <span>désabonner</span> ou
148
+ <span>gérer vos préférences en matière d'e-mail</span>.
149
+ </p>
150
+ <p>&copy; Boilerplate co., 38 Rue Legendre, 75017 Paris, France</p>
151
+ <div class="social" style="width: 100%">
152
+ <div style="float: left">
153
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718814671/test/Logo_nsmysd.png"
154
+ alt="Logo de Boilerplate" class="footer-image" />
155
+ </div>
156
+ <div class="social-icons">
157
+ <a href="https://www.twitter.com/nomdelentreprise" target="_blank">
158
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986108/test/twitter_xnqzgi.png" alt="X" />
159
+ </a>
160
+ <a href="https://www.facebook.com/nomdelentreprise" target="_blank">
161
+ <img src="http://res.cloudinary.com/dhkvaew6n/raw/upload/v1718986190/test/facebook_yafqw6.png"
162
+ alt="Facebook" />
163
+ </a>
164
+ <a href="https://www.instagram.com/nomdelentreprise" target="_blank">
165
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a5/Instagram_icon.png" alt="Instagram" />
166
+ </a>
167
+ <a href="https://www.linkedin.com/company/nomdelentreprise" target="_blank">
168
+ <img src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png"
169
+ alt="LinkedIn" />
170
+ </a>
171
+ </div>
172
+ </div>
173
+ </td>
174
+ </tr>
175
+ </table>
176
+ </body>
177
+
178
+ </html>