diff --git a/cmd/review/main.go b/cmd/review/main.go index 2dc700d..286f9b2 100644 --- a/cmd/review/main.go +++ b/cmd/review/main.go @@ -45,8 +45,7 @@ func (r *reviewer) Review(s *models.TownSignup, decision models.SignupDecision) s.DecisionTime = time.Now() s.Decision = decision s.DecidedBy = r.adminName - s.Insert(r.db) - return nil + return s.Review(r.db) } func (r *reviewer) AddNote(s *models.TownSignup, content string) error { @@ -222,30 +221,39 @@ func _main() error { pages.SwitchToPage("main") }) - // TODO cleanEmailModal + reviewModal := tview.NewFlex().SetDirection(tview.FlexRow) - cleanEmailModal := tview.NewFlex().SetDirection(tview.FlexRow) - emailView := tview.NewTextView() - cleanEmailModal.AddItem(tview.NewTextView().SetText("email value?"), 1, 1, false) - cleanEmailModal.AddItem(emailView, 0, 1, false) + providedEmailView := tview.NewTextView() + providedEmailView.SetTitle("provided email input") - pages.AddPage("main", mainFlex, true, true) - pages.AddPage("error", errorModal, false, false) - pages.AddPage("notate", notate, true, false) + reviewForm := tview.NewForm() + decisionFI := tview.NewDropDown().SetLabel("decision") + decisionFI.SetOptions([]string{"accepted", "rejected"}, func(_ string, _ int) {}) - app := tview.NewApplication() - app.SetRoot(pages, true) + cleanEmailInput := tview.NewInputField() + cleanEmailInput.SetLabel("clean email") + cleanEmailInput.SetAcceptanceFunc(func(tx string, _ rune) bool { return len(tx) > 0 }) - // TODO replace imperative shit with a signupManager - advanceSignup := func() { - signupIx++ - if signupIx == len(signups) { - signupIx = 0 + reviewForm.AddFormItem(decisionFI) + reviewForm.AddFormItem(cleanEmailInput) + reviewForm.AddButton("submit", func() { + currSignup := signups[signupIx] + cleanEmail := reviewForm.GetFormItemByLabel("clean email").(*tview.InputField).GetText() + currSignup.CleanEmail = cleanEmail + + decision := models.SignupRejected + _, d := reviewForm.GetFormItemByLabel("decision").(*tview.DropDown).GetCurrentOption() + if d == "accepted" { + decision = models.SignupAccepted + } + + err := r.Review(currSignup, decision) + if err != nil { + errorModal.SetText(fmt.Sprintf("error! failed to submit review: %s", err.Error())) + pages.SwitchToPage("error") + return } - render() - } - removeSignup := func(signup *models.TownSignup) { newSignups := []*models.TownSignup{} for ix, s := range signups { if ix != signupIx { @@ -258,8 +266,29 @@ func _main() error { signupIx = 0 } } + updateCount() render() - } + if decision == models.SignupAccepted { + // TODO generate invite token + // TODO send invite email + } + pages.SwitchToPage("main") + }) + reviewForm.AddButton("cancel", func() { + pages.SwitchToPage("main") + }) + + reviewModal.AddItem(tview.NewTextView().SetText("provided email input"), 1, 1, false) + reviewModal.AddItem(providedEmailView, 0, 1, false) + reviewModal.AddItem(reviewForm, 0, 1, true) + + pages.AddPage("main", mainFlex, true, true) + pages.AddPage("error", errorModal, false, false) + pages.AddPage("notate", notate, true, false) + pages.AddPage("review", reviewModal, true, false) + + app := tview.NewApplication() + app.SetRoot(pages, true) app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { currPage, _ := pages.GetFrontPage() @@ -268,7 +297,11 @@ func _main() error { } switch event.Rune() { case 's': - advanceSignup() + signupIx++ + if signupIx == len(signups) { + signupIx = 0 + } + render() case 'r': if len(signups) > 0 { signupIx = rand.Intn(len(signups)) @@ -278,33 +311,17 @@ func _main() error { if len(signups) == 0 { return nil } - // TODO modal for collecting clean email - signup := signups[signupIx] - err := r.Review(signup, models.SignupAccepted) - if err != nil { - errorModal.SetText(fmt.Sprintf("error! failed to approve '%d': %s", signup.ID, err.Error())) - pages.SwitchToPage("error") - return nil - } - removeSignup(signup) - updateCount() - render() - // TODO generate invite token - // TODO send invite email + providedEmailView.SetText(signups[signupIx].Email) + decisionFI.SetCurrentOption(0) + pages.SwitchToPage("review") + app.SetFocus(cleanEmailInput) case 'R': if len(signups) == 0 { return nil } - signup := signups[signupIx] - err = r.Review(signup, models.SignupRejected) - if err != nil { - errorModal.SetText(fmt.Sprintf("error! failed to reject '%d': %s", signup.ID, err.Error())) - pages.SwitchToPage("error") - return nil - } - removeSignup(signup) - updateCount() - render() + providedEmailView.SetText(signups[signupIx].Email) + decisionFI.SetCurrentOption(1) + pages.SwitchToPage("review") case 'N': if len(signups) == 0 { return nil diff --git a/models/models.go b/models/models.go index 501a83e..d3376cb 100644 --- a/models/models.go +++ b/models/models.go @@ -132,6 +132,33 @@ func (s *TownSignup) RefreshNotes(db *sql.DB) error { return nil } +func (s *TownSignup) Review(db *sql.DB) error { + stmt, err := db.Prepare(` + UPDATE signups SET + decision = ?, + decision_time = ?, + decided_by = ?, + clean_email = ? + WHERE id = ?`) + if err != nil { + return err + } + + _, err = stmt.Exec( + s.Decision, + s.DecisionTime.Unix(), + s.DecidedBy, + s.CleanEmail, + s.ID) + if err != nil { + return err + } + + stmt.Close() + + return nil +} + func (s *TownSignup) All(db *sql.DB) ([]*TownSignup, error) { // TODO notes; circle back once can author them rows, err := db.Query(` diff --git a/sql/create_signups_db.sql b/sql/create_signups_db.sql index e4551a6..b32f8eb 100644 --- a/sql/create_signups_db.sql +++ b/sql/create_signups_db.sql @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS signups ( -- admin provided decision_time TEXT, - decision TEXT + decision TEXT, decided_by TEXT, clean_email TEXT );