You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.0 KiB
89 lines
2.0 KiB
package main |
|
|
|
import ( |
|
"embed" |
|
"io/fs" |
|
"net/http" |
|
"path" |
|
"strings" |
|
) |
|
|
|
//go:embed all:web/dist all:web/public |
|
var adminFS embed.FS |
|
|
|
// getAdminFS returns the embedded filesystem for the admin UI. |
|
func getAdminFS() (http.FileSystem, error) { |
|
// Try dist first (built assets) |
|
distFS, err := fs.Sub(adminFS, "web/dist") |
|
if err == nil { |
|
// Check if dist has content |
|
entries, _ := fs.ReadDir(distFS, ".") |
|
if len(entries) > 0 { |
|
return http.FS(distFS), nil |
|
} |
|
} |
|
|
|
// Fall back to public (template) |
|
publicFS, err := fs.Sub(adminFS, "web/public") |
|
if err != nil { |
|
return nil, err |
|
} |
|
return http.FS(publicFS), nil |
|
} |
|
|
|
// serveAdminUI serves the embedded admin web UI. |
|
func (s *AdminServer) serveAdminUI(w http.ResponseWriter, r *http.Request) { |
|
fsys, err := getAdminFS() |
|
if err != nil { |
|
http.Error(w, "Admin UI not available", http.StatusInternalServerError) |
|
return |
|
} |
|
|
|
// Strip /admin prefix from path |
|
urlPath := r.URL.Path |
|
if strings.HasPrefix(urlPath, "/admin") { |
|
urlPath = strings.TrimPrefix(urlPath, "/admin") |
|
if urlPath == "" { |
|
urlPath = "/" |
|
} |
|
} |
|
|
|
// Try to serve the file |
|
filePath := strings.TrimPrefix(urlPath, "/") |
|
if filePath == "" { |
|
filePath = "index.html" |
|
} |
|
|
|
// Check if file exists |
|
f, err := fsys.Open(filePath) |
|
if err != nil { |
|
// Serve index.html for SPA routing |
|
filePath = "index.html" |
|
f, err = fsys.Open(filePath) |
|
if err != nil { |
|
http.Error(w, "Not found", http.StatusNotFound) |
|
return |
|
} |
|
} |
|
f.Close() |
|
|
|
// Set content type |
|
switch path.Ext(filePath) { |
|
case ".html": |
|
w.Header().Set("Content-Type", "text/html; charset=utf-8") |
|
case ".css": |
|
w.Header().Set("Content-Type", "text/css; charset=utf-8") |
|
case ".js": |
|
w.Header().Set("Content-Type", "application/javascript; charset=utf-8") |
|
case ".json": |
|
w.Header().Set("Content-Type", "application/json; charset=utf-8") |
|
case ".svg": |
|
w.Header().Set("Content-Type", "image/svg+xml") |
|
case ".png": |
|
w.Header().Set("Content-Type", "image/png") |
|
} |
|
|
|
// Serve the file |
|
r.URL.Path = "/" + filePath |
|
http.FileServer(fsys).ServeHTTP(w, r) |
|
}
|
|
|