106 lines
3.4 KiB
Org Mode
106 lines
3.4 KiB
Org Mode
* Frontend Mentor - Order summary card solution
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: frontend-mentor---order-summary-card-solution
|
|
:END:
|
|
This is a solution to the
|
|
[[https://www.frontendmentor.io/challenges/order-summary-component-QlPmajDUj][Order
|
|
summary card challenge on Frontend Mentor]]. Frontend Mentor challenges
|
|
help you improve your coding skills by building realistic projects.
|
|
|
|
** Overview
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: overview
|
|
:END:
|
|
*** The challenge
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: the-challenge
|
|
:END:
|
|
Users should be able to:
|
|
|
|
- See hover states for interactive elements
|
|
|
|
*** Screenshot
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: screenshot
|
|
:END:
|
|
[[screenshot-desktop.png]]
|
|
[[screenshot-mobile.png]]
|
|
|
|
*** Links
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: links
|
|
:END:
|
|
- [[https://www.frontendmentor.io/solutions/responsive-by-tailwindcss-ssr-on-scala-with-cask-thymeleaf-template-bMMgFdajHT][Solution URL]]
|
|
- [[https://efim-frontentmentor-order-summary.onrender.com/][Live Site URL]]
|
|
Free instance on render.com is turned off after 15 minutes of inactivity, please give the server a moment to start up if you're visiting it at the moment of being turned off
|
|
|
|
** My process
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: my-process
|
|
:END:
|
|
*** Built with
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: built-with
|
|
:END:
|
|
- Semantic HTML5 markup
|
|
- Tailwincss
|
|
- Mobile-first workflow
|
|
- SSR in Scala & Cask webserver
|
|
- Thymeleaf templates
|
|
|
|
**** running during development
|
|
installing "sbt-revolver":
|
|
#+begin_src scala
|
|
addSbtPlugin("io.spray" % "sbt-revolver" % "0.10.0")
|
|
#+end_src
|
|
|
|
then `~reStart -p 49012`
|
|
|
|
otherwise =~= in front of sbt command reruns it only if it finished execution.
|
|
|
|
*** What I learned
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: what-i-learned
|
|
:END:
|
|
**** placing Thymeleaf templates
|
|
if they are in src/main/resources - they should be available on class path.
|
|
and search should be relative to the resources, i.e putting templates into dir "templates"
|
|
then
|
|
#+begin_src scala
|
|
val templateResolver = new ClassLoaderTemplateResolver()
|
|
templateResolver.setPrefix("templates/");
|
|
templateResolver.setSuffix(".html")
|
|
val result = templateEngine.process("index", context)
|
|
#+end_src
|
|
will look for file in "src/main/resources/templates/index.html" to treat as a template
|
|
**** to reload web server during development - sbt plugin "sbt-revolver"
|
|
|
|
**** with these html templates I can start learning and using Emmet mode in Emacs
|
|
https://github.com/smihica/emmet-mode
|
|
|
|
**** Importing Thymeleaf template
|
|
There are other methods to include templates like th:replace and th:include, which have slightly different behaviours. th:insert keeps the host tag (the div in your case), th:replace replaces the whole host tag with the fragment, and th:include replaces the inner content of the host tag with the fragment.
|
|
|
|
So i can actually have the "Order Summary" as reusable part.
|
|
**** getting responsive background image with Tailwincss
|
|
#+begin_src html
|
|
<div
|
|
class="bg-[url('../public/images/pattern-background-mobile.svg')] fixed h-screen w-screen bg-no-repeat bg-contain md:bg-[url('../public/images/pattern-background-desktop.svg')]"
|
|
></div>
|
|
#+end_src
|
|
|
|
*** Continued development
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: continued-development
|
|
:END:
|
|
This was first exercise I've done with Thymeleaf templates.
|
|
|
|
Next is using fragments with some dynamic content and styling.
|
|
Then attempting to include htmx fueled reactivity.
|
|
|
|
** Acknowledgments
|
|
:PROPERTIES:
|
|
:CUSTOM_ID: acknowledgments
|
|
:END:
|
|
Lots of gratitude to Thymeleaf templates, they seem to be very advandced and thoughtfully designed
|