Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react UI #270

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,13 @@ In case you'd like to add some other features to the logbook or you found a bug,
* Signature Pad https://github.com/szimek/signature_pad
* PapaParse https://github.com/mholt/PapaParse
* arc.js https://github.com/springmeyer/arc.js


* Golang go-pdf https://github.com/go-pdf/fpdf
* Golang chi web-server https://github.com/go-chi/chi
* React https://react.dev/
* Material UI https://mui.com/material-ui/
* Material React Table https://material-react-table.com
* dayjs https://github.com/iamkun/dayjs
* TanStack Query https://tanstack.com/query/
* export-to-csv https://github.com/alexcaza/export-to-csv
12 changes: 11 additions & 1 deletion app/handlers_aircraft.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/vsimakhin/web-logbook/internal/models"
)

// HandlerNightTime is a handler for calculating night time
func (app *application) HandlerAircrafts(w http.ResponseWriter, r *http.Request) {

var aircrafts map[string]string
Expand All @@ -27,3 +26,14 @@ func (app *application) HandlerAircrafts(w http.ResponseWriter, r *http.Request)

app.writeJSON(w, http.StatusOK, aircrafts)
}

// HandlerApiAircraftModels is a handler for getting the list of aircraft models/types
func (app *application) HandlerApiAircraftModels(w http.ResponseWriter, r *http.Request) {

models, err := app.db.GetAircraftModels()
if err != nil {
app.handleError(w, err)
}

app.writeJSON(w, http.StatusOK, models)
}
11 changes: 8 additions & 3 deletions app/handlers_airport.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,28 @@ import (

// HandlerAirportByID returns airport record by ID (ICAO or IATA)
func (app *application) HandlerAirportByID(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "id")
uuid := strings.ToUpper(chi.URLParam(r, "id"))

airport, err := app.db.GetAirportByID(uuid)
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}

if airport.IATA == "" && airport.ICAO == "" {
// looks like there is no such ID in airport database
app.warningLog.Printf("cannot find %s in the airport database\n", uuid)
app.writeJSON(w, http.StatusNotFound, models.JSONResponse{OK: false, Message: "Airport not found"})
return
}

app.writeJSON(w, http.StatusOK, airport)
}

/////////////////////////////////////////////////
// for futher review
/////////////////////////////////////////////////

func (app *application) downloadAirportDB(source string) ([]models.Airport, error) {
var airports []models.Airport
var airportsDB map[string]interface{}
Expand Down
105 changes: 37 additions & 68 deletions app/handlers_attachments.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"encoding/json"
"fmt"
"io"
"net/http"
Expand All @@ -13,40 +12,63 @@ import (
)

// HandlerGetAttachments generates attachments
func (app *application) HandlerGetAttachments(w http.ResponseWriter, r *http.Request) {
func (app *application) HandlerApiGetAttachments(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "uuid")

attachments, err := app.db.GetAttachments(uuid)
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}

app.writeJSON(w, http.StatusOK, attachments)
}

// HandlerUploadAttachment handles attachments upload
func (app *application) HandlerUploadAttachment(w http.ResponseWriter, r *http.Request) {
// HandlerApiGetAttachment is a hadnler for attachment download
func (app *application) HandlerApiGetAttachment(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "uuid")

att, err := app.db.GetAttachmentByID(uuid)
if err != nil {
app.handleError(w, err)
return
}

app.writeJSON(w, http.StatusOK, att)
}

// HandlerApiDeleteAttachment is a handler for removing attachments
func (app *application) HandlerApiDeleteAttachment(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "uuid")

err := app.db.DeleteAttachment(uuid)
if err != nil {
app.handleError(w, err)
return
}

var response models.JSONResponse
app.writeOkResponse(w, "Attachment removed")
}

// HandlerApiUploadAttachment handles attachments upload
func (app *application) HandlerApiUploadAttachment(w http.ResponseWriter, r *http.Request) {

err := r.ParseMultipartForm(32 << 20)
if err != nil {
app.errorLog.Println(fmt.Errorf("cannot parse the data, probably the attachment is too big - %s", err))
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}

attachment := models.Attachment{
RecordID: r.PostFormValue("record_id"),
RecordID: r.PostFormValue("id"),
}

// check attached file
file, header, err := r.FormFile("document")
if err != nil {
if !strings.Contains(err.Error(), "no such file") {
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}
} else {
Expand All @@ -56,7 +78,7 @@ func (app *application) HandlerUploadAttachment(w http.ResponseWriter, r *http.R
// read file
bs, err := io.ReadAll(file)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}
attachment.Document = bs
Expand All @@ -65,70 +87,17 @@ func (app *application) HandlerUploadAttachment(w http.ResponseWriter, r *http.R
// new record
uuid, err := uuid.NewRandom()
if err != nil {
app.errorLog.Println(err)
response.OK = false
response.Message = err.Error()
app.handleError(w, err)
return
}

attachment.UUID = uuid.String()

err = app.db.InsertAttachmentRecord(attachment)
if err != nil {
app.errorLog.Println(err)
response.OK = false
response.Message = err.Error()
} else {
response.OK = true
response.Message = "Attachment has been uploaded"

}

app.writeJSON(w, http.StatusOK, response)
}

// HandlerDeleteAttachment is a handler for removing attachments
func (app *application) HandlerDeleteAttachment(w http.ResponseWriter, r *http.Request) {

var att models.Attachment
var response models.JSONResponse

err := json.NewDecoder(r.Body).Decode(&att)
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

err = app.db.DeleteAttachment(att.UUID)
if err != nil {
app.errorLog.Println(err)
response.OK = false
response.Message = err.Error()
} else {
response.OK = true

}

app.writeJSON(w, http.StatusOK, response)
}

// HandlerAttachmentDownload is a hadnler for attachment download
func (app *application) HandlerAttachmentDownload(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "uuid")

att, err := app.db.GetAttachmentByID(uuid)
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
app.handleError(w, err)
return
}

w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", att.DocumentName))

_, err = w.Write(att.Document)
if err != nil {
app.errorLog.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
app.writeOkResponse(w, "Attachment has been uploaded")
}
21 changes: 21 additions & 0 deletions app/handlers_aux.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"fmt"
"io/fs"
"net/http"
"strings"
)

//go:embed static
Expand Down Expand Up @@ -73,3 +74,23 @@

app.writeJSON(w, http.StatusOK, data)
}

//go:embed ui/dist/*

Check failure on line 78 in app/handlers_aux.go

View workflow job for this annotation

GitHub Actions / build

pattern ui/dist/*: no matching files found
var ui embed.FS

func (app *application) HandlerUI() http.Handler {
// Subdirectory inside the embedded FS where the React build is located
dist, _ := fs.Sub(ui, "ui/dist")

fileServer := http.FileServer(http.FS(dist))

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
requestedPath := r.URL.Path

if requestedPath != "/" && !strings.Contains(requestedPath, "assets") {
r.URL.Path = "/"
}

fileServer.ServeHTTP(w, r)
})
}
14 changes: 0 additions & 14 deletions app/handlers_export.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import (
"net/http"

"github.com/go-chi/chi/v5"
"github.com/vsimakhin/web-logbook/internal/csvexport"
"github.com/vsimakhin/web-logbook/internal/models"
"github.com/vsimakhin/web-logbook/internal/pdfexport"
"github.com/vsimakhin/web-logbook/internal/xlsexport"
)

const exportA4 = "A4"
const exportA5 = "A5"
const exportCSV = "csv"
const exportXLS = "xls"

// HandlerExportPDFA4Page is a handler for /export-pdf-a4 page
Expand Down Expand Up @@ -103,15 +101,6 @@ func (app *application) HandlerExportLogbook(w http.ResponseWriter, r *http.Requ
return pdfExporter.ExportA5(flightRecords, w)
}

case exportCSV:
contentType = "text/csv"
fileName = "logbook.csv"
var e csvexport.ExportCSV
e.ExportCSV = settings.ExportCSV
exportFunc = func() error {
return e.Export(flightRecords, w)
}

case exportXLS:
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
fileName = "logbook.xlsx"
Expand Down Expand Up @@ -160,9 +149,6 @@ func (app *application) HandlerExportSettingsSave(w http.ResponseWriter, r *http
} else if format == exportA5 {
currsettings.ExportA5 = settings.ExportA5

} else if format == exportCSV {
currsettings.ExportCSV = settings.ExportCSV

} else if format == exportXLS {
currsettings.ExportXLS = settings.ExportXLS

Expand Down
Loading
Loading