11package handlers
22
3- import "github.com/swamphacks/core/apps/api/internal/services"
3+ import (
4+ "bytes"
5+ "encoding/json"
6+ "errors"
7+ "io"
8+ "net/http"
9+ "strconv"
10+
11+ "github.com/go-chi/chi/v5"
12+ "github.com/go-playground/validator/v10"
13+ "github.com/google/uuid"
14+ "github.com/rs/zerolog/log"
15+ res "github.com/swamphacks/core/apps/api/internal/api/response"
16+ "github.com/swamphacks/core/apps/api/internal/ctxutils"
17+ "github.com/swamphacks/core/apps/api/internal/db/repository"
18+ "github.com/swamphacks/core/apps/api/internal/db/sqlc"
19+ "github.com/swamphacks/core/apps/api/internal/services"
20+ )
421
522type ApplicationHandler struct {
623 appService * services.ApplicationService
@@ -11,3 +28,194 @@ func NewApplicationHandler(appService *services.ApplicationService) *Application
1128 appService : appService ,
1229 }
1330}
31+
32+ func getEventID (w http.ResponseWriter , r * http.Request ) (uuid.UUID , error ) {
33+ eventIdStr := chi .URLParam (r , "eventId" )
34+ if eventIdStr == "" {
35+ err := errors .New ("missing_event_id" )
36+ errMsg := "The event ID is missing from the URL!"
37+
38+ log .Err (err ).Msg (errMsg )
39+
40+ res .SendError (w , http .StatusBadRequest ,
41+ res .NewError (err .Error (), errMsg ))
42+
43+ return uuid .Nil , err
44+ }
45+
46+ eventId , err := uuid .Parse (eventIdStr )
47+ if err != nil {
48+ err = errors .New ("invalid_event_id" )
49+ errMsg := "The event ID is not a valid UUID"
50+
51+ log .Err (err ).Msg (errMsg )
52+
53+ res .SendError (w , http .StatusBadRequest ,
54+ res .NewError (err .Error (), errMsg ))
55+
56+ return uuid .Nil , err
57+ }
58+
59+ return eventId , nil
60+ }
61+
62+ func (h * ApplicationHandler ) GetApplicationByUserAndEventID (w http.ResponseWriter , r * http.Request ) {
63+ eventId , err := getEventID (w , r )
64+
65+ if err != nil {
66+ return
67+ }
68+
69+ userIdPtr := ctxutils .GetUserIdFromCtx (r .Context ())
70+
71+ if userIdPtr == nil {
72+ return
73+ }
74+
75+ userId := * userIdPtr
76+
77+ params := sqlc.GetApplicationByUserAndEventIDParams {
78+ UserID : userId ,
79+ EventID : eventId ,
80+ }
81+
82+ application , err := h .appService .GetApplicationByUserAndEventID (r .Context (), params )
83+
84+ if err != nil {
85+ if err == repository .ErrApplicationNotFound {
86+ params := sqlc.CreateApplicationParams {
87+ UserID : userId ,
88+ EventID : eventId ,
89+ }
90+ newApplication , err := h .appService .CreateApplication (r .Context (), params )
91+ if err != nil {
92+ res .SendError (w , http .StatusBadRequest , res .NewError ("create_application_error" , "can't create application" ))
93+ } else {
94+ res .Send (w , http .StatusOK , newApplication )
95+ }
96+ res .SendError (w , http .StatusBadRequest , res .NewError ("application_not_found" , "can't find application" ))
97+ } else {
98+ res .SendError (w , http .StatusBadRequest , res .NewError ("get_application_error" , "error retrieving application" ))
99+ }
100+
101+ return
102+ }
103+
104+ res .Send (w , http .StatusOK , application )
105+ }
106+
107+ func (h * ApplicationHandler ) SubmitApplication (w http.ResponseWriter , r * http.Request ) {
108+ // Parse multipart form (10 MB max memory)
109+ err := r .ParseMultipartForm (10 << 20 )
110+ if err != nil {
111+ http .Error (w , "Failed to parse form: " + err .Error (), http .StatusBadRequest )
112+ return
113+ }
114+
115+ var submission services.ApplicationSubmissionFields
116+
117+ // Map form values
118+ submission .FirstName = r .FormValue ("firstName" )
119+ submission .LastName = r .FormValue ("lastName" )
120+
121+ if ageStr := r .FormValue ("age" ); ageStr != "" {
122+ if age , err := strconv .Atoi (ageStr ); err == nil {
123+ submission .Age = age
124+ }
125+ }
126+
127+ submission .Phone = r .FormValue ("phone" )
128+ submission .PreferredEmail = r .FormValue ("preferredEmail" )
129+ submission .UniversityEmail = r .FormValue ("universityEmail" )
130+ submission .Linkedin = r .FormValue ("linkedin" )
131+ submission .Github = r .FormValue ("github" )
132+
133+ if ageCertStr := r .FormValue ("ageCertification" ); ageCertStr != "" {
134+ submission .AgeCertification = (ageCertStr == "true" || ageCertStr == "1" )
135+ }
136+
137+ submission .School = r .FormValue ("school" )
138+ submission .Level = r .FormValue ("level" )
139+ submission .Year = r .FormValue ("year" )
140+ submission .GraduationYear = r .FormValue ("graduationYear" )
141+ submission .Majors = r .FormValue ("majors" )
142+ submission .Minors = r .FormValue ("minors" )
143+ submission .Experience = r .FormValue ("experience" )
144+ submission .ProjectExperience = r .FormValue ("projectExperience" )
145+ submission .ShirtSize = r .FormValue ("shirtSize" )
146+ submission .Essay1 = r .FormValue ("essay1" )
147+ submission .Essay2 = r .FormValue ("essay2" )
148+ submission .Referral = r .FormValue ("referral" )
149+ submission .PictureConsent = r .FormValue ("pictureConsent" )
150+ submission .InpersonAcknowledgement = r .FormValue ("inpersonAcknowledgement" )
151+ submission .AgreeToConduct = r .FormValue ("agreeToConduct" )
152+ submission .InfoShareAuthorization = r .FormValue ("infoShareAuthorization" )
153+ submission .AgreeToMLHEmails = r .FormValue ("agreeToMLHEmails" )
154+
155+ resumeFile , _ , err := r .FormFile ("resume[]" )
156+ if err == nil {
157+ defer resumeFile .Close ()
158+ }
159+
160+ resumeFileBuffer := bytes .NewBuffer (nil )
161+
162+ if _ , err := io .Copy (resumeFileBuffer , resumeFile ); err != nil {
163+ return
164+ }
165+
166+ validate := validator .New ()
167+ if err := validate .Struct (submission ); err != nil {
168+ res .SendError (w , http .StatusBadRequest , res .NewError ("invalid_request" , err .Error ()))
169+ return
170+ }
171+
172+ eventId , err := getEventID (w , r )
173+
174+ if err == nil {
175+ w .WriteHeader (http .StatusBadRequest )
176+ return
177+ }
178+
179+ userIdPtr := ctxutils .GetUserIdFromCtx (r .Context ())
180+
181+ if userIdPtr == nil {
182+ w .WriteHeader (http .StatusBadRequest )
183+ return
184+ }
185+
186+ userId := * userIdPtr
187+
188+ h .appService .SubmitApplication (r .Context (), submission , resumeFileBuffer .Bytes (), userId , eventId )
189+
190+ w .WriteHeader (http .StatusOK )
191+ }
192+
193+ func (h * ApplicationHandler ) SaveApplication (w http.ResponseWriter , r * http.Request ) {
194+ var data any
195+
196+ if err := json .NewDecoder (r .Body ).Decode (& data ); err != nil {
197+ res .SendError (w , http .StatusBadRequest , res .NewError ("invalid_form_data" , "Something went wrong while parsing form submission" ))
198+ return
199+ }
200+
201+ eventId , err := getEventID (w , r )
202+
203+ if err != nil {
204+ return
205+ }
206+
207+ userIdPtr := ctxutils .GetUserIdFromCtx (r .Context ())
208+
209+ if userIdPtr == nil {
210+ return
211+ }
212+
213+ userId := * userIdPtr
214+
215+ h .appService .SaveApplication (r .Context (), data , sqlc.UpdateApplicationParams {
216+ UserID : userId ,
217+ EventID : eventId ,
218+ })
219+
220+ w .WriteHeader (http .StatusOK )
221+ }
0 commit comments