package multistepform import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver import org.thymeleaf.TemplateEngine import org.thymeleaf.context.Context import cask.endpoints.ParamReader import java.util.UUID import scala.jdk.CollectionConverters._ import multistepform.Models.Answers case class Routes()(implicit cc: castor.Context, log: cask.Logger) extends cask.Routes { val templateResolver = new ClassLoaderTemplateResolver() templateResolver.setPrefix("templates/"); templateResolver.setSuffix(".html") templateResolver.setTemplateMode("HTML5") val templateEngine = new TemplateEngine() templateEngine.setTemplateResolver(templateResolver) val sessoinCookieName = "sessionId" /** * This route works with and without 'sessionId' cookie present * set's this cookie if not present, and returns initial 'index.html' * where the form is not yet initialized, and will be requested for the session */ @cask.get("/") def getIndex(ctx: cask.Request) = { val sessionCookie = ctx.cookies.get(sessoinCookieName) lazy val newSessionCookies = sessionCookie match { case None => Seq(cask.Cookie(sessoinCookieName, UUID.randomUUID().toString(), path = "/")) case Some(_) => Seq.empty // don't set new cookies } println(s"getting cookie $sessionCookie will set new? ${newSessionCookies}") val context = new Context() val indexPage = templateEngine.process("index", context) cask.Response( indexPage, headers = Seq("Content-Type" -> "text/html;charset=UTF-8"), cookies = newSessionCookies ) } @cask.get("/force-new-session") def forceNewSession() = { val newSessionCookie = cask.Cookie(sessoinCookieName, UUID.randomUUID().toString(), path = "/") println(s"setting new session ${newSessionCookie.value}") cask.Response( s"New session forced. Force new session", headers = Seq("Content-Type" -> "text/html;charset=UTF-8"), cookies = Seq(newSessionCookie) ) } /** * This method only works when cookie 'sessionId' is present * will get or init Form State for the session, * and return last unsubmitted form step fragment */ @cask.get("/get-form") def getForm(sessionId: cask.Cookie) = { val state = Models.Answers(currentStep = 1) cask.Response("yoyo") val context = new Context() context.setVariable("formData", state) val formFragment = templateEngine.process(state.fragmentName, Set("formFragment").asJava, context) cask.Response( formFragment, headers = Seq("Content-Type" -> "text/html;charset=UTF-8") ) } // i guess let's make step a hidden input? @cask.post("/submit-step/:stepNum") def submitStep(sessionId: cask.Cookie, stepNum: Int, request: cask.Request) = { val id = sessionId.value println(s"got $request for $id") val userAnswers = Sessions.sessionReplies.getOrElse(id, Answers(id)) // now i want to do what? // select 'answerStep' form userAnswers // delegate parsing and saving of the request.text to it // set current step to next // and return next rendered form step // with the 'form data' caclulated from the updated answers cask.Response(s"what i got is $request and ${request.text()}") } @cask.staticResources("/public") def publicFiles() = "public" initialize() }