forked from tildetown/town
approval/rejection
parent
29ba24d36c
commit
6ec2a52db8
|
@ -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
|
||||||
render()
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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(`
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue