diff --git a/.gitignore b/.gitignore index ceeb05b..a98563f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /tmp +/uploads/* \ No newline at end of file diff --git a/main.go b/main.go index 4c3c743..ae897ae 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "Advertisement_Panel/src" "fmt" "html/template" "net/http" @@ -23,11 +24,12 @@ func main() { templ, _ = template.ParseGlob("templates/*.html") fmt.Print("Now running server!\n") + // Serves index http.HandleFunc("/", index_handler) // Serves json for html to find file names - http.HandleFunc("/files", file_handler) + http.HandleFunc("/files", src.FileHandler) // Serves ascii page http.HandleFunc("/ascii", ascii_handler) @@ -35,8 +37,19 @@ func main() { // Serves images http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static")))) + http.Handle("/uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir("./uploads")))) + + // Serves administration page + http.HandleFunc("/admin/", admin_handler) + + // Handles image upload + http.HandleFunc("/upload", src.UploadHandler) + + fmt.Print("Webserver running on http://localhost:8080\n") + // Serves what ever the user is requesting base on above urls http.ListenAndServe(":8080", nil) + } func index_handler(w http.ResponseWriter, r *http.Request) { @@ -46,3 +59,6 @@ func index_handler(w http.ResponseWriter, r *http.Request) { func ascii_handler(w http.ResponseWriter, r *http.Request) { templ.ExecuteTemplate(w, "ascii.html", nil) } +func admin_handler(w http.ResponseWriter, r *http.Request) { + templ.ExecuteTemplate(w, "admin.html", nil) +} diff --git a/src/Admin.go b/src/Admin.go new file mode 100644 index 0000000..c6d5f54 --- /dev/null +++ b/src/Admin.go @@ -0,0 +1 @@ +package src diff --git a/file_handlers.go b/src/FileHandlers.go similarity index 85% rename from file_handlers.go rename to src/FileHandlers.go index d593d0e..382c3a5 100644 --- a/file_handlers.go +++ b/src/FileHandlers.go @@ -1,4 +1,4 @@ -package main +package src import ( "encoding/json" @@ -10,8 +10,19 @@ import ( const staticDir = "static" +type FileData struct { + ImageNames []string + SpicyImageNames []string + AsciiFiles []AsciiEntry +} + +type AsciiEntry struct { + Name string + FontSize int +} + // move FileData and AsciiEntry here if you want, or leave in main.go -func file_handler(w http.ResponseWriter, r *http.Request) { +func FileHandler(w http.ResponseWriter, r *http.Request) { data := FileData{ ImageNames: []string{}, SpicyImageNames: []string{}, diff --git a/src/UploadHandlers.go b/src/UploadHandlers.go new file mode 100644 index 0000000..3ac2f18 --- /dev/null +++ b/src/UploadHandlers.go @@ -0,0 +1,36 @@ +package src + +import ( + "fmt" + "io" + "net/http" + "os" +) + +func UploadHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + file, header, err := r.FormFile("image") // "image" is the name of the file input + if err != nil { + http.Error(w, "Error retrieving file", http.StatusBadRequest) + return + } + defer file.Close() + + dst, err := os.Create("./uploads/" + header.Filename) + if err != nil { + http.Error(w, "Error creating file on server", http.StatusInternalServerError) + return + } + defer dst.Close() + + if _, err := io.Copy(dst, file); err != nil { + http.Error(w, "Error saving file", http.StatusInternalServerError) + return + } + fmt.Fprint(w, "") + fmt.Fprintf(w, "Image uploaded successfully: %s", header.Filename) +} diff --git a/static/css/admin.css b/static/css/admin.css new file mode 100644 index 0000000..edf1fb7 --- /dev/null +++ b/static/css/admin.css @@ -0,0 +1,67 @@ +body { + font-family: Arial, sans-serif; + width: 100vw; + height: 100vh; + background: #101010; + color: #fff; + display: flex; + align-items: center; + justify-content: center; +} +.container { + background: #212121; + padding: 24px 32px; + border-radius: 8px; + max-width: 400px; + box-shadow: 0 2px 8px rgba(0,0,0,0.08); +} +.active { + background-color: #007bff; + color: white; +} +main { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + max-width: 400px; + background: #121212; +} +nav { + padding: 10px 18px; + border-radius: 8px; + width: 100%; + box-shadow: 0 2px 8px rgba(0,0,0,0.08) +} +h2 { + margin-bottom: 20px; + color: #ccc; +} +label { + display: block; + margin-bottom: 8px; + font-weight: 500; +} +input[type="file"] { + margin-bottom: 16px; +} +button[type="submit"] { + background: #007bff; + color: #fff; + border: none; + padding: 10px 18px; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; +} +button:hover { + background: #0056b3; +} +.preview { + margin-top: 16px; + max-width: 100%; + max-height: 200px; + display: none; + border: 1px solid #ddd; + border-radius: 4px; +} \ No newline at end of file diff --git a/static/css/global.css b/static/css/global.css new file mode 100644 index 0000000..ec922ea --- /dev/null +++ b/static/css/global.css @@ -0,0 +1,22 @@ +body { + margin: 0; + background: black; + display: flex; + justify-content: center; + align-items: center; + color: white; + height: 100vh; + cursor: none; +} + +pre { + white-space: pre; + font-family: monospace; + font-size: 14px; + line-height: 1.2; +} + +img { + max-width: 100%; + max-height: 100%; +} \ No newline at end of file diff --git a/static/js/admin.js b/static/js/admin.js new file mode 100644 index 0000000..47c5f0e --- /dev/null +++ b/static/js/admin.js @@ -0,0 +1,71 @@ +const imageInput = document.getElementById('imageInput'); +const preview = document.getElementById('preview'); + +let currentFile = null; + + + +imageInput.addEventListener('change', function() { + currentFile = this.files[0]; + if (currentFile) { + const reader = new FileReader(); + reader.onload = function(e) { + preview.src = e.target.result; + preview.style.display = 'block'; + } + reader.readAsDataURL(currentFile); + } else { + preview.style.display = 'none'; + } +}); + +document.getElementById('imageForm').addEventListener('submit', function(e) { + e.preventDefault(); + + // Add your upload logic here + const formData = new FormData(); + formData.append('image', currentFile); + if (!currentFile) { + alert('Please select an image to upload.'); + return; + } + fetch('/upload', { + method: 'POST', + body: formData + }).then(response => response.text()) + .then(data => { + console.log(data); + alert('Image uploaded successfully!'); + window.location.reload(); + }) + .catch(error => { + console.error('Error:', error); + alert('Error uploading image.'); + }); +}); + +function openTab(evt, tabNumber) { + // Declare all variables + var i, tabcontent, tablinks; + + // Get all elements with class="tabcontent" and hide them + tabcontent = document.getElementsByClassName("tab-container"); + for (i = 0; i < tabcontent.length; i++) { + tabcontent[i].style.display = "none"; + } + + // Get all elements with class="tablinks" and remove the class "active" + tablinks = document.getElementsByClassName("tab-button"); + for (i = 0; i < tablinks.length; i++) { + tablinks[i].className = tablinks[i].className.replace(" active", ""); + } + + // Show the current tab, and add an "active" class to the button that opened the tab + console.log("tab-"+tabNumber); + let currentTab = document.getElementById('tab-'+(tabNumber)) + if (currentTab) { + currentTab.style.display = "block"; + } else throw new Error("Tab not found: " + tabNumber); + currentTab.style.display = "block"; + evt.currentTarget.className += " active"; +} diff --git a/templates/admin.html b/templates/admin.html new file mode 100644 index 0000000..2d0889f --- /dev/null +++ b/templates/admin.html @@ -0,0 +1,32 @@ + + +
+ +