42 changed files with 1383 additions and 546 deletions
@ -0,0 +1,48 @@ |
|||
package api |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"fmt" |
|||
"io" |
|||
"regexp" |
|||
) |
|||
|
|||
func (s *Session) GetInvoice(identifier string) (map[string]interface{}, error) { |
|||
var endpoint string |
|||
|
|||
isInvoiceNumber, _ := regexp.MatchString(`^[A-Za-z]`, identifier) |
|||
|
|||
if isInvoiceNumber { |
|||
endpoint = fmt.Sprintf("/invoice?invoiceNumber=%s", identifier) |
|||
} else { |
|||
endpoint = fmt.Sprintf("/invoice/%s", identifier) |
|||
} |
|||
|
|||
resp, err := s.DoRequest("GET", endpoint, nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer resp.Body.Close() |
|||
|
|||
body, _ := io.ReadAll(resp.Body) |
|||
if resp.StatusCode != 200 { |
|||
return nil, fmt.Errorf("failed to get invoice info: %s, response: %s", resp.Status, string(body)) |
|||
} |
|||
|
|||
var result map[string]interface{} |
|||
if err := json.Unmarshal(body, &result); err != nil { |
|||
return nil, fmt.Errorf("error unmarshalling response: %v", err) |
|||
} |
|||
|
|||
if data, ok := result["data"].(map[string]interface{}); ok { |
|||
if invoices, ok := data["invoices"].([]interface{}); ok && len(invoices) > 0 { |
|||
if invoice, ok := invoices[0].(map[string]interface{}); ok { |
|||
return invoice, nil |
|||
} |
|||
} else { |
|||
return data, nil |
|||
} |
|||
} |
|||
|
|||
return nil, fmt.Errorf("no invoice found in the response") |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
package api |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"fmt" |
|||
"io" |
|||
) |
|||
|
|||
func (s *Session) GetAttachmentsForJob(jobID string) (map[string]interface{}, error) { |
|||
resp, err := s.DoRequest("GET", fmt.Sprintf("/job/%s/paperwork", jobID), nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer resp.Body.Close() |
|||
|
|||
body, _ := io.ReadAll(resp.Body) |
|||
if resp.StatusCode != 200 { |
|||
return nil, fmt.Errorf("failed to get attachments: %s, response: %s", resp.Status, string(body)) |
|||
} |
|||
|
|||
var result map[string]interface{} |
|||
if err := json.Unmarshal(body, &result); err != nil { |
|||
return nil, fmt.Errorf("error unmarshalling response: %v", err) |
|||
} |
|||
return result, nil |
|||
} |
|||
|
|||
func (s *Session) DeleteAttachment(attachmentID string) error { |
|||
resp, err := s.DoRequest("DELETE", fmt.Sprintf("/attachment/%s", attachmentID), nil) |
|||
if err != nil { |
|||
return err |
|||
} |
|||
defer resp.Body.Close() |
|||
|
|||
if resp.StatusCode != 200 && resp.StatusCode != 204 { |
|||
body, _ := io.ReadAll(resp.Body) |
|||
return fmt.Errorf("failed to delete attachment: %s, response: %s", resp.Status, string(body)) |
|||
} |
|||
|
|||
return nil |
|||
} |
|||
|
|||
func (s *Session) GetDeficiencyInfoForJob(jobID string) ([]map[string]interface{}, error) { |
|||
resp, err := s.DoRequest("GET", fmt.Sprintf("/deficiency/%s", jobID), nil) |
|||
if err != nil { |
|||
return nil, err |
|||
} |
|||
defer resp.Body.Close() |
|||
|
|||
body, _ := io.ReadAll(resp.Body) |
|||
if resp.StatusCode != 200 { |
|||
return nil, fmt.Errorf("failed to get deficiency info: %s, response: %s", resp.Status, string(body)) |
|||
} |
|||
|
|||
var result struct { |
|||
Data []map[string]interface{} `json:"data"` |
|||
} |
|||
if err := json.Unmarshal(body, &result); err != nil { |
|||
return nil, fmt.Errorf("error unmarshalling response: %v", err) |
|||
} |
|||
|
|||
return result.Data, nil |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
package api |
|||
|
|||
import ( |
|||
"sync" |
|||
"time" |
|||
) |
|||
|
|||
type SessionStore struct { |
|||
sessions map[string]*Session |
|||
mu sync.RWMutex |
|||
} |
|||
|
|||
func NewSessionStore() *SessionStore { |
|||
return &SessionStore{ |
|||
sessions: make(map[string]*Session), |
|||
} |
|||
} |
|||
|
|||
func (store *SessionStore) Set(sessionID string, session *Session) { |
|||
store.mu.Lock() |
|||
defer store.mu.Unlock() |
|||
store.sessions[sessionID] = session |
|||
} |
|||
|
|||
func (store *SessionStore) Get(sessionID string) (*Session, bool) { |
|||
store.mu.RLock() |
|||
defer store.mu.RUnlock() |
|||
session, ok := store.sessions[sessionID] |
|||
return session, ok |
|||
} |
|||
|
|||
func (store *SessionStore) Delete(sessionID string) { |
|||
store.mu.Lock() |
|||
defer store.mu.Unlock() |
|||
delete(store.sessions, sessionID) |
|||
} |
|||
|
|||
func (store *SessionStore) CleanupSessions() { |
|||
store.mu.Lock() |
|||
defer store.mu.Unlock() |
|||
for id, session := range store.sessions { |
|||
if time.Since(session.LastAccessed) > 24*time.Hour { |
|||
delete(store.sessions, id) |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +1,48 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func AdminHandler(w http.ResponseWriter, r *http.Request) { |
|||
if r.Header.Get("HX-Request") == "true" { |
|||
// This is an HTMX request, return only the jobs partial
|
|||
tmpl := template.Must(template.ParseFiles("templates/partials/jobs.html")) |
|||
jobs := r.Cookies() // Replace with actual data fetching
|
|||
tmpl.Execute(w, jobs) |
|||
} else { |
|||
// This is a full page request
|
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/partials/admin.html")) |
|||
jobs := []string{"Job 1", "Job 2", "Job 3"} // Replace with actual data fetching
|
|||
func HandleAdmin(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
ui.DisplayMenu([]string{ |
|||
"User Management", |
|||
"System Settings", |
|||
"Back to Main Menu", |
|||
}, "Admin Menu") |
|||
|
|||
tmpl.Execute(w, map[string]interface{}{ |
|||
"Title": "Jobs", |
|||
"Jobs": jobs, |
|||
}) |
|||
choice, err := utils.GetUserChoice(3) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
|
|||
switch choice { |
|||
case 1: |
|||
userManagement(session) |
|||
case 2: |
|||
systemSettings(session) |
|||
case 3: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func userManagement(session *api.Session) { |
|||
ui.ClearScreen() |
|||
ui.DisplayMessage("User Management") |
|||
// TODO: Implement user management logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func systemSettings(session *api.Session) { |
|||
ui.ClearScreen() |
|||
ui.DisplayMessage("System Settings") |
|||
// TODO: Implement system settings logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func AssetsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/assets.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleAssets(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Assets Menu:") |
|||
fmt.Println("1. List Assets") |
|||
fmt.Println("2. Add Asset") |
|||
fmt.Println("3. Edit Asset") |
|||
fmt.Println("4. Delete Asset") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listAssets(session) |
|||
case 2: |
|||
addAsset(session) |
|||
case 3: |
|||
editAsset(session) |
|||
case 4: |
|||
deleteAsset(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listAssets(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing assets...") |
|||
// TODO: Implement asset listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addAsset(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new asset...") |
|||
// TODO: Implement asset creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editAsset(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing an asset...") |
|||
// TODO: Implement asset editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteAsset(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting an asset...") |
|||
// TODO: Implement asset deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func CompaniesHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/companies.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleCompanies(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Companies Menu:") |
|||
fmt.Println("1. List Companies") |
|||
fmt.Println("2. Add Company") |
|||
fmt.Println("3. Edit Company") |
|||
fmt.Println("4. Delete Company") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listCompanies(session) |
|||
case 2: |
|||
addCompany(session) |
|||
case 3: |
|||
editCompany(session) |
|||
case 4: |
|||
deleteCompany(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listCompanies(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing companies...") |
|||
// TODO: Implement company listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addCompany(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new company...") |
|||
// TODO: Implement company creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editCompany(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a company...") |
|||
// TODO: Implement company editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteCompany(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a company...") |
|||
// TODO: Implement company deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func ContactsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/contacts.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleContacts(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Contacts Menu:") |
|||
fmt.Println("1. List Contacts") |
|||
fmt.Println("2. Add Contact") |
|||
fmt.Println("3. Edit Contact") |
|||
fmt.Println("4. Delete Contact") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listContacts(session) |
|||
case 2: |
|||
addContact(session) |
|||
case 3: |
|||
editContact(session) |
|||
case 4: |
|||
deleteContact(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listContacts(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing contacts...") |
|||
// TODO: Implement contact listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addContact(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new contact...") |
|||
// TODO: Implement contact creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editContact(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a contact...") |
|||
// TODO: Implement contact editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteContact(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a contact...") |
|||
// TODO: Implement contact deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func ContractsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/contracts.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleContracts(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Contracts Menu:") |
|||
fmt.Println("1. List Contracts") |
|||
fmt.Println("2. Add Contract") |
|||
fmt.Println("3. Edit Contract") |
|||
fmt.Println("4. Delete Contract") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listContracts(session) |
|||
case 2: |
|||
addContract(session) |
|||
case 3: |
|||
editContract(session) |
|||
case 4: |
|||
deleteContract(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listContracts(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing contracts...") |
|||
// TODO: Implement contract listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addContract(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new contract...") |
|||
// TODO: Implement contract creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editContract(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a contract...") |
|||
// TODO: Implement contract editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteContract(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a contract...") |
|||
// TODO: Implement contract deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,34 +0,0 @@ |
|||
package handlers |
|||
|
|||
import ( |
|||
"html/template" |
|||
"log" |
|||
"net/http" |
|||
) |
|||
|
|||
func DashboardHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl, err := template.ParseFiles( |
|||
"templates/layout.html", |
|||
"templates/dashboard.html", |
|||
"templates/partials/invoice_search.html", |
|||
"templates/partials/invoice_search_results.html", |
|||
) |
|||
if err != nil { |
|||
log.Printf("Template parsing error: %v", err) |
|||
http.Error(w, "Internal Server Error", http.StatusInternalServerError) |
|||
return |
|||
} |
|||
|
|||
data := struct{}{} // Empty struct as data
|
|||
|
|||
if r.Header.Get("HX-Request") == "true" { |
|||
err = tmpl.ExecuteTemplate(w, "content", data) |
|||
} else { |
|||
err = tmpl.ExecuteTemplate(w, "layout.html", data) |
|||
} |
|||
if err != nil { |
|||
log.Printf("Template execution error: %v", err) |
|||
http.Error(w, "Internal Server Error", http.StatusInternalServerError) |
|||
return |
|||
} |
|||
} |
|||
@ -1,11 +1,57 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func GenericHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/generic.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleGenericTools(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Generic Tools Menu:") |
|||
fmt.Println("1. Tool 1") |
|||
fmt.Println("2. Tool 2") |
|||
fmt.Println("3. Tool 3") |
|||
fmt.Println("4. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(4) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
runTool1(session) |
|||
case 2: |
|||
runTool2(session) |
|||
case 3: |
|||
runTool3(session) |
|||
case 4: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func runTool1(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Running Tool 1...") |
|||
// TODO: Implement Tool 1 logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func runTool2(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Running Tool 2...") |
|||
// TODO: Implement Tool 2 logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func runTool3(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Running Tool 3...") |
|||
// TODO: Implement Tool 3 logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,57 +1,70 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"log" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"net/http" |
|||
"strings" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func InvoicesHandler(w http.ResponseWriter, r *http.Request) { |
|||
session, ok := r.Context().Value("session").(*api.Session) |
|||
if !ok { |
|||
http.Error(w, "Unauthorized", http.StatusUnauthorized) |
|||
return |
|||
} |
|||
|
|||
// Handle the search request
|
|||
if r.Method == "GET" && r.URL.Query().Get("search") != "" { |
|||
handleInvoiceSearch(w, r, session) |
|||
return |
|||
} |
|||
func HandleInvoices(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Invoices Menu:") |
|||
fmt.Println("1. Search Invoice") |
|||
fmt.Println("2. List Recent Invoices") |
|||
fmt.Println("3. Create Invoice") |
|||
fmt.Println("4. Back to Main Menu") |
|||
|
|||
// Handle the initial page load
|
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/invoices.html")) |
|||
err := tmpl.Execute(w, nil) |
|||
if err != nil { |
|||
log.Printf("Error executing template: %v", err) |
|||
http.Error(w, "Internal Server Error", http.StatusInternalServerError) |
|||
choice, err := utils.GetUserChoice(4) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
searchInvoice(session) |
|||
case 2: |
|||
listRecentInvoices(session) |
|||
case 3: |
|||
createInvoice(session) |
|||
case 4: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func handleInvoiceSearch(w http.ResponseWriter, r *http.Request, session *api.Session) { |
|||
searchTerm := strings.TrimSpace(r.URL.Query().Get("search")) |
|||
|
|||
if searchTerm == "" { |
|||
log.Println("Empty search term, returning empty response") |
|||
w.WriteHeader(http.StatusOK) |
|||
return |
|||
} |
|||
func searchInvoice(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Search Invoice:") |
|||
identifier := utils.PromptForInput("Enter Invoice Number or ID: ") |
|||
|
|||
invoice, err := session.GetInvoice(searchTerm) |
|||
invoice, err := session.GetInvoice(identifier) |
|||
if err != nil { |
|||
log.Printf("Error fetching invoice: %v", err) |
|||
w.WriteHeader(http.StatusInternalServerError) |
|||
tmpl := template.Must(template.ParseFiles("templates/partials/invoice_search_results.html")) |
|||
tmpl.ExecuteTemplate(w, "invoice_search_results", map[string]interface{}{"Error": err.Error()}) |
|||
fmt.Printf("Error fetching invoice: %v\n", err) |
|||
utils.PressEnterToContinue() |
|||
return |
|||
} |
|||
|
|||
tmpl := template.Must(template.ParseFiles("templates/partials/invoice_search_results.html")) |
|||
err = tmpl.ExecuteTemplate(w, "invoice_search_results", invoice) |
|||
if err != nil { |
|||
log.Printf("Error executing template: %v", err) |
|||
http.Error(w, "Internal Server Error", http.StatusInternalServerError) |
|||
} |
|||
fmt.Println("Invoice Details:") |
|||
fmt.Printf("Invoice Number: %v\n", invoice["invoiceNumber"]) |
|||
fmt.Printf("Total Price: $%v\n", invoice["totalPrice"]) |
|||
fmt.Printf("Status: %v\n", invoice["status"]) |
|||
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func listRecentInvoices(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing recent invoices...") |
|||
// TODO: Implement recent invoices listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func createInvoice(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Creating a new invoice...") |
|||
// TODO: Implement invoice creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,26 +1,116 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func JobsHandler(w http.ResponseWriter, r *http.Request) { |
|||
jobs := []string{"Job 1", "Job 2", "Job 3"} // Replace with actual data fetching
|
|||
|
|||
if r.Header.Get("HX-Request") == "true" { |
|||
// This is an HTMX request, return the jobs content wrapped in the content template
|
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/partials/jobs.html")) |
|||
tmpl.ExecuteTemplate(w, "content", map[string]interface{}{ |
|||
"Title": "Jobs", |
|||
"Jobs": jobs, |
|||
}) |
|||
} else { |
|||
// This is a full page request
|
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/partials/jobs.html")) |
|||
tmpl.Execute(w, map[string]interface{}{ |
|||
"Title": "Jobs", |
|||
"Jobs": jobs, |
|||
}) |
|||
func HandleJobs(session *api.Session) { |
|||
for { |
|||
ui.DisplayMenu([]string{ |
|||
"Search Job by ID", |
|||
"List Recent Jobs", |
|||
"Create New Job", |
|||
"Manage Job Attachments", |
|||
"View Deficiencies", |
|||
"Back to Main Menu", |
|||
}, "Jobs Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(6) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
|
|||
switch choice { |
|||
case 1: |
|||
searchJobByID(session) |
|||
case 2: |
|||
listRecentJobs(session) |
|||
case 3: |
|||
createNewJob(session) |
|||
case 4: |
|||
manageJobAttachments(session) |
|||
case 5: |
|||
viewDeficiencyById(session) |
|||
case 6: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func searchJobByID(session *api.Session) { |
|||
ui.ClearScreen() |
|||
ui.DisplayMessage("Search Job by ID:") |
|||
jobID := utils.PromptForInput("Enter Job ID: ") |
|||
|
|||
// TODO: Implement job search logic using the API
|
|||
ui.DisplayMessage(fmt.Sprintf("Searching for job with ID: %s", jobID)) |
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func listRecentJobs(session *api.Session) { |
|||
ui.ClearScreen() |
|||
ui.DisplayMessage("Listing recent jobs...") |
|||
// TODO: Implement recent jobs listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func createNewJob(session *api.Session) { |
|||
ui.ClearScreen() |
|||
ui.DisplayMessage("Creating a new job...") |
|||
// TODO: Implement job creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func manageJobAttachments(session *api.Session) { |
|||
ui.ClearScreen() |
|||
jobID := utils.PromptForInput("Enter Job ID: ") |
|||
|
|||
attachments, err := session.GetAttachmentsForJob(jobID) |
|||
if err != nil { |
|||
ui.DisplayError("Failed to retrieve attachments:", err) |
|||
utils.PressEnterToContinue() |
|||
return |
|||
} |
|||
|
|||
ui.DisplayMessage(fmt.Sprintf("Attachments for Job %s:", jobID)) |
|||
if dataMap, ok := attachments["data"].(map[string]interface{}); ok { |
|||
if attachmentsList, ok := dataMap["attachments"].([]interface{}); ok { |
|||
for i, attachment := range attachmentsList { |
|||
if att, ok := attachment.(map[string]interface{}); ok { |
|||
ui.DisplayMessage(fmt.Sprintf("%d. %s", i+1, att["fileName"])) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
// TODO: Implement attachment deletion logic
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func viewDeficiencyById(session *api.Session) { |
|||
ui.ClearScreen() |
|||
deficiencyID := utils.PromptForInput("Enter Deficiency ID: ") |
|||
|
|||
ui.DisplayMessage(fmt.Sprintf("Fetching information for Deficiency %s...", deficiencyID)) |
|||
|
|||
deficiencies, err := session.GetDeficiencyInfoForJob(deficiencyID) |
|||
if err != nil { |
|||
ui.DisplayError("Failed to retrieve deficiency information:", err) |
|||
utils.PressEnterToContinue() |
|||
return |
|||
} |
|||
|
|||
for _, deficiency := range deficiencies { |
|||
ui.DisplayMessage(fmt.Sprintf("ID: %v", deficiency["id"])) |
|||
ui.DisplayMessage(fmt.Sprintf("Description: %v", deficiency["description"])) |
|||
ui.DisplayMessage(fmt.Sprintf("Status: %v", deficiency["status"])) |
|||
ui.DisplayMessage("---") |
|||
} |
|||
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func LocationsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/locations.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleLocations(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Locations Menu:") |
|||
fmt.Println("1. List Locations") |
|||
fmt.Println("2. Add Location") |
|||
fmt.Println("3. Edit Location") |
|||
fmt.Println("4. Delete Location") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listLocations(session) |
|||
case 2: |
|||
addLocation(session) |
|||
case 3: |
|||
editLocation(session) |
|||
case 4: |
|||
deleteLocation(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listLocations(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing locations...") |
|||
// TODO: Implement location listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addLocation(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new location...") |
|||
// TODO: Implement location creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editLocation(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a location...") |
|||
// TODO: Implement location editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteLocation(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a location...") |
|||
// TODO: Implement location deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,57 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func NotificationsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/notifications.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleNotifications(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Notifications Menu:") |
|||
fmt.Println("1. View Notifications") |
|||
fmt.Println("2. Mark Notification as Read") |
|||
fmt.Println("3. Delete Notification") |
|||
fmt.Println("4. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(4) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
viewNotifications(session) |
|||
case 2: |
|||
markNotificationAsRead(session) |
|||
case 3: |
|||
deleteNotification(session) |
|||
case 4: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func viewNotifications(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Viewing notifications...") |
|||
// TODO: Implement notification viewing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func markNotificationAsRead(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Marking notification as read...") |
|||
// TODO: Implement marking notification as read logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteNotification(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting notification...") |
|||
// TODO: Implement notification deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func QuotesHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/quotes.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleQuotes(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Quotes Menu:") |
|||
fmt.Println("1. List Quotes") |
|||
fmt.Println("2. Create Quote") |
|||
fmt.Println("3. Edit Quote") |
|||
fmt.Println("4. Delete Quote") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listQuotes(session) |
|||
case 2: |
|||
createQuote(session) |
|||
case 3: |
|||
editQuote(session) |
|||
case 4: |
|||
deleteQuote(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listQuotes(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing quotes...") |
|||
// TODO: Implement quote listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func createQuote(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Creating a new quote...") |
|||
// TODO: Implement quote creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editQuote(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a quote...") |
|||
// TODO: Implement quote editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteQuote(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a quote...") |
|||
// TODO: Implement quote deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func ServicesHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/services.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleServices(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Services Menu:") |
|||
fmt.Println("1. List Services") |
|||
fmt.Println("2. Add Service") |
|||
fmt.Println("3. Edit Service") |
|||
fmt.Println("4. Delete Service") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listServices(session) |
|||
case 2: |
|||
addService(session) |
|||
case 3: |
|||
editService(session) |
|||
case 4: |
|||
deleteService(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listServices(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing services...") |
|||
// TODO: Implement service listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addService(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new service...") |
|||
// TODO: Implement service creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editService(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a service...") |
|||
// TODO: Implement service editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteService(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a service...") |
|||
// TODO: Implement service deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func TagsHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/tags.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleTags(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Tags Menu:") |
|||
fmt.Println("1. List Tags") |
|||
fmt.Println("2. Add Tag") |
|||
fmt.Println("3. Edit Tag") |
|||
fmt.Println("4. Delete Tag") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listTags(session) |
|||
case 2: |
|||
addTag(session) |
|||
case 3: |
|||
editTag(session) |
|||
case 4: |
|||
deleteTag(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listTags(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing tags...") |
|||
// TODO: Implement tag listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addTag(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new tag...") |
|||
// TODO: Implement tag creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editTag(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a tag...") |
|||
// TODO: Implement tag editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteTag(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a tag...") |
|||
// TODO: Implement tag deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -1,11 +1,67 @@ |
|||
package handlers |
|||
package cli |
|||
|
|||
import ( |
|||
"html/template" |
|||
"net/http" |
|||
"fmt" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"marmic/servicetrade-toolbox/internal/ui" |
|||
"marmic/servicetrade-toolbox/internal/utils" |
|||
) |
|||
|
|||
func UsersHandler(w http.ResponseWriter, r *http.Request) { |
|||
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/users.html")) |
|||
tmpl.Execute(w, nil) |
|||
func HandleUsers(session *api.Session) { |
|||
for { |
|||
ui.ClearScreen() |
|||
fmt.Println("Users Menu:") |
|||
fmt.Println("1. List Users") |
|||
fmt.Println("2. Add User") |
|||
fmt.Println("3. Edit User") |
|||
fmt.Println("4. Delete User") |
|||
fmt.Println("5. Back to Main Menu") |
|||
|
|||
choice, err := utils.GetUserChoice(5) |
|||
if err != nil { |
|||
ui.DisplayError("Invalid input:", err) |
|||
utils.PressEnterToContinue() |
|||
continue |
|||
} |
|||
switch choice { |
|||
case 1: |
|||
listUsers(session) |
|||
case 2: |
|||
addUser(session) |
|||
case 3: |
|||
editUser(session) |
|||
case 4: |
|||
deleteUser(session) |
|||
case 5: |
|||
return |
|||
} |
|||
} |
|||
} |
|||
|
|||
func listUsers(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Listing users...") |
|||
// TODO: Implement user listing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func addUser(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Adding a new user...") |
|||
// TODO: Implement user creation logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func editUser(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Editing a user...") |
|||
// TODO: Implement user editing logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
func deleteUser(session *api.Session) { |
|||
ui.ClearScreen() |
|||
fmt.Println("Deleting a user...") |
|||
// TODO: Implement user deletion logic using the API
|
|||
utils.PressEnterToContinue() |
|||
} |
|||
|
|||
@ -0,0 +1,36 @@ |
|||
package middleware |
|||
|
|||
import ( |
|||
"context" |
|||
"marmic/servicetrade-toolbox/internal/api" |
|||
"net/http" |
|||
) |
|||
|
|||
var SessionStore = api.NewSessionStore() |
|||
|
|||
func AuthMiddleware(next http.Handler) http.Handler { |
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|||
cookie, err := r.Cookie("PHPSESSID") |
|||
if err != nil { |
|||
http.Redirect(w, r, "/login", http.StatusSeeOther) |
|||
return |
|||
} |
|||
|
|||
sessionID := cookie.Value |
|||
session, exists := SessionStore.Get(sessionID) |
|||
if !exists { |
|||
session = api.NewSession() |
|||
session.Cookie = "PHPSESSID=" + sessionID |
|||
|
|||
if err := session.ValidateSession(); err != nil { |
|||
http.Redirect(w, r, "/login", http.StatusSeeOther) |
|||
return |
|||
} |
|||
|
|||
SessionStore.Set(sessionID, session) |
|||
} |
|||
|
|||
ctx := context.WithValue(r.Context(), "session", session) |
|||
next.ServeHTTP(w, r.WithContext(ctx)) |
|||
}) |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
package ui |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"github.com/inancgumus/screen" |
|||
) |
|||
|
|||
func ClearScreen() { |
|||
screen.Clear() |
|||
screen.MoveTopLeft() |
|||
} |
|||
|
|||
func DisplayStartScreen() { |
|||
ClearScreen() |
|||
fmt.Println("========================================") |
|||
fmt.Println(" Welcome to ServiceTrade CLI") |
|||
fmt.Println("========================================") |
|||
fmt.Println("Please log in with your ServiceTrade credentials to continue.") |
|||
fmt.Println() |
|||
} |
|||
|
|||
func DisplayMessage(message string) { |
|||
fmt.Println(message) |
|||
} |
|||
|
|||
func DisplayError(prefix string, err error) { |
|||
fmt.Printf("%s %v\n", prefix, err) |
|||
} |
|||
|
|||
func DisplayMenu(items []string, title string) { |
|||
ClearScreen() |
|||
fmt.Printf("\n%s:\n", title) |
|||
for i, item := range items { |
|||
fmt.Printf("%d. %s\n", i+1, item) |
|||
} |
|||
} |
|||
@ -1,79 +0,0 @@ |
|||
package ui |
|||
|
|||
import ( |
|||
"bufio" |
|||
"fmt" |
|||
"os" |
|||
"strconv" |
|||
"strings" |
|||
|
|||
"github.com/inancgumus/screen" |
|||
) |
|||
|
|||
func ClearScreen() { |
|||
screen.Clear() |
|||
screen.MoveTopLeft() |
|||
} |
|||
|
|||
func DisplayStartScreen() { |
|||
ClearScreen() |
|||
fmt.Println("========================================") |
|||
fmt.Println(" Welcome to ServiceTrade CLI") |
|||
fmt.Println("========================================") |
|||
fmt.Println("Please log in with your ServiceTrade credentials to continue.") |
|||
fmt.Println() |
|||
} |
|||
|
|||
func PromptCredentials() (string, string, error) { |
|||
reader := bufio.NewReader(os.Stdin) |
|||
|
|||
fmt.Print("Enter your email: ") |
|||
email, _ := reader.ReadString('\n') |
|||
email = strings.TrimSpace(email) |
|||
|
|||
fmt.Print("Enter your password: ") |
|||
password, _ := reader.ReadString('\n') |
|||
password = strings.TrimSpace(password) |
|||
|
|||
return email, password, nil |
|||
} |
|||
|
|||
func DisplayMessage(message string) { |
|||
fmt.Println(message) |
|||
} |
|||
|
|||
func DisplayError(prefix string, err error) { |
|||
fmt.Printf("%s %v\n", prefix, err) |
|||
} |
|||
|
|||
func PressEnterToContinue() { |
|||
fmt.Println("Press Enter to continue...") |
|||
bufio.NewReader(os.Stdin).ReadBytes('\n') |
|||
} |
|||
|
|||
func DisplayMenu(items []string, title string) { |
|||
ClearScreen() |
|||
fmt.Printf("\n%s:\n", title) |
|||
for i, item := range items { |
|||
fmt.Printf("%d. %s\n", i+1, item) |
|||
} |
|||
} |
|||
|
|||
func GetUserChoice(max int) (int, error) { |
|||
reader := bufio.NewReader(os.Stdin) |
|||
fmt.Printf("\nEnter your choice (1-%d): ", max) |
|||
input, _ := reader.ReadString('\n') |
|||
input = strings.TrimSpace(input) |
|||
choice, err := strconv.Atoi(input) |
|||
if err != nil || choice < 1 || choice > max { |
|||
return 0, fmt.Errorf("invalid input") |
|||
} |
|||
return choice, nil |
|||
} |
|||
|
|||
func PromptForInput(prompt string) string { |
|||
reader := bufio.NewReader(os.Stdin) |
|||
fmt.Print(prompt) |
|||
input, _ := reader.ReadString('\n') |
|||
return strings.TrimSpace(input) |
|||
} |
|||
Loading…
Reference in new issue