forms.gno
3.01 Kb ยท 131 lines
1package forms
2
3import (
4 "time"
5
6 "gno.land/p/nt/seqid"
7)
8
9// FieldType examples :
10// - string: "string";
11// - number: "number";
12// - boolean: "boolean";
13// - choice: "['Pizza', 'Schnitzel', 'Burger']";
14// - multi-choice: "{'Pizza', 'Schnitzel', 'Burger'}";
15type Field struct {
16 Label string
17 FieldType string
18 Required bool
19}
20
21type Form struct {
22 ID string
23 Owner address
24 Title string
25 Description string
26 Fields []Field
27 CreatedAt time.Time
28 openAt time.Time
29 closeAt time.Time
30}
31
32// Answers example :
33// - ["Alex", 21, true, 0, [0, 1]]
34type Submission struct {
35 FormID string
36 Author address
37 Answers string // json
38 SubmittedAt time.Time
39}
40
41type FormDB struct {
42 Forms []*Form
43 Answers []*Submission
44 IDCounter seqid.ID
45}
46
47func NewDB() *FormDB {
48 return &FormDB{
49 Forms: make([]*Form, 0),
50 Answers: make([]*Submission, 0),
51 }
52}
53
54// This function checks if the form is open by verifying the given dates
55// - If a form doesn't have any dates, it's considered open
56// - If a form has only an open date, it's considered open if the open date is in the past
57// - If a form has only a close date, it's considered open if the close date is in the future
58// - If a form has both open and close dates, it's considered open if the current date is between the open and close dates
59func (form *Form) IsOpen() bool {
60 openAt, errOpen := form.OpenAt()
61 closedAt, errClose := form.CloseAt()
62
63 noOpenDate := errOpen != nil
64 noCloseDate := errClose != nil
65
66 if noOpenDate && noCloseDate {
67 return true
68 }
69
70 if noOpenDate && !noCloseDate {
71 return time.Now().Before(closedAt)
72 }
73
74 if !noOpenDate && noCloseDate {
75 return time.Now().After(openAt)
76 }
77
78 now := time.Now()
79 return now.After(openAt) && now.Before(closedAt)
80}
81
82// OpenAt returns the open date of the form if it exists
83func (form *Form) OpenAt() (time.Time, error) {
84 if form.openAt.IsZero() {
85 return time.Time{}, errNoOpenDate
86 }
87
88 return form.openAt, nil
89}
90
91// CloseAt returns the close date of the form if it exists
92func (form *Form) CloseAt() (time.Time, error) {
93 if form.closeAt.IsZero() {
94 return time.Time{}, errNoCloseDate
95 }
96
97 return form.closeAt, nil
98}
99
100// GetForm returns a form by its ID if it exists
101func (db *FormDB) GetForm(id string) (*Form, error) {
102 for _, form := range db.Forms {
103 if form.ID == id {
104 return form, nil
105 }
106 }
107 return nil, errFormNotFound
108}
109
110// GetAnswer returns an answer by its form - and author ids if it exists
111func (db *FormDB) GetAnswer(formID string, author address) (*Submission, error) {
112 for _, answer := range db.Answers {
113 if answer.FormID == formID && answer.Author.String() == author.String() {
114 return answer, nil
115 }
116 }
117 return nil, errAnswerNotFound
118}
119
120// GetSubmissionsByFormID returns a list containing the existing form submissions by the form ID
121func (db *FormDB) GetSubmissionsByFormID(formID string) []*Submission {
122 submissions := make([]*Submission, 0)
123
124 for _, answer := range db.Answers {
125 if answer.FormID == formID {
126 submissions = append(submissions, answer)
127 }
128 }
129
130 return submissions
131}