diff --git a/internal/route/main.go b/internal/route/main.go index 1bef013..8fe550e 100644 --- a/internal/route/main.go +++ b/internal/route/main.go @@ -221,6 +221,9 @@ func RoutesProtected(r *mux.Router, bd *gorm.DB) { //API Check path r.HandleFunc("/validate-path", download.PathValidationHandler) + r.HandleFun("/folders", renders.StreamHandler) + r.HandleFun("/folders/detail", renders.DetailHandler) + //API Scan folder } diff --git a/renders/renders.go b/renders/renders.go index 9a0ca1a..84c18f4 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -20,7 +20,58 @@ import ( "gorm.io/gorm" ) +var ( + // templates contiendra TOUTES vos pages .pages.tmpl + templates *template.Template +) +func init() { + // 1. Définissez votre FuncMap + funcMap := template.FuncMap{ + "hasSuffix": strings.HasSuffix, + "ext": func(name string) string { + return strings.TrimPrefix(filepath.Ext(name), ".") + }, + "split": strings.Split, + "trimPrefix": strings.TrimPrefix, + } + + // 2. Parsez tous les templates EN UNE FOIS, en injectant le FuncMap + templates = template.Must( + template.New(""). + Funcs(funcMap). + // ajuste le chemin vers vos .pages.tmpl + ParseGlob("./templates/*.pages.tmpl"), + ) +} + +type Entry struct { + Name, Path string + IsDir bool + ModTime time.Time + Size int64 +} + +// helper pour lister un dossier +func listEntries(base, rel string) ([]Entry, error) { + dir := filepath.Join(base, rel) + fis, err := os.ReadDir(dir) + if err != nil { + return nil, err + } + out := make([]Entry, 0, len(fis)) + for _, fi := range fis { + info, _ := fi.Info() + out = append(out, Entry{ + Name: fi.Name(), + Path: filepath.ToSlash(filepath.Join(rel, fi.Name())), + IsDir: fi.IsDir(), + ModTime: info.ModTime(), + Size: info.Size(), + }) + } + return out, nil +} func Login(w http.ResponseWriter, r *http.Request){ renderTemplate(w,"login",nil) } @@ -568,37 +619,72 @@ func HandleDeleteMultipleJobs(db *gorm.DB) http.HandlerFunc { } } +func StreamHandler(w http.ResponseWriter, r *http.Request) { + base := "/app/upload" + cur := r.URL.Query().Get("path") // ex: "", "Icons", "Code/Sub" + + // 1) sidebar : on ne gère que le niveau racine + root, _ := listEntries(base, "") + var dirs []Entry + for _, e := range root { + if e.IsDir { + dirs = append(dirs, e) + } + } + + // 2) contenu courant + entries, _ := listEntries(base, cur) + + data := map[string]interface{}{ + "Dirs": dirs, + "Entries": entries, + "CurrentPath": cur, + } + + // Si c’est un appel HTMX (liste partielle) : on renvoie juste la grille + if r.Header.Get("HX-Request") == "true" { + renderPartial(w, "_file_list", data) + return + } + // Sinon on rend la page complète + renderTemplate(w, "folders", data) +} +func DetailHandler(w http.ResponseWriter, r *http.Request) { + base := "static/uploads" + rel := r.URL.Query().Get("path") + info, err := os.Stat(filepath.Join(base, rel)) + if err != nil { + http.NotFound(w, r) + return + } + entry := Entry{ + Name: info.Name(), + Path: rel, + IsDir: info.IsDir(), + ModTime: info.ModTime(), + Size: info.Size(), + } + // Toujours partial HTMX + renderPartial(w, "_file_detail", map[string]interface{}{ + "Entry": entry, + }) +} + + + + + func renderPartial(w http.ResponseWriter, templ string, data map[string]interface{}) { - t, err := template.ParseFiles("./templates/" + templ + ".pages.tmpl") - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - err = t.Execute(w, data) - if err != nil { + // Exécute directement le define `.pages.tmpl` + if err := templates.ExecuteTemplate(w, templ+".pages.tmpl", data); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } - - func renderTemplate(w http.ResponseWriter, templ string, data map[string]interface{}) { - t, err := template.ParseFiles( - "./templates/head.pages.tmpl", // Template inclus - "./templates/" + templ + ".pages.tmpl", // Template principal - ) - - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - // Exécutez explicitement le template principal - err = t.ExecuteTemplate(w, templ+".pages.tmpl", data) - - if err != nil { + // Pareil, on exécute le principal + if err := templates.ExecuteTemplate(w, templ+".pages.tmpl", data); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } diff --git a/templates/_file_detail.pages.tmpl b/templates/_file_detail.pages.tmpl new file mode 100644 index 0000000..d1d1f6d --- /dev/null +++ b/templates/_file_detail.pages.tmpl @@ -0,0 +1,14 @@ +
+ {{ with .Entry }} +

{{ .Name }}

+

Type : {{ ext .Name }}

+

Taille : {{ printf "%.1f KB" (float64 .Size/1024) }}

+

Modifié le : {{ .ModTime.Format "02 Jan 2006 15:04" }}

+ {{ if and (not .IsDir) (or (hasSuffix .Name ".jpg") (hasSuffix .Name ".png")) }} +
+ +
+ {{ end }} + {{ end }} +
+ diff --git a/templates/_file_list.pages.tmpl b/templates/_file_list.pages.tmpl new file mode 100644 index 0000000..d52f0b7 --- /dev/null +++ b/templates/_file_list.pages.tmpl @@ -0,0 +1,30 @@ +
+ {{- range .Entries }} +
+
+
+
+ {{ if .IsDir }} + + {{ else if or (hasSuffix .Name ".jpg") (hasSuffix .Name ".png") }} + {{ .Name }} + {{ else }} + + {{ end }} +
+
+
+

{{ .Name }}

+
+
+
+ {{- end }} +
diff --git a/templates/dashboard.pages.tmpl b/templates/dashboard.pages.tmpl index 289dde8..2ce7363 100644 --- a/templates/dashboard.pages.tmpl +++ b/templates/dashboard.pages.tmpl @@ -43,6 +43,7 @@ +
  • Folders
  • Settings
  • diff --git a/templates/folders.pages.tmpl b/templates/folders.pages.tmpl new file mode 100644 index 0000000..cf5e6de --- /dev/null +++ b/templates/folders.pages.tmpl @@ -0,0 +1,80 @@ + + +
    +
    +
    + + +
    + +
    + + +
    + + +
    + {{ template "_file_list.pages.tmpl" . }} +
    +
    + + +
    +
    + Sélectionnez un fichier ou dossier… +
    +
    + +
    +
    +
    +