-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/go-backend/internal/web/views/auth_components_templ.go b/go-backend/internal/web/views/auth_components_templ.go
new file mode 100644
index 0000000..0c424ab
--- /dev/null
+++ b/go-backend/internal/web/views/auth_components_templ.go
@@ -0,0 +1,575 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.1001
+package views
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+func LoginScreen() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AuthScreen(
+ "Se connecter à Xtablo",
+ "/login-v2",
+ "Découvrez la nouvelle expérience de connexion",
+ LoginForm(),
+ AuthScreenFooter("Pas encore de compte ?", "/signup", "S'inscrire"),
+ ).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SignupScreen() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var2 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var2 == nil {
+ templ_7745c5c3_Var2 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AuthScreen(
+ "S'inscrire à Xtablo",
+ "/login",
+ "Vous avez déjà un compte ?",
+ SignupForm(),
+ AuthScreenFooter("Vous avez déjà un compte ?", "/login", "Se connecter"),
+ ).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AuthScreen(title string, helperHref string, helperLabel string, form templ.Component, footer templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var3 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var3 == nil {
+ templ_7745c5c3_Var3 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var4 string
+ templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(title)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 25, Col: 13}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = form.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = AuthDivider().Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = GoogleButton().Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = footer.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func LoginForm() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var7 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var7 == nil {
+ templ_7745c5c3_Var7 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SignupForm() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var8 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var8 == nil {
+ templ_7745c5c3_Var8 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AuthField(fieldID string, fieldName string, fieldLabel string, inputType string, placeholder string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var9 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var9 == nil {
+ templ_7745c5c3_Var9 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fieldLabel)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 61, Col: 37}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AuthScreenFooter(copy string, href string, label string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var16 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var16 == nil {
+ templ_7745c5c3_Var16 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var17 string
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(copy)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 68, Col: 8}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var19 string
+ templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(label)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 69, Col: 61}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AuthStatus(kind string, message string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var20 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var20 == nil {
+ templ_7745c5c3_Var20 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ if kind == "success" {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var21 string
+ templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(message)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 75, Col: 67}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else if kind == "error" {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var22 string
+ templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(message)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/auth_components.templ`, Line: 77, Col: 64}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+func AuthDivider() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var23 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var23 == nil {
+ templ_7745c5c3_Var23 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func GoogleButton() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var24 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var24 == nil {
+ templ_7745c5c3_Var24 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
Continuer avec Google Sign in with Google ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AnimatedBackground() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var25 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var25 == nil {
+ templ_7745c5c3_Var25 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/go-backend/internal/web/views/dashboard_components.templ b/go-backend/internal/web/views/dashboard_components.templ
new file mode 100644
index 0000000..eb464dd
--- /dev/null
+++ b/go-backend/internal/web/views/dashboard_components.templ
@@ -0,0 +1,330 @@
+package views
+
+templ DashboardPage(activePath string, content templ.Component) {
+
+
+
+
+
+
XTablo
+
+
+
+
+
+ @DashboardSidebar(activePath)
+ @DashboardMainContent(content)
+
+
+
+}
+
+templ DashboardNotFoundPage(displayName string, email string) {
+ @DashboardPage("", NotFoundContent(displayName))
+}
+
+templ DashboardMainContent(content templ.Component) {
+
+ @content
+
+}
+
+templ DashboardContentSwap(activePath string, content templ.Component) {
+ @DashboardMainContent(content)
+ @DashboardNavOOB(activePath)
+}
+
+templ DashboardSidebar(activePath string) {
+
+}
+
+templ DashboardNavOOB(activePath string) {
+ for _, item := range sidebarPrimaryNavItems(activePath) {
+ @SidebarNavItemOOB(item)
+ }
+ for _, item := range sidebarFooterNavItems(activePath) {
+ @SidebarNavItemOOB(item)
+ }
+}
+
+templ SidebarOrganization() {
+
+}
+
+templ OverviewMainContent(displayName string, email string) {
+
+ @OverviewHeader(displayName)
+ @OverviewActions(overviewQuickActions())
+ @OverviewProjects(overviewProjects())
+ @OverviewTasks(overviewTasks())
+
+}
+
+templ TasksMainContent() {
+ @AppSectionMainContent("Tâches", "Suivez les tâches de votre équipe, les priorités en cours et ce qui reste à livrer.")
+}
+
+templ TablosMainContent() {
+ @AppSectionMainContent("Projets", "Gardez une vue claire sur vos tablos, leur état d'avancement et les prochaines décisions à prendre.")
+}
+
+templ PlanningMainContent() {
+ @AppSectionMainContent("Planning", "Visualisez le rythme de l'équipe, les jalons à venir et les arbitrages de charge.")
+}
+
+templ ChatMainContent() {
+ @AppSectionMainContent("Discussions", "Retrouvez les conversations importantes, les décisions récentes et les échanges à relancer.")
+}
+
+templ FilesMainContent() {
+ @AppSectionMainContent("Fichiers", "Centralisez les documents utiles, les pièces partagées et les ressources de travail.")
+}
+
+templ FeedbackMainContent() {
+ @AppSectionMainContent("Feedback", "Collectez les retours produit, priorisez les signaux et transformez-les en actions concrètes.")
+}
+
+templ AppSectionMainContent(title string, description string) {
+
+
+
Espace de travail
+
{ title }
+
{ description }
+
+
+}
+
+templ NotFoundContent(displayName string) {
+
+
+
Erreur de navigation
+
404
+
Page introuvable
+
Cette page n'existe pas ou n'est plus disponible.
+
+
+ Connecté en tant que
+ { dashboardGreetingName(displayName) }
+
+
+
+}
+
+templ OverviewHeader(displayName string) {
+
+}
+
+templ OverviewActions(actions []quickAction) {
+
+ for _, action := range actions {
+ @QuickActionCard(action)
+ }
+
+}
+
+templ OverviewProjects(projects []dashboardProject) {
+
+
+
Mes Projets
+
+
+ for _, project := range projects {
+ @ProjectCard(project)
+ }
+
+
+
+ Voir 11 de plus
+
+
+
+
+
+
+}
+
+templ OverviewTasks(tasks []dashboardTask) {
+
+
+
+ for _, task := range tasks {
+ @TaskRow(task)
+ }
+
+
+}
+
+templ QuickActionCard(action quickAction) {
+
+
+ @ActionIcon(action.Icon)
+
+
+
{ action.Title }
+
{ action.Description }
+
+
+}
+
+templ ProjectCard(project dashboardProject) {
+
+
+ { project.Status }
+
+ @ActionIcon("trash")
+
+
+
+
+ { project.Initial }
+
+
{ project.Title }
+
+
+ @ActionIcon("calendar")
+ { project.Date }
+
+
+
+ Progression:
+ { progressPercentLabel(project.Progress) }
+
+
+
+
+}
+
+templ TaskRow(task dashboardTask) {
+
+
+ if task.Completed {
+ @ActionIcon("check-circle")
+ }
+
+
+
{ task.Status }
+
+}
+
+templ SidebarNavItem(item sidebarNavItem) {
+
+
+
+}
+
+templ SidebarNavItemOOB(item sidebarNavItem) {
+
+
+
+}
+
+templ SidebarProjectItem(item sidebarProjectItem) {
+
+}
diff --git a/go-backend/internal/web/views/dashboard_components_templ.go b/go-backend/internal/web/views/dashboard_components_templ.go
new file mode 100644
index 0000000..a21f8a7
--- /dev/null
+++ b/go-backend/internal/web/views/dashboard_components_templ.go
@@ -0,0 +1,1523 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.1001
+package views
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+func DashboardPage(activePath string, content templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
XTablo ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = DashboardSidebar(activePath).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = DashboardMainContent(content).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func DashboardNotFoundPage(displayName string, email string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var2 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var2 == nil {
+ templ_7745c5c3_Var2 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = DashboardPage("", NotFoundContent(displayName)).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func DashboardMainContent(content templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var3 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var3 == nil {
+ templ_7745c5c3_Var3 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = content.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func DashboardContentSwap(activePath string, content templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var4 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var4 == nil {
+ templ_7745c5c3_Var4 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = DashboardMainContent(content).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = DashboardNavOOB(activePath).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func DashboardSidebar(activePath string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var5 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var5 == nil {
+ templ_7745c5c3_Var5 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func DashboardNavOOB(activePath string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var6 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var6 == nil {
+ templ_7745c5c3_Var6 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ for _, item := range sidebarPrimaryNavItems(activePath) {
+ templ_7745c5c3_Err = SidebarNavItemOOB(item).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ for _, item := range sidebarFooterNavItems(activePath) {
+ templ_7745c5c3_Err = SidebarNavItemOOB(item).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+func SidebarOrganization() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var7 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var7 == nil {
+ templ_7745c5c3_Var7 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func OverviewMainContent(displayName string, email string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var8 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var8 == nil {
+ templ_7745c5c3_Var8 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = OverviewHeader(displayName).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = OverviewActions(overviewQuickActions()).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = OverviewProjects(overviewProjects()).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = OverviewTasks(overviewTasks()).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func TasksMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var9 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var9 == nil {
+ templ_7745c5c3_Var9 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Tâches", "Suivez les tâches de votre équipe, les priorités en cours et ce qui reste à livrer.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func TablosMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var10 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var10 == nil {
+ templ_7745c5c3_Var10 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Projets", "Gardez une vue claire sur vos tablos, leur état d'avancement et les prochaines décisions à prendre.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func PlanningMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var11 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var11 == nil {
+ templ_7745c5c3_Var11 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Planning", "Visualisez le rythme de l'équipe, les jalons à venir et les arbitrages de charge.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func ChatMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var12 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var12 == nil {
+ templ_7745c5c3_Var12 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Discussions", "Retrouvez les conversations importantes, les décisions récentes et les échanges à relancer.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func FilesMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var13 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var13 == nil {
+ templ_7745c5c3_Var13 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Fichiers", "Centralisez les documents utiles, les pièces partagées et les ressources de travail.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func FeedbackMainContent() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var14 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var14 == nil {
+ templ_7745c5c3_Var14 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AppSectionMainContent("Feedback", "Collectez les retours produit, priorisez les signaux et transformez-les en actions concrètes.").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func AppSectionMainContent(title string, description string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var15 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var15 == nil {
+ templ_7745c5c3_Var15 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
Espace de travail
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var16 string
+ templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(title)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 143, Col: 14}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var17 string
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(description)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 144, Col: 19}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func NotFoundContent(displayName string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var18 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var18 == nil {
+ templ_7745c5c3_Var18 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
Erreur de navigation
404
Page introuvable Cette page n'existe pas ou n'est plus disponible.
Connecté en tant que ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var19 string
+ templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(dashboardGreetingName(displayName))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 164, Col: 48}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func OverviewHeader(displayName string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var20 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var20 == nil {
+ templ_7745c5c3_Var20 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func OverviewActions(actions []quickAction) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var23 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var23 == nil {
+ templ_7745c5c3_Var23 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, action := range actions {
+ templ_7745c5c3_Err = QuickActionCard(action).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func OverviewProjects(projects []dashboardProject) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var24 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var24 == nil {
+ templ_7745c5c3_Var24 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
Mes Projets ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, project := range projects {
+ templ_7745c5c3_Err = ProjectCard(project).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func OverviewTasks(tasks []dashboardTask) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var25 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var25 == nil {
+ templ_7745c5c3_Var25 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, task := range tasks {
+ templ_7745c5c3_Err = TaskRow(task).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func QuickActionCard(action quickAction) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var26 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var26 == nil {
+ templ_7745c5c3_Var26 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = ActionIcon(action.Icon).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var27 string
+ templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(action.Title)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 240, Col: 49}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var28 string
+ templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(action.Description)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 241, Col: 26}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func ProjectCard(project dashboardProject) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var29 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var29 == nil {
+ templ_7745c5c3_Var29 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var30 = []any{"project-status " + toneClass(project.StatusTone)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var30...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var32 string
+ templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(project.Status)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 249, Col: 85}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = ActionIcon("trash").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var33 = []any{"project-avatar " + projectAccentClass(project.Accent)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var33...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var35 string
+ templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(project.Initial)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 256, Col: 27}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var36 string
+ templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(project.Title)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 258, Col: 22}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = ActionIcon("calendar").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var37 string
+ templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(project.Date)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 262, Col: 23}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "
Progression: ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var38 string
+ templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(progressPercentLabel(project.Progress))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 267, Col: 52}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var39 = []any{"project-progress-bar " + projectAccentClass(project.Accent)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var39...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func TaskRow(task dashboardTask) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var42 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var42 == nil {
+ templ_7745c5c3_Var42 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ var templ_7745c5c3_Var43 = []any{taskRowClass(task.Completed)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var43...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var45 = []any{taskCheckClass(task.Completed)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var45...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if task.Completed {
+ templ_7745c5c3_Err = ActionIcon("check-circle").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var47 string
+ templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(task.Title)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 284, Col: 18}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var53 = []any{"task-status " + toneClass(task.StatusTone)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var53...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var55 string
+ templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(task.Status)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/dashboard_components.templ`, Line: 293, Col: 75}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SidebarNavItem(item sidebarNavItem) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var56 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var56 == nil {
+ templ_7745c5c3_Var56 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ var templ_7745c5c3_Var57 = []any{sidebarNavItemClass(item.Active)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var57...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SidebarNavItemOOB(item sidebarNavItem) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var63 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var63 == nil {
+ templ_7745c5c3_Var63 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ var templ_7745c5c3_Var64 = []any{sidebarNavItemClass(item.Active)}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var64...)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SidebarProjectItem(item sidebarProjectItem) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var70 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var70 == nil {
+ templ_7745c5c3_Var70 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/go-backend/internal/web/views/home.go b/go-backend/internal/web/views/home.go
new file mode 100644
index 0000000..e05f6ca
--- /dev/null
+++ b/go-backend/internal/web/views/home.go
@@ -0,0 +1,195 @@
+package views
+
+import (
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/a-h/templ"
+)
+
+func sidebarNavItemClass(active bool) string {
+ if active {
+ return "sidebar-nav-item is-active"
+ }
+ return "sidebar-nav-item"
+}
+
+func isActivePath(activePath string, href string) bool {
+ return strings.TrimSpace(activePath) != "" && activePath == href
+}
+
+func sidebarNavItemID(href string) string {
+ switch href {
+ case "/":
+ return "sidebar-nav-home"
+ default:
+ slug := strings.Trim(strings.ReplaceAll(href, "/", "-"), "-")
+ if slug == "" {
+ slug = "item"
+ }
+ return "sidebar-nav-" + slug
+ }
+}
+
+type quickAction struct {
+ Title string
+ Description string
+ Icon string
+}
+
+type sidebarNavItem struct {
+ Href string
+ Label string
+ Icon string
+ Active bool
+ DividerAfter bool
+}
+
+type sidebarProjectItem struct {
+ Href string
+ Label string
+ Icon string
+}
+
+type dashboardProject struct {
+ Title string
+ Status string
+ StatusTone string
+ Initial string
+ Accent string
+ Date string
+ Progress int
+}
+
+type dashboardTask struct {
+ Title string
+ Project string
+ ProjectKey string
+ ProjectHue string
+ Date string
+ Status string
+ StatusTone string
+ Completed bool
+}
+
+func dashboardDateLabel(now time.Time) string {
+ return now.Format("Monday, January 2")
+}
+
+func dashboardTodayLabel() string {
+ return dashboardDateLabel(time.Now())
+}
+
+func dashboardGreetingName(displayName string) string {
+ displayName = strings.TrimSpace(displayName)
+ if displayName == "" {
+ return "Arthur"
+ }
+ if len(displayName) == 1 {
+ return strings.ToUpper(displayName)
+ }
+ return strings.ToUpper(displayName[:1]) + displayName[1:]
+}
+
+func overviewQuickActions() []quickAction {
+ return []quickAction{
+ {Title: "Créer un projet", Description: "Définir les objectifs et le périmètre", Icon: "folder-plus"},
+ {Title: "Créer une tâche", Description: "Découper le travail en actions", Icon: "circle-plus"},
+ {Title: "Inviter l'équipe", Description: "Ajouter des collaborateurs", Icon: "user-plus"},
+ {Title: "Envoyer un message", Description: "Communiquer rapidement", Icon: "chat"},
+ }
+}
+
+func overviewProjects() []dashboardProject {
+ return []dashboardProject{
+ {Title: "Hello", Status: "En cours", StatusTone: "warning", Initial: "H", Accent: "blue", Date: "Apr 15, 2026", Progress: 50},
+ {Title: "Jean Macon interet pour le produit de ta mere", Status: "En cours", StatusTone: "warning", Initial: "J", Accent: "purple", Date: "Nov 18, 2025", Progress: 50},
+ {Title: "bikip56648 / Arthur Belleville", Status: "En cours", StatusTone: "warning", Initial: "B", Accent: "blue", Date: "Nov 06, 2025", Progress: 50},
+ {Title: "lsdkfjsl / Arthur Belleville", Status: "À faire", StatusTone: "info", Initial: "L", Accent: "blue", Date: "Oct 26, 2025", Progress: 0},
+ {Title: "Hello / Arthur Belleville", Status: "À faire", StatusTone: "info", Initial: "H", Accent: "blue", Date: "Oct 26, 2025", Progress: 0},
+ {Title: "Wes Ocif / Arthur", Status: "À faire", StatusTone: "info", Initial: "W", Accent: "blue", Date: "Oct 20, 2025", Progress: 0},
+ }
+}
+
+func overviewTasks() []dashboardTask {
+ return []dashboardTask{
+ {Title: "yo", Project: "Hello", ProjectKey: "H", ProjectHue: "blue", Date: "Apr 16, 2026", Status: "À faire", StatusTone: "info", Completed: false},
+ {Title: "yo", Project: "Hello", ProjectKey: "H", ProjectHue: "blue", Date: "Apr 16, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
+ {Title: "hello", Project: "margot", ProjectKey: "M", ProjectHue: "red", Date: "Mar 7, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
+ {Title: "Bonjour", Project: "Jean Macon interet pour le produit de ta mere", ProjectKey: "J", ProjectHue: "purple", Date: "Feb 24, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
+ {Title: "Bonjour", Project: "Jean Macon interet pour le produit de ta mere", ProjectKey: "J", ProjectHue: "purple", Date: "Feb 21, 2026", Status: "Terminé", StatusTone: "success", Completed: true},
+ {Title: "Faire ceci", Project: "bikip56648 / Arthur Belleville", ProjectKey: "B", ProjectHue: "blue", Date: "Nov 18, 2025", Status: "Terminé", StatusTone: "success", Completed: true},
+ {Title: "Hello monsieur", Project: "bikip56648 / Arthur Belleville", ProjectKey: "B", ProjectHue: "blue", Date: "Nov 18, 2025", Status: "Terminé", StatusTone: "success", Completed: true},
+ }
+}
+
+func sidebarPrimaryNavItems(activePath string) []sidebarNavItem {
+ return []sidebarNavItem{
+ {Href: "/", Label: "Aperçu", Icon: "panels", Active: isActivePath(activePath, "/"), DividerAfter: true},
+ {Href: "/tasks", Label: "Tâches", Icon: "tasks", Active: isActivePath(activePath, "/tasks")},
+ {Href: "/tablos", Label: "Projets", Icon: "layers", Active: isActivePath(activePath, "/tablos"), DividerAfter: true},
+ {Href: "/planning", Label: "Planning", Icon: "planning", Active: isActivePath(activePath, "/planning")},
+ {Href: "/chat", Label: "Discussions", Icon: "chat", Active: isActivePath(activePath, "/chat")},
+ {Href: "/files", Label: "Fichiers", Icon: "files", Active: isActivePath(activePath, "/files")},
+ }
+}
+
+func sidebarProjectItems() []sidebarProjectItem {
+ return []sidebarProjectItem{
+ {Href: "/tablos/hello", Label: "Hello", Icon: "bolt"},
+ {Href: "/tablos/atelier", Label: "Atelier Produit", Icon: "gem"},
+ {Href: "/tablos/arthur", Label: "Arthur Belleville", Icon: "bolt"},
+ {Href: "/tablos/equipe", Label: "Equipe Design", Icon: "bolt"},
+ }
+}
+
+func sidebarFooterNavItems(activePath string) []sidebarNavItem {
+ return []sidebarNavItem{
+ {Href: "/feedback", Label: "Feedback", Icon: "send", Active: isActivePath(activePath, "/feedback")},
+ }
+}
+
+func toneClass(tone string) string {
+ switch tone {
+ case "warning":
+ return "tone-warning"
+ case "success":
+ return "tone-success"
+ default:
+ return "tone-info"
+ }
+}
+
+func projectAccentClass(accent string) string {
+ switch accent {
+ case "purple":
+ return "project-accent-purple"
+ case "red":
+ return "project-accent-red"
+ default:
+ return "project-accent-blue"
+ }
+}
+
+func taskRowClass(completed bool) string {
+ if completed {
+ return "task-row is-complete"
+ }
+ return "task-row"
+}
+
+func taskCheckClass(completed bool) string {
+ if completed {
+ return "task-check is-complete"
+ }
+ return "task-check"
+}
+
+func progressPercentLabel(progress int) string {
+ return fmt.Sprintf("%d%%", progress)
+}
+
+func progressInlineStyle(progress int) templ.SafeCSS {
+ return templ.SanitizeCSS("width", templ.SafeCSSProperty(progressPercentLabel(progress)))
+}
diff --git a/go-backend/internal/web/views/icons.templ b/go-backend/internal/web/views/icons.templ
new file mode 100644
index 0000000..d7e4a44
--- /dev/null
+++ b/go-backend/internal/web/views/icons.templ
@@ -0,0 +1,102 @@
+package views
+
+templ ActionIcon(kind string) {
+ switch kind {
+ case "folder-plus":
+
+
+
+
+
+ case "circle-plus":
+
+
+
+
+
+ case "user-plus":
+
+
+
+
+
+
+ case "trash":
+
+
+
+
+
+
+
+ case "calendar":
+
+
+
+
+
+
+ case "check-circle":
+
+
+
+
+ default:
+ @SidebarIcon(kind)
+ }
+}
+
+templ SidebarIcon(kind string) {
+ switch kind {
+ case "panels":
+
+
+
+
+
+ case "tasks":
+
+
+
+
+
+
+
+ case "layers":
+
+
+
+
+
+ case "planning":
+
+
+
+
+
+
+ case "chat":
+
+
+
+ case "files":
+
+
+
+ case "send":
+
+
+
+
+ case "gem":
+
+
+
+
+
+ default:
+
+
+
+ }
+}
diff --git a/go-backend/internal/web/views/icons_templ.go b/go-backend/internal/web/views/icons_templ.go
new file mode 100644
index 0000000..b95c056
--- /dev/null
+++ b/go-backend/internal/web/views/icons_templ.go
@@ -0,0 +1,145 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.1001
+package views
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+func ActionIcon(kind string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ switch kind {
+ case "folder-plus":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "circle-plus":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "user-plus":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "trash":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "calendar":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "check-circle":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ default:
+ templ_7745c5c3_Err = SidebarIcon(kind).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+func SidebarIcon(kind string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var2 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var2 == nil {
+ templ_7745c5c3_Var2 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ switch kind {
+ case "panels":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "tasks":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "layers":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "planning":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "chat":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "files":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "send":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case "gem":
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ default:
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/go-backend/internal/web/views/login_templ.go b/go-backend/internal/web/views/login_templ.go
deleted file mode 100644
index f508771..0000000
--- a/go-backend/internal/web/views/login_templ.go
+++ /dev/null
@@ -1,342 +0,0 @@
-// Code generated by templ - DO NOT EDIT.
-
-// templ: version: v0.3.1001
-package views
-
-//lint:file-ignore SA4006 This context is only used if a nested component is present.
-
-import "github.com/a-h/templ"
-import templruntime "github.com/a-h/templ/runtime"
-
-func AuthPage(content templ.Component) templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var1 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var1 == nil {
- templ_7745c5c3_Var1 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
XTablo ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = AnimatedBackground().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = content.Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func LoginScreen() templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var2 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var2 == nil {
- templ_7745c5c3_Var2 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
Se connecter à Xtablo ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = AuthDivider().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = GoogleButton().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
Pas encore de compte ? S'inscrire
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func SignupScreen() templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var3 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var3 == nil {
- templ_7745c5c3_Var3 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
S'inscrire à Xtablo ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = AuthDivider().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = GoogleButton().Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
Vous avez déjà un compte ? Se connecter
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func HomePage(displayName string, email string) templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var4 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var4 == nil {
- templ_7745c5c3_Var4 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
XTablo Bienvenue ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var5 string
- templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(displayName)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/login.templ`, Line: 135, Col: 21}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
Session active pour ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(email)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/login.templ`, Line: 136, Col: 35}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func AuthStatus(kind string, message string) templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var7 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var7 == nil {
- templ_7745c5c3_Var7 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- if kind == "success" {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var8 string
- templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(message)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/login.templ`, Line: 148, Col: 67}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- } else if kind == "error" {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var9 string
- templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(message)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/web/views/login.templ`, Line: 150, Col: 64}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
- return nil
- })
-}
-
-func AuthDivider() templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var10 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var10 == nil {
- templ_7745c5c3_Var10 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func GoogleButton() templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var11 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var11 == nil {
- templ_7745c5c3_Var11 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
Continuer avec Google Sign in with Google ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func AnimatedBackground() templ.Component {
- return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
- templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
- if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
- return templ_7745c5c3_CtxErr
- }
- templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
- if !templ_7745c5c3_IsBuffer {
- defer func() {
- templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err == nil {
- templ_7745c5c3_Err = templ_7745c5c3_BufErr
- }
- }()
- }
- ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var12 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var12 == nil {
- templ_7745c5c3_Var12 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-var _ = templruntime.GeneratedTemplate
diff --git a/go-backend/internal/web/views/pages.templ b/go-backend/internal/web/views/pages.templ
new file mode 100644
index 0000000..8c3c58b
--- /dev/null
+++ b/go-backend/internal/web/views/pages.templ
@@ -0,0 +1,70 @@
+package views
+
+templ AuthPage(content templ.Component) {
+
+
+
+
+
+
+
+
+
+
+
+
+
XTablo
+
+
+
+
+
+
+
+
+ @AnimatedBackground()
+
+
+
+
+
+
+
+
+ @content
+
+
+
+
+
+
+
+}
+
+templ LoginPage() {
+ @AuthPage(LoginScreen())
+}
+
+templ SignupPage() {
+ @AuthPage(SignupScreen())
+}
+
+templ HomePage(displayName string, email string) {
+ @DashboardPage("/", OverviewMainContent(displayName, email))
+}
diff --git a/go-backend/internal/web/views/pages_templ.go b/go-backend/internal/web/views/pages_templ.go
new file mode 100644
index 0000000..de124ea
--- /dev/null
+++ b/go-backend/internal/web/views/pages_templ.go
@@ -0,0 +1,143 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.1001
+package views
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+func AuthPage(content templ.Component) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
XTablo ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = AnimatedBackground().Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = content.Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func LoginPage() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var2 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var2 == nil {
+ templ_7745c5c3_Var2 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AuthPage(LoginScreen()).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func SignupPage() templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var3 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var3 == nil {
+ templ_7745c5c3_Var3 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = AuthPage(SignupScreen()).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+func HomePage(displayName string, email string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var4 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var4 == nil {
+ templ_7745c5c3_Var4 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = DashboardPage("/", OverviewMainContent(displayName, email)).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/go-backend/router.go b/go-backend/router.go
index fc9cd2a..999b974 100644
--- a/go-backend/router.go
+++ b/go-backend/router.go
@@ -31,6 +31,12 @@ func newRouterWithHandler(authHandler *handlers.AuthHandler) http.Handler {
// Views
mux.Get("/", authHandler.GetHome())
+ mux.Get("/tasks", authHandler.GetTasksPage())
+ mux.Get("/tablos", authHandler.GetTablosPage())
+ mux.Get("/planning", authHandler.GetPlanningPage())
+ mux.Get("/chat", authHandler.GetChatPage())
+ mux.Get("/files", authHandler.GetFilesPage())
+ mux.Get("/feedback", authHandler.GetFeedbackPage())
mux.Get("/login", authHandler.GetLoginPage())
mux.Get("/signup", authHandler.GetSignupPage())
mux.Post("/login", authHandler.PostLogin())
@@ -42,6 +48,7 @@ func newRouterWithHandler(authHandler *handlers.AuthHandler) http.Handler {
mux.HandleFunc("/logo_dark.png", serveStaticFile(staticFS, "logo_dark.png", "image/png"))
mux.HandleFunc("/logo_white.png", serveStaticFile(staticFS, "logo_white.png", "image/png"))
mux.HandleFunc("/manifest.webmanifest", serveStaticFile(staticFS, "manifest.webmanifest", "application/manifest+json"))
+ mux.NotFound(authHandler.GetNotFound())
return mux
}
diff --git a/go-backend/router_test.go b/go-backend/router_test.go
index fc1b908..f720c68 100644
--- a/go-backend/router_test.go
+++ b/go-backend/router_test.go
@@ -6,6 +6,8 @@ import (
"net/url"
"strings"
"testing"
+
+ "xtablo-backend/internal/web/handlers"
)
func TestRootRedirectsToLoginWhenUnauthenticated(t *testing.T) {
@@ -23,6 +25,21 @@ func TestRootRedirectsToLoginWhenUnauthenticated(t *testing.T) {
}
}
+func TestUnknownRouteRedirectsToLoginWhenUnauthenticated(t *testing.T) {
+ req := httptest.NewRequest(http.MethodGet, "/missing", nil)
+ rec := httptest.NewRecorder()
+
+ router := newTestRouter()
+ router.ServeHTTP(rec, req)
+
+ if rec.Code != http.StatusSeeOther {
+ t.Fatalf("expected status 303, got %d", rec.Code)
+ }
+ if location := rec.Header().Get("Location"); location != "/login" {
+ t.Fatalf("expected redirect to /login, got %q", location)
+ }
+}
+
func TestLoginPageRenders(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/login", nil)
rec := httptest.NewRecorder()
@@ -68,7 +85,7 @@ func TestSignupPageRenders(t *testing.T) {
body := rec.Body.String()
for _, want := range []string{
- "S'inscrire à Xtablo",
+ "S'inscrire à Xtablo",
`hx-post="/signup"`,
"Vous avez déjà un compte ?",
} {
@@ -154,11 +171,115 @@ func TestLoginCreatesSessionAndRedirects(t *testing.T) {
if homeRec.Code != http.StatusOK {
t.Fatalf("expected authenticated root status 200, got %d", homeRec.Code)
}
- if !strings.Contains(homeRec.Body.String(), "Bienvenue") {
- t.Fatalf("expected authenticated home page, got %q", homeRec.Body.String())
+ for _, want := range []string{
+ "Bonjour,",
+ "Aperçu",
+ "https://cdn.jsdelivr.net/npm/htmx.org@4.0.0-beta2/dist/htmx.min.js",
+ `hx-get="/tasks"`,
+ `hx-target="#app-main-content"`,
+ `hx-swap="outerHTML"`,
+ `hx-push-url="true"`,
+ "Tâches",
+ "Projets",
+ "Planning",
+ "Discussions",
+ "Fichiers",
+ "Feedback",
+ "Arctic Matrix",
+ "Créer un projet",
+ "Créer une tâche",
+ "Inviter l'équipe",
+ "Envoyer un message",
+ "Mes Projets",
+ "Mes Tâches",
+ `action="/logout"`,
+ } {
+ if !strings.Contains(homeRec.Body.String(), want) {
+ t.Fatalf("expected authenticated home page to contain %q, got %q", want, homeRec.Body.String())
+ }
}
- if !strings.Contains(homeRec.Body.String(), `action="/logout"`) {
- t.Fatalf("expected authenticated home page to include logout form, got %q", homeRec.Body.String())
+}
+
+func TestTasksPageRendersFullDashboardPage(t *testing.T) {
+ form := url.Values{}
+ form.Set("email", "demo@xtablo.com")
+ form.Set("password", "xtablo-demo")
+
+ loginReq := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
+ loginReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ loginRec := httptest.NewRecorder()
+
+ router := newTestRouter()
+ router.ServeHTTP(loginRec, loginReq)
+
+ sessionCookie := findCookie(loginRec.Result().Cookies(), "xtablo_session")
+ if sessionCookie == nil {
+ t.Fatalf("expected session cookie to be set")
+ }
+
+ req := httptest.NewRequest(http.MethodGet, "/tasks", nil)
+ req.AddCookie(sessionCookie)
+ rec := httptest.NewRecorder()
+ router.ServeHTTP(rec, req)
+
+ if rec.Code != http.StatusOK {
+ t.Fatalf("expected status 200, got %d", rec.Code)
+ }
+
+ body := rec.Body.String()
+ for _, want := range []string{
+ `class="sidebar-nav-shell"`,
+ `id="app-main-content"`,
+ "Tâches",
+ "Suivez les tâches de votre équipe",
+ } {
+ if !strings.Contains(body, want) {
+ t.Fatalf("expected tasks page to contain %q", want)
+ }
+ }
+}
+
+func TestTasksPageReturnsHTMXMainContentSwap(t *testing.T) {
+ form := url.Values{}
+ form.Set("email", "demo@xtablo.com")
+ form.Set("password", "xtablo-demo")
+
+ loginReq := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
+ loginReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ loginRec := httptest.NewRecorder()
+
+ router := newTestRouter()
+ router.ServeHTTP(loginRec, loginReq)
+
+ sessionCookie := findCookie(loginRec.Result().Cookies(), "xtablo_session")
+ if sessionCookie == nil {
+ t.Fatalf("expected session cookie to be set")
+ }
+
+ req := httptest.NewRequest(http.MethodGet, "/tasks", nil)
+ req.Header.Set("HX-Request", "true")
+ req.AddCookie(sessionCookie)
+ rec := httptest.NewRecorder()
+ router.ServeHTTP(rec, req)
+
+ if rec.Code != http.StatusOK {
+ t.Fatalf("expected status 200, got %d", rec.Code)
+ }
+
+ body := rec.Body.String()
+ for _, want := range []string{
+ `id="app-main-content"`,
+ `hx-swap-oob="outerHTML"`,
+ `id="sidebar-nav-tasks"`,
+ "Tâches",
+ "Suivez les tâches de votre équipe",
+ } {
+ if !strings.Contains(body, want) {
+ t.Fatalf("expected HTMX tasks response to contain %q", want)
+ }
+ }
+ if strings.Contains(body, `class="sidebar-nav-shell"`) {
+ t.Fatalf("expected HTMX tasks response to avoid rerendering the full sidebar")
}
}
@@ -244,6 +365,77 @@ func TestLogoutClearsSessionAndRedirectsToLogin(t *testing.T) {
}
}
+func TestUnknownRouteShowsDashboard404WhenAuthenticated(t *testing.T) {
+ form := url.Values{}
+ form.Set("email", "demo@xtablo.com")
+ form.Set("password", "xtablo-demo")
+
+ loginReq := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
+ loginReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ loginRec := httptest.NewRecorder()
+
+ router := newTestRouter()
+ router.ServeHTTP(loginRec, loginReq)
+
+ sessionCookie := findCookie(loginRec.Result().Cookies(), "xtablo_session")
+ if sessionCookie == nil {
+ t.Fatalf("expected session cookie to be set")
+ }
+
+ req := httptest.NewRequest(http.MethodGet, "/missing", nil)
+ req.AddCookie(sessionCookie)
+ rec := httptest.NewRecorder()
+ router.ServeHTTP(rec, req)
+
+ if rec.Code != http.StatusNotFound {
+ t.Fatalf("expected status 404, got %d", rec.Code)
+ }
+
+ body := rec.Body.String()
+ for _, want := range []string{
+ "Aperçu",
+ "Page introuvable",
+ "Cette page n'existe pas",
+ `href="/"`,
+ `action="/logout"`,
+ } {
+ if !strings.Contains(body, want) {
+ t.Fatalf("expected authenticated 404 page to contain %q", want)
+ }
+ }
+}
+
+func TestSessionSurvivesHandlerRecreation(t *testing.T) {
+ repo := handlers.NewInMemoryAuthRepository()
+
+ loginRouter := newRouterWithHandler(handlers.NewAuthHandler(repo))
+
+ form := url.Values{}
+ form.Set("email", "demo@xtablo.com")
+ form.Set("password", "xtablo-demo")
+
+ loginReq := httptest.NewRequest(http.MethodPost, "/login", strings.NewReader(form.Encode()))
+ loginReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ loginRec := httptest.NewRecorder()
+ loginRouter.ServeHTTP(loginRec, loginReq)
+
+ sessionCookie := findCookie(loginRec.Result().Cookies(), "xtablo_session")
+ if sessionCookie == nil {
+ t.Fatalf("expected session cookie to be set")
+ }
+
+ reloadedRouter := newRouterWithHandler(handlers.NewAuthHandler(repo))
+
+ homeReq := httptest.NewRequest(http.MethodGet, "/", nil)
+ homeReq.AddCookie(sessionCookie)
+ homeRec := httptest.NewRecorder()
+ reloadedRouter.ServeHTTP(homeRec, homeReq)
+
+ if homeRec.Code != http.StatusOK {
+ t.Fatalf("expected session to survive handler recreation, got status %d", homeRec.Code)
+ }
+}
+
func findCookie(cookies []*http.Cookie, name string) *http.Cookie {
for _, cookie := range cookies {
if cookie.Name == name {
diff --git a/go-backend/static/styles.css b/go-backend/static/styles.css
index 5286232..38689b5 100644
--- a/go-backend/static/styles.css
+++ b/go-backend/static/styles.css
@@ -518,15 +518,888 @@ input {
}
.home-shell {
- align-items: center;
background:
linear-gradient(135deg, rgba(128, 78, 236, 0.08), transparent 30%),
linear-gradient(160deg, rgba(30, 27, 46, 0.05), transparent 42%),
linear-gradient(to bottom right, rgba(30, 27, 46, 0.08), var(--background), rgba(128, 78, 236, 0.04));
+ min-height: 100vh;
+}
+
+.dashboard-shell {
+ background:
+ linear-gradient(135deg, rgba(128, 78, 236, 0.08), transparent 30%),
+ linear-gradient(160deg, rgba(30, 27, 46, 0.05), transparent 42%),
+ linear-gradient(to bottom right, rgba(30, 27, 46, 0.08), var(--background), rgba(128, 78, 236, 0.04));
+ color: var(--foreground);
+ display: grid;
+ grid-template-columns: minmax(16rem, 18rem) 1fr;
+ min-height: 100vh;
+}
+
+.dashboard-sidebar {
+ padding-left: env(safe-area-inset-left, 0px);
+}
+
+.sidebar-nav-shell {
+ background: rgba(255, 255, 255, 0.92);
+ border-right: 1px solid rgba(30, 27, 46, 0.08);
+ box-shadow: 20px 0 45px rgba(30, 27, 46, 0.06);
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ overflow-x: hidden;
+ overflow-y: auto;
+ padding: env(safe-area-inset-top, 0px) 0.75rem env(safe-area-inset-bottom, 0px) 0;
+ position: sticky;
+ top: 0;
+}
+
+.sidebar-brand {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ padding: 0.75rem 0.5rem;
+ position: relative;
+}
+
+.sidebar-brand-link {
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ width: 100%;
+}
+
+.sidebar-brand-logo {
+ border-radius: 0.75rem;
+ height: 4rem;
+ object-fit: cover;
+ width: 4rem;
+}
+
+.sidebar-brand-title {
+ color: #1f2937;
+ font-size: 1.125rem;
+ font-weight: 700;
+ margin: 0;
+}
+
+.sidebar-collapse-button {
+ align-items: center;
+ background: rgba(255, 255, 255, 0.95);
+ border: 0;
+ border-radius: 999px;
+ box-shadow: 0 10px 24px rgba(30, 27, 46, 0.14);
+ color: #6b7280;
+ cursor: pointer;
+ display: inline-flex;
+ height: 1.5rem;
+ justify-content: center;
+ padding: 0.25rem;
+ position: absolute;
+ right: 0.75rem;
+ top: 0.5rem;
+ width: 1.5rem;
+}
+
+.sidebar-collapse-button svg {
+ height: 1rem;
+ width: 1rem;
+}
+
+.sidebar-primary {
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+}
+
+.sidebar-list {
+ display: grid;
+ gap: 0;
+ list-style: none;
+ margin: 0;
+ padding: 0.75rem 0 0;
+}
+
+.sidebar-divider {
+ margin: 0.5rem 0;
+ padding: 0 0.875rem;
+}
+
+.sidebar-divider hr,
+.sidebar-projects hr {
+ border: 0;
+ border-top: 1px solid rgba(107, 114, 128, 0.22);
+ margin: 0;
+}
+
+.sidebar-nav-item {
+ border-radius: 0.9rem;
+ color: #6b7280;
+ font-weight: 500;
+ margin: 0 0.5rem;
+ padding: 0.15rem 0;
+ transition: background-color 0.2s ease, color 0.2s ease;
+}
+
+.sidebar-nav-item:hover {
+ background: rgba(30, 27, 46, 0.05);
+ color: #111827;
+}
+
+.sidebar-nav-item.is-active {
+ background: rgba(128, 78, 236, 0.14);
+ color: #804eec;
+ font-weight: 600;
+}
+
+.sidebar-nav-link {
+ display: block;
+ width: 100%;
+}
+
+.sidebar-nav-link-inner {
+ align-items: center;
+ display: flex;
+ gap: 0.75rem;
+ padding: 0.6rem 0.95rem;
+}
+
+.sidebar-nav-icon {
+ align-items: center;
+ display: inline-flex;
+ justify-content: center;
+}
+
+.sidebar-nav-icon svg {
+ height: 1.35rem;
+ width: 1.35rem;
+}
+
+.sidebar-nav-label {
+ font-size: 1rem;
+}
+
+.sidebar-projects {
+ margin-top: 0.4rem;
+ padding: 0 0.75rem 0.75rem;
+}
+
+.sidebar-section-label {
+ color: #6b7280;
+ font-size: 0.625rem;
+ font-weight: 700;
+ letter-spacing: 0.14em;
+ margin: 0.9rem 0 0.65rem;
+ padding: 0 0.5rem;
+ text-transform: uppercase;
+}
+
+.sidebar-project-list {
+ display: grid;
+ gap: 0.1rem;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.sidebar-project-link {
+ align-items: center;
+ border-radius: 0.85rem;
+ color: #6b7280;
+ display: flex;
+ gap: 0.65rem;
+ padding: 0.48rem 0.5rem;
+ transition: background-color 0.2s ease, color 0.2s ease;
+}
+
+.sidebar-project-link:hover {
+ background: rgba(30, 27, 46, 0.05);
+ color: #111827;
+}
+
+.sidebar-project-icon {
+ align-items: center;
+ border: 1px solid rgba(107, 114, 128, 0.35);
+ border-radius: 999px;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: 1.55rem;
+ justify-content: center;
+ width: 1.55rem;
+}
+
+.sidebar-project-icon svg {
+ height: 0.9rem;
+ width: 0.9rem;
+}
+
+.sidebar-project-label {
+ flex: 1;
+ font-size: 0.9rem;
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.sidebar-footer-links {
+ margin-top: auto;
+ padding-bottom: 0.25rem;
+}
+
+.sidebar-organization {
+ background: rgba(255, 255, 255, 0.92);
+ padding: 0 0.5rem 0.9rem;
+}
+
+.organization-button {
+ align-items: center;
+ background: transparent;
+ border: 0;
+ border-radius: 0.95rem;
+ cursor: pointer;
+ display: flex;
+ gap: 0.65rem;
+ padding: 0.55rem 0.65rem;
+ text-align: left;
+ transition: background-color 0.2s ease;
+ width: 100%;
+}
+
+.organization-button:hover {
+ background: rgba(30, 27, 46, 0.05);
+}
+
+.organization-avatar {
+ border-radius: 999px;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: 1.75rem;
+ overflow: hidden;
+ width: 1.75rem;
+}
+
+.organization-avatar img {
+ aspect-ratio: 1;
+ height: 100%;
+ object-fit: cover;
+ width: 100%;
+}
+
+.organization-copy {
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+}
+
+.organization-name {
+ color: #374151;
+ font-size: 0.95rem;
+ font-weight: 600;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.organization-meta {
+ color: #6b7280;
+ font-size: 0.75rem;
+}
+
+.dashboard-main {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ min-width: 0;
+ padding: 2rem;
+}
+
+.overview-page {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+ min-height: 100%;
+}
+
+.overview-header {
+ padding: 0 0 0.25rem;
+}
+
+.overview-date {
+ color: #475467;
+ font-size: 1rem;
+ font-weight: 500;
+ margin: 0 0 0.5rem;
+}
+
+.overview-header-row {
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+ justify-content: space-between;
+}
+
+.overview-greeting {
+ color: #475467;
+ font-size: clamp(1.4rem, 2vw, 1.75rem);
+ font-weight: 500;
+ margin: 0;
+}
+
+.overview-greeting span {
+ color: #111827;
+}
+
+.overview-header-actions {
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+}
+
+.overview-badge {
+ align-items: center;
+ background: linear-gradient(to right, #a855f7, #3b82f6);
+ border: 0;
+ border-radius: 999px;
+ color: #fff;
+ display: inline-flex;
+ font-size: 0.75rem;
+ font-weight: 600;
+ justify-content: center;
+ min-height: 1.85rem;
+ padding: 0.25rem 0.75rem;
+}
+
+.overview-logout-form {
+ margin: 0;
+}
+
+.overview-logout-button {
+ background: rgba(255, 255, 255, 0.92);
+ border: 1px solid rgba(234, 236, 240, 1);
+ border-radius: 0.85rem;
+ color: #475467;
+ cursor: pointer;
+ font-weight: 600;
+ min-height: 2.75rem;
+ padding: 0.65rem 1rem;
+}
+
+.overview-actions {
+ display: grid;
+ gap: 1rem;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+}
+
+.quick-action-card {
+ align-items: center;
+ background: #fff;
+ border: 1px solid #eaecf0;
+ border-radius: 1rem;
+ cursor: pointer;
+ display: flex;
+ gap: 0.9rem;
+ min-height: 5rem;
+ padding: 0.9rem;
+ text-align: left;
+ transition: box-shadow 0.2s ease, transform 0.2s ease;
+}
+
+.quick-action-card:hover,
+.project-card:hover {
+ box-shadow: 0 12px 30px rgba(15, 23, 42, 0.08);
+}
+
+.quick-action-icon {
+ align-items: center;
+ background: #f4f3ff;
+ border-radius: 0.7rem;
+ color: #7f56d9;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: 2.5rem;
+ justify-content: center;
+ width: 2.5rem;
+}
+
+.quick-action-icon svg {
+ height: 1.5rem;
+ width: 1.5rem;
+}
+
+.quick-action-copy {
+ flex: 1;
+ min-width: 0;
+}
+
+.quick-action-title {
+ color: #111827;
+ font-size: 1.05rem;
+ font-weight: 600;
+ line-height: 1.2;
+}
+
+.quick-action-copy p {
+ color: #6b7280;
+ font-size: 0.9rem;
+ margin: 0.25rem 0 0;
+}
+
+.overview-section {
+ padding: 0.25rem 0 0;
+}
+
+.overview-section-heading {
+ align-items: center;
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 1.5rem;
+}
+
+.overview-section-heading h3,
+.tasks-section-header h3 {
+ color: #111827;
+ font-size: 1.6rem;
+ font-weight: 600;
+ margin: 0;
+}
+
+.project-grid {
+ display: grid;
+ gap: 1.25rem;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.project-card {
+ background: #fff;
+ border: 1px solid #eaecf0;
+ border-radius: 1rem;
+ cursor: pointer;
+ padding: 1rem;
+ transition: box-shadow 0.2s ease;
+}
+
+.project-card-top {
+ align-items: flex-start;
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 1rem;
+}
+
+.project-status,
+.task-status {
+ border: 1px solid transparent;
+ border-radius: 999px;
+ display: inline-flex;
+ font-size: 0.75rem;
+ font-weight: 600;
+ padding: 0.25rem 0.7rem;
+}
+
+.tone-warning {
+ background: #fffbeb;
+ border-color: #fde68a;
+ color: #ca8a04;
+}
+
+.tone-info {
+ background: #eff6ff;
+ border-color: #bfdbfe;
+ color: #2563eb;
+}
+
+.tone-success {
+ background: #ecfdf3;
+ border-color: #bbf7d0;
+ color: #16a34a;
+}
+
+.project-delete-button {
+ background: transparent;
+ border: 0;
+ color: #9ca3af;
+ cursor: pointer;
+ padding: 0;
+}
+
+.project-delete-button:hover {
+ color: #ef4444;
+}
+
+.project-delete-button svg,
+.project-date-row svg,
+.overview-more-button svg,
+.tasks-add-button svg,
+.task-check svg {
+ height: 1rem;
+ width: 1rem;
+}
+
+.project-card-title-row {
+ align-items: center;
+ display: flex;
+ gap: 0.75rem;
+ margin-bottom: 1rem;
+}
+
+.project-avatar {
+ align-items: center;
+ border-radius: 0.85rem;
+ color: #fff;
+ display: inline-flex;
+ flex-shrink: 0;
+ font-size: 1.1rem;
+ font-weight: 700;
+ height: 3rem;
+ justify-content: center;
+ width: 3rem;
+}
+
+.project-accent-blue {
+ background: #3b82f6;
+}
+
+.project-accent-purple {
+ background: #a855f7;
+}
+
+.project-accent-red {
+ background: #ef4444;
+}
+
+.project-card-title-row h4 {
+ color: #111827;
+ flex: 1;
+ font-size: 1rem;
+ font-weight: 600;
+ margin: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.project-date-row {
+ align-items: center;
+ color: #6b7280;
+ display: flex;
+ font-size: 0.875rem;
+ gap: 0.5rem;
+ margin-bottom: 1rem;
+}
+
+.project-progress-label {
+ align-items: center;
+ color: #6b7280;
+ display: flex;
+ font-size: 0.875rem;
+ justify-content: space-between;
+ margin-bottom: 0.5rem;
+}
+
+.project-progress-label strong {
+ color: #111827;
+}
+
+.project-progress-track {
+ background: #f3f4f6;
+ border-radius: 999px;
+ height: 0.5rem;
+ overflow: hidden;
+}
+
+.project-progress-bar {
+ border-radius: 999px;
+ height: 100%;
+}
+
+.overview-more-row {
+ display: flex;
+ justify-content: center;
+ margin-top: 1.5rem;
+}
+
+.overview-more-button {
+ align-items: center;
+ background: transparent;
+ border: 0;
+ color: #7c3aed;
+ cursor: pointer;
+ display: inline-flex;
+ font-size: 0.875rem;
+ font-weight: 600;
+ gap: 0.4rem;
+}
+
+.app-section-page {
+ min-height: 100vh;
+ padding: 2rem;
+}
+
+.app-section-surface {
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, #ffffff 100%);
+ border: 1px solid #eaecf0;
+ border-radius: 1.5rem;
+ box-shadow: 0 24px 48px rgba(15, 23, 42, 0.08);
+ max-width: 52rem;
+ padding: 2rem;
+}
+
+.app-section-eyebrow {
+ color: #7c3aed;
+ font-size: 0.78rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ margin-bottom: 0.9rem;
+ text-transform: uppercase;
+}
+
+.app-section-surface h2 {
+ color: #111827;
+ font-size: clamp(1.8rem, 4vw, 2.6rem);
+ line-height: 1.05;
+ margin: 0;
+}
+
+.app-section-surface p {
+ color: #475467;
+ font-size: 1rem;
+ line-height: 1.8;
+ margin: 1rem 0 0;
+ max-width: 40rem;
+}
+
+.not-found-page {
+ align-items: center;
+ background:
+ radial-gradient(circle at top, rgba(124, 58, 237, 0.14), transparent 35%),
+ linear-gradient(180deg, #f8f7ff 0%, #f4f7fb 100%);
display: flex;
justify-content: center;
min-height: 100vh;
- padding: 1.5rem;
+ padding: 3rem 1.5rem;
+}
+
+.not-found-surface {
+ backdrop-filter: blur(18px);
+ background: rgba(255, 255, 255, 0.88);
+ border: 1px solid rgba(148, 163, 184, 0.22);
+ border-radius: 2rem;
+ box-shadow: 0 32px 70px rgba(15, 23, 42, 0.12);
+ padding: 3rem;
+ width: min(100%, 44rem);
+}
+
+.not-found-eyebrow {
+ align-items: center;
+ background: rgba(124, 58, 237, 0.1);
+ border-radius: 999px;
+ color: #7c3aed;
+ display: inline-flex;
+ font-size: 0.78rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ padding: 0.45rem 0.85rem;
+ text-transform: uppercase;
+}
+
+.not-found-code {
+ color: #111827;
+ font-size: clamp(4.75rem, 11vw, 7.5rem);
+ font-weight: 800;
+ letter-spacing: -0.08em;
+ line-height: 0.95;
+ margin-top: 1.4rem;
+}
+
+.not-found-surface h2 {
+ color: #111827;
+ font-size: clamp(1.9rem, 4vw, 2.8rem);
+ line-height: 1.05;
+ margin: 1rem 0 0;
+}
+
+.not-found-surface p {
+ color: #475467;
+ font-size: 1rem;
+ line-height: 1.75;
+ margin: 1rem 0 0;
+ max-width: 36rem;
+}
+
+.not-found-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.9rem;
+ margin-top: 2rem;
+}
+
+.not-found-primary,
+.not-found-secondary {
+ align-items: center;
+ border: 1px solid transparent;
+ border-radius: 0.95rem;
+ display: inline-flex;
+ font-size: 0.95rem;
+ font-weight: 600;
+ justify-content: center;
+ min-height: 2.9rem;
+ padding: 0.85rem 1.25rem;
+ text-decoration: none;
+ transition:
+ transform 0.18s ease,
+ box-shadow 0.18s ease,
+ background-color 0.18s ease,
+ border-color 0.18s ease;
+}
+
+.not-found-primary {
+ background: linear-gradient(135deg, #7c3aed 0%, #2563eb 100%);
+ box-shadow: 0 18px 35px rgba(124, 58, 237, 0.25);
+ color: #fff;
+}
+
+.not-found-primary:hover,
+.not-found-secondary:hover {
+ transform: translateY(-1px);
+}
+
+.not-found-secondary-form {
+ margin: 0;
+}
+
+.not-found-secondary {
+ background: rgba(255, 255, 255, 0.9);
+ border-color: rgba(148, 163, 184, 0.3);
+ color: #344054;
+ cursor: pointer;
+}
+
+.not-found-meta {
+ align-items: center;
+ color: #667085;
+ display: flex;
+ font-size: 0.95rem;
+ gap: 0.5rem;
+ margin-top: 1.5rem;
+}
+
+.not-found-meta strong {
+ color: #111827;
+}
+
+.tasks-section {
+ background: #fff;
+ border: 1px solid #eaecf0;
+ border-radius: 1rem;
+ overflow: hidden;
+}
+
+.tasks-section-header {
+ align-items: center;
+ border-bottom: 1px solid #e5e7eb;
+ display: flex;
+ justify-content: space-between;
+ padding: 1.2rem 1rem;
+}
+
+.tasks-add-button {
+ align-items: center;
+ background: #fff;
+ border: 1px solid #e5e7eb;
+ border-radius: 0.7rem;
+ color: #475467;
+ cursor: pointer;
+ display: inline-flex;
+ font-weight: 500;
+ gap: 0.5rem;
+ min-height: 2.75rem;
+ padding: 0.7rem 1rem;
+}
+
+.task-list {
+ display: flex;
+ flex-direction: column;
+}
+
+.task-row {
+ align-items: center;
+ border-bottom: 1px solid #e5e7eb;
+ cursor: pointer;
+ display: flex;
+ gap: 0.75rem;
+ padding: 0.9rem 1rem;
+ transition: background-color 0.2s ease;
+}
+
+.task-row:hover {
+ background: rgba(249, 250, 251, 0.9);
+}
+
+.task-check {
+ align-items: center;
+ background: #fff;
+ border: 2px solid #d1d5db;
+ border-radius: 999px;
+ color: #fff;
+ cursor: pointer;
+ display: inline-flex;
+ flex-shrink: 0;
+ height: 2rem;
+ justify-content: center;
+ width: 2rem;
+}
+
+.task-check.is-complete {
+ background: #7c3aed;
+ border-color: #7c3aed;
+}
+
+.task-body {
+ flex: 1;
+ min-width: 0;
+}
+
+.task-body p {
+ color: #111827;
+ font-size: 0.95rem;
+ font-weight: 500;
+ margin: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.task-row.is-complete .task-body p {
+ color: #9ca3af;
+ text-decoration: line-through;
+}
+
+.task-meta {
+ align-items: center;
+ color: #6b7280;
+ display: flex;
+ flex-wrap: wrap;
+ font-size: 0.75rem;
+ gap: 0.45rem;
+ margin-top: 0.3rem;
+}
+
+.task-project-badge {
+ align-items: center;
+ border-radius: 0.35rem;
+ color: #fff;
+ display: inline-flex;
+ font-size: 0.5rem;
+ font-weight: 700;
+ height: 1rem;
+ justify-content: center;
+ width: 1rem;
+}
+
+.task-date {
+ white-space: nowrap;
}
.home-card {
@@ -564,6 +1437,75 @@ input {
.logout-button {
max-width: 14rem;
+ width: 100%;
+}
+
+@media (max-width: 980px) {
+ .dashboard-shell {
+ grid-template-columns: 1fr;
+ }
+
+ .sidebar-nav-shell {
+ border-bottom: 1px solid rgba(30, 27, 46, 0.08);
+ border-right: 0;
+ box-shadow: 0 12px 30px rgba(30, 27, 46, 0.08);
+ height: auto;
+ position: static;
+ }
+
+ .overview-actions,
+ .project-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+}
+
+@media (max-width: 720px) {
+ .dashboard-main {
+ padding: 1rem;
+ }
+
+ .overview-header-row,
+ .tasks-section-header {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+
+ .overview-actions,
+ .project-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .task-row {
+ align-items: flex-start;
+ flex-wrap: wrap;
+ }
+
+ .task-status {
+ margin-left: 2.75rem;
+ }
+
+ .not-found-surface {
+ border-radius: 1.5rem;
+ padding: 2rem;
+ }
+
+ .not-found-actions {
+ flex-direction: column;
+ }
+
+ .not-found-primary,
+ .not-found-secondary,
+ .not-found-secondary-form {
+ width: 100%;
+ }
+
+ .app-section-page {
+ padding: 1rem;
+ }
+
+ .app-section-surface {
+ padding: 1.5rem;
+ }
}
@keyframes move-right-slow {