approval/rejection

trunk
vilmibm 2023-02-23 22:20:39 +00:00
parent 29ba24d36c
commit 6ec2a52db8
3 changed files with 90 additions and 46 deletions

View File

@ -45,8 +45,7 @@ func (r *reviewer) Review(s *models.TownSignup, decision models.SignupDecision)
s.DecisionTime = time.Now() s.DecisionTime = time.Now()
s.Decision = decision s.Decision = decision
s.DecidedBy = r.adminName s.DecidedBy = r.adminName
s.Insert(r.db) return s.Review(r.db)
return nil
} }
func (r *reviewer) AddNote(s *models.TownSignup, content string) error { func (r *reviewer) AddNote(s *models.TownSignup, content string) error {
@ -222,30 +221,39 @@ func _main() error {
pages.SwitchToPage("main") pages.SwitchToPage("main")
}) })
// TODO cleanEmailModal reviewModal := tview.NewFlex().SetDirection(tview.FlexRow)
cleanEmailModal := tview.NewFlex().SetDirection(tview.FlexRow) providedEmailView := tview.NewTextView()
emailView := tview.NewTextView() providedEmailView.SetTitle("provided email input")
cleanEmailModal.AddItem(tview.NewTextView().SetText("email value?"), 1, 1, false)
cleanEmailModal.AddItem(emailView, 0, 1, false)
pages.AddPage("main", mainFlex, true, true) reviewForm := tview.NewForm()
pages.AddPage("error", errorModal, false, false) decisionFI := tview.NewDropDown().SetLabel("decision")
pages.AddPage("notate", notate, true, false) decisionFI.SetOptions([]string{"accepted", "rejected"}, func(_ string, _ int) {})
app := tview.NewApplication() cleanEmailInput := tview.NewInputField()
app.SetRoot(pages, true) cleanEmailInput.SetLabel("clean email")
cleanEmailInput.SetAcceptanceFunc(func(tx string, _ rune) bool { return len(tx) > 0 })
// TODO replace imperative shit with a signupManager reviewForm.AddFormItem(decisionFI)
advanceSignup := func() { reviewForm.AddFormItem(cleanEmailInput)
signupIx++ reviewForm.AddButton("submit", func() {
if signupIx == len(signups) { currSignup := signups[signupIx]
signupIx = 0 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{} newSignups := []*models.TownSignup{}
for ix, s := range signups { for ix, s := range signups {
if ix != signupIx { if ix != signupIx {
@ -258,8 +266,29 @@ func _main() error {
signupIx = 0 signupIx = 0
} }
} }
updateCount()
render() 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 { app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
currPage, _ := pages.GetFrontPage() currPage, _ := pages.GetFrontPage()
@ -268,7 +297,11 @@ func _main() error {
} }
switch event.Rune() { switch event.Rune() {
case 's': case 's':
advanceSignup() signupIx++
if signupIx == len(signups) {
signupIx = 0
}
render()
case 'r': case 'r':
if len(signups) > 0 { if len(signups) > 0 {
signupIx = rand.Intn(len(signups)) signupIx = rand.Intn(len(signups))
@ -278,33 +311,17 @@ func _main() error {
if len(signups) == 0 { if len(signups) == 0 {
return nil return nil
} }
// TODO modal for collecting clean email providedEmailView.SetText(signups[signupIx].Email)
signup := signups[signupIx] decisionFI.SetCurrentOption(0)
err := r.Review(signup, models.SignupAccepted) pages.SwitchToPage("review")
if err != nil { app.SetFocus(cleanEmailInput)
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
case 'R': case 'R':
if len(signups) == 0 { if len(signups) == 0 {
return nil return nil
} }
signup := signups[signupIx] providedEmailView.SetText(signups[signupIx].Email)
err = r.Review(signup, models.SignupRejected) decisionFI.SetCurrentOption(1)
if err != nil { pages.SwitchToPage("review")
errorModal.SetText(fmt.Sprintf("error! failed to reject '%d': %s", signup.ID, err.Error()))
pages.SwitchToPage("error")
return nil
}
removeSignup(signup)
updateCount()
render()
case 'N': case 'N':
if len(signups) == 0 { if len(signups) == 0 {
return nil return nil

View File

@ -132,6 +132,33 @@ func (s *TownSignup) RefreshNotes(db *sql.DB) error {
return nil 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) { func (s *TownSignup) All(db *sql.DB) ([]*TownSignup, error) {
// TODO notes; circle back once can author them // TODO notes; circle back once can author them
rows, err := db.Query(` rows, err := db.Query(`

View File

@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS signups (
-- admin provided -- admin provided
decision_time TEXT, decision_time TEXT,
decision TEXT decision TEXT,
decided_by TEXT, decided_by TEXT,
clean_email TEXT clean_email TEXT
); );