feat: installing htmx and toggling card size
This commit is contained in:
parent
3e00aa5f3d
commit
b6ba1dfcd0
|
@ -0,0 +1,16 @@
|
||||||
|
.bsp/
|
||||||
|
.scala-build/
|
||||||
|
.metals/
|
||||||
|
.direnv
|
||||||
|
*/dist/
|
||||||
|
/11-single-price-grid-component/.bloop/
|
||||||
|
|
||||||
|
**/.bloop
|
||||||
|
**/project/project/
|
||||||
|
**/project/metals.sbt
|
||||||
|
**/project/.bloop
|
||||||
|
**/project/target/
|
||||||
|
**/target/
|
||||||
|
|
||||||
|
*/result
|
||||||
|
result
|
|
@ -0,0 +1,90 @@
|
||||||
|
{ pkgs, lib, sbt-derivation }:
|
||||||
|
|
||||||
|
let
|
||||||
|
pname = "testimonials-grid-section";
|
||||||
|
package = sbt-derivation.lib.mkSbtDerivation {
|
||||||
|
inherit pkgs pname;
|
||||||
|
# ...and the rest of the arguments
|
||||||
|
version = "0.0.1";
|
||||||
|
src = pkgs.nix-gitignore.gitignoreSource [ ] ./.;
|
||||||
|
nativeBuildInputs = [ pkgs.nodePackages.tailwindcss ];
|
||||||
|
buildPhase = ''
|
||||||
|
sbt assembly
|
||||||
|
tailwindcss -i ./src/input.css -o ./output.css
|
||||||
|
'';
|
||||||
|
# css path different from ordinary development,
|
||||||
|
# because .gitignore makes it unavailable during nix build
|
||||||
|
# anyway copied to correct place
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp target/scala-*/${pname}-assembly-*.jar $out/bin/${pname}.jar
|
||||||
|
mkdir -p $out/bin/dist
|
||||||
|
cp ./output.css $out/bin/dist/output.css
|
||||||
|
cp -r public $out/bin/public
|
||||||
|
'';
|
||||||
|
|
||||||
|
depsSha256 = "sha256-Y5RktcE3fxUJci4o7LTuNlBEybTdVRqsG551AkVeRPw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
module = { config, pkgs, ... }:
|
||||||
|
let cfg = config.services.${pname};
|
||||||
|
in {
|
||||||
|
options.services.${pname} = {
|
||||||
|
enable = lib.mkEnableOption "My frontendmentor exercise ${pname}";
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
default = 8080;
|
||||||
|
description = "Port to listen on.";
|
||||||
|
};
|
||||||
|
|
||||||
|
host = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "localhost";
|
||||||
|
description = "Host to bind to.";
|
||||||
|
};
|
||||||
|
|
||||||
|
useNginx = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Whether to use Nginx to proxy requests.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
users.groups."${pname}-group" = { };
|
||||||
|
users.users."${pname}-user" = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "${pname}-group";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.${pname} =
|
||||||
|
let serverHost = if cfg.useNginx then "localhost" else cfg.host;
|
||||||
|
in {
|
||||||
|
description = "Exercise app ${pname}";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
after = [ "network.target" ];
|
||||||
|
startLimitIntervalSec = 30;
|
||||||
|
startLimitBurst = 10;
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart =
|
||||||
|
"${pkgs.jdk}/bin/java -jar ${package}/bin/${pname}.jar -p ${
|
||||||
|
toString cfg.port
|
||||||
|
} --host ${serverHost}";
|
||||||
|
WorkingDirectory = "${package}/bin";
|
||||||
|
Restart = "on-failure";
|
||||||
|
User = "${pname}-user";
|
||||||
|
Group = "${pname}-group";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = lib.mkIf cfg.useNginx {
|
||||||
|
virtualHosts.${cfg.host} = {
|
||||||
|
locations."/".proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
package = package;
|
||||||
|
module = module;
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -11,15 +11,14 @@
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
sizes="32x32"
|
sizes="32x32"
|
||||||
href=".public/images/favicon-32x32.png"
|
href="public/images/favicon-32x32.png"
|
||||||
/>
|
/>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:wght@500;600&display=swap"
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Barlow+Semi+Condensed:wght@500;600&display=swap"
|
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
<title>Frontend Mentor | [Challenge Name Here]</title>
|
<title>Frontend Mentor | [Challenge Name Here]</title>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="public/deps/htmx.min.js"></script>
|
||||||
<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
|
<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
|
||||||
<style>
|
<style>
|
||||||
.attribution {
|
.attribution {
|
||||||
|
@ -31,13 +30,16 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="grid place-content-center bg-light-grayish-blue grid-flow-dense">
|
<body class="grid grid-flow-col-dense place-content-center bg-light-grayish-blue">
|
||||||
<div class="py-20 px-7 space-y-7 min-h-screen text-white md:grid md:gap-[30px] md:py-0 md:px-0 h-max max-w-[1200px] md:grid-cols-[repeat(auto-fill,_255px)] md:auto-rows-[280px] md:mt-[160px] md:space-y-0">
|
<div class="py-20 px-7 space-y-7 min-h-screen text-white md:grid md:gap-[30px] md:py-0 md:px-0 h-max max-w-[1200px] md:grid-cols-[repeat(auto-fill,_255px)] md:auto-rows-[280px] md:mt-[160px] md:space-y-0">
|
||||||
<section
|
<section
|
||||||
th:fragment="testimonialSection(testimonials)"
|
th:fragment="testimonialSection(testimonials)"
|
||||||
th:each="testimonial : ${testimonials}"
|
th:each="testimonial : ${testimonials}"
|
||||||
th:classappend="${testimonial.additionalClasses}? ${testimonial.additionalClasses} : 'bg-moderate-violet md:col-span-2'"
|
th:classappend="${testimonial.additionalSizeClasses} + ' ' + ${testimonial.additionalColorClasses}"
|
||||||
class="py-7 px-10 flex flex-col justify-between rounded-xl first:bg-[url('../public/images/bg-pattern-quotation.svg')] bg-no-repeat bg-[right_2rem_top] drop-shadow "
|
class="py-7 px-10 flex flex-col justify-between rounded-xl first:bg-[url('../public/images/bg-pattern-quotation.svg')] bg-no-repeat bg-[right_2rem_top] drop-shadow "
|
||||||
|
th:id="${testimonial.id}"
|
||||||
|
th:hx-get="'/testimonial/' + ${testimonial.id} + '?nextOrientation=' + ${testimonial.followupOrientation}"
|
||||||
|
hx-swap="outerHTML"
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<img
|
<img
|
||||||
|
|
|
@ -55,15 +55,20 @@ object Main {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@cask.get("/testimonial/:id")
|
@cask.get("/testimonial/:id")
|
||||||
def getTestimonial(id: Int) = {
|
def getTestimonial(id: String, nextOrientation: Int) = {
|
||||||
|
// println(s"got params $nextOrientation")
|
||||||
val context = new Context()
|
val context = new Context()
|
||||||
val test = Testimonial.sameAsRequested.head
|
// wow, i need copy because attributes are vars and not vals,
|
||||||
context.setVariable(
|
// didn't have to think about this in a long long time
|
||||||
"selectedTestimonials",
|
val foundTestimonial =
|
||||||
List(test).asJava
|
Testimonial.sameAsRequested.find(_.id == id).get.copy()
|
||||||
)
|
|
||||||
|
foundTestimonial.setNextSizeClass(nextOrientation)
|
||||||
|
// println(
|
||||||
|
// s"should change size and orientation : $foundTestimonial "
|
||||||
|
// )
|
||||||
|
context.setVariable("selectedTestimonials", List(foundTestimonial).asJava)
|
||||||
val result = templateEngine.process("testimonialSection", context)
|
val result = templateEngine.process("testimonialSection", context)
|
||||||
println(s"will try with $test ; to get \n$result")
|
|
||||||
cask.Response(
|
cask.Response(
|
||||||
result,
|
result,
|
||||||
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
||||||
|
|
|
@ -1,51 +1,65 @@
|
||||||
package testimonialsgrid
|
package testimonialsgrid
|
||||||
import scala.beans.BeanProperty
|
import scala.beans.BeanProperty
|
||||||
|
import java.util.UUID
|
||||||
|
import scala.util.Random
|
||||||
|
|
||||||
final case class Testimonial(
|
final case class Testimonial(
|
||||||
@BeanProperty var avatarUrl: String,
|
@BeanProperty var avatarUrl: String,
|
||||||
@BeanProperty var author: String,
|
@BeanProperty var author: String,
|
||||||
@BeanProperty var header: String,
|
@BeanProperty var header: String,
|
||||||
@BeanProperty var text: String,
|
@BeanProperty var text: String,
|
||||||
@BeanProperty var age: Int,
|
@BeanProperty var id: String,
|
||||||
@BeanProperty var additionalClasses: String
|
@BeanProperty var additionalColorClasses: String,
|
||||||
)
|
@BeanProperty var additionalSizeClasses: String,
|
||||||
|
@BeanProperty var followupOrientation: Int = 0,
|
||||||
|
sequentSizeClasses: List[String] = List("")
|
||||||
|
) {
|
||||||
|
def setNextSizeClass(key: Int): Unit = {
|
||||||
|
val nextOrientationIndex = (key + 1) % sequentSizeClasses.size
|
||||||
|
this.additionalSizeClasses = sequentSizeClasses(nextOrientationIndex)
|
||||||
|
this.followupOrientation = nextOrientationIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
object Testimonial {
|
object Testimonial {
|
||||||
val colorful = List(
|
val colorful = List(
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-patrick.jpg",
|
"public/images/image-patrick.jpg",
|
||||||
"Leopold",
|
"Leopold",
|
||||||
" Odio facilisis mauris sit amet massa vitae tortor condimentum lacinia quis vel eros donec ac odio tempor orci dapibus ultrices. ",
|
" Odio facilisis mauris sit amet massa vitae tortor condimentum lacinimport java.util.UUID ia quis vel eros donec ac odio tempor orci dapibus ultrices. ",
|
||||||
" Nibh sed pulvinar proin gravida hendrerit? Massa tincidunt nunc pulvinar sapien et ligula libero nunc!",
|
" Nibh sed pulvinar proin gravida hendrerit? Massa tincidunt nunc pulvinar sapien et ligula libero nunc!",
|
||||||
91,
|
UUID.randomUUID().toString(),
|
||||||
"bg-red-500"
|
"bg-red-500",
|
||||||
|
""
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-jonathan.jpg",
|
"public/images/image-jonathan.jpg",
|
||||||
"Aragorn",
|
"Aragorn",
|
||||||
" Eleifend donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum! ",
|
" Eleifend donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum! ",
|
||||||
" Egestas fringilla phasellus faucibus scelerisque eleifend! Dignissim enim, sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in! ",
|
" Egestas fringilla phasellus faucibus scelerisque eleifend! Dignissim enim, sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in! ",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-blue-500 md:col-span-2"
|
"bg-blue-500",
|
||||||
|
"md:col-span-2"
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-jeanette.jpg",
|
"public/images/image-jeanette.jpg",
|
||||||
"Jeanatte Mamamia",
|
"Jeanatte Mamamia",
|
||||||
" Id venenatis a, condimentum vitae sapien pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed tempus, urna et pharetra pharetra! ",
|
" Id venenatis a, condimentum vitae sapien pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed tempus, urna et pharetra pharetra! ",
|
||||||
" Amet nulla facilisi morbi tempus iaculis urna, id volutpat lacus laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Lorem dolor, sed viverra ipsum nunc aliquet bibendum? ",
|
" Amet nulla facilisi morbi tempus iaculis urna, id volutpat lacus laoreet non curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Lorem dolor, sed viverra ipsum nunc aliquet bibendum? ",
|
||||||
91,
|
UUID.randomUUID().toString(),
|
||||||
"bg-green-200 text-black md:row-span-2"
|
"bg-green-200 text-black",
|
||||||
|
"md:row-span-2"
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-kira.jpg",
|
"public/images/image-kira.jpg",
|
||||||
"Mamma mia",
|
"Mamma mia",
|
||||||
" Id venenatis a, condimentum vitae sapien pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed tempus, urna et pharetra pharetra! ",
|
" Id venenatis a, condimentum vitae sapien pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas sed tempus, urna et pharetra pharetra! ",
|
||||||
""" Quis hendrerit dolor magna eget est lorem ipsum dolor sit amet, consectetur adipiscing elit pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis! Nam libero justo, laoreet sit amet cursus sit amet, dictum sit amet justo donec.
|
""" Quis hendrerit dolor magna eget est lorem ipsum dolor sit amet, consectetur adipiscing elit pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis! Nam libero justo, laoreet sit amet cursus sit amet, dictum sit amet justo donec.
|
||||||
""",
|
""",
|
||||||
91,
|
UUID.randomUUID().toString(),
|
||||||
"bg-amber-200 text-black md:col-span-2"
|
"bg-amber-200 text-black",
|
||||||
),
|
"md:col-span-2"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val sameAsRequested = List(
|
val sameAsRequested = List(
|
||||||
|
@ -61,8 +75,10 @@ object Testimonial {
|
||||||
The next 12 weeks was the best - and most grueling - time of my life. Since completing
|
The next 12 weeks was the best - and most grueling - time of my life. Since completing
|
||||||
the course, I’ve successfully switched careers, working as a Software Engineer at a VR startup. ”
|
the course, I’ve successfully switched careers, working as a Software Engineer at a VR startup. ”
|
||||||
""",
|
""",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-moderate-violet md:col-span-2"
|
"bg-moderate-violet",
|
||||||
|
"md:col-span-2",
|
||||||
|
sequentSizeClasses = List("md:row-span-2", "md:col-span-2")
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-jonathan.jpg",
|
"public/images/image-jonathan.jpg",
|
||||||
|
@ -70,8 +86,9 @@ object Testimonial {
|
||||||
" The team was very supportive and kept me motivated ",
|
" The team was very supportive and kept me motivated ",
|
||||||
""" " Egestas fringilla phasellus faucibus scelerisque eleifend! Dignissim enim, sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in! ",
|
""" " Egestas fringilla phasellus faucibus scelerisque eleifend! Dignissim enim, sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in! ",
|
||||||
""",
|
""",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-very-dark-grayish-blue md:col-span-1"
|
"bg-very-dark-grayish-blue",
|
||||||
|
"md:col-span-1"
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-jeanette.jpg",
|
"public/images/image-jeanette.jpg",
|
||||||
|
@ -80,8 +97,9 @@ object Testimonial {
|
||||||
""" “ Thank you for the wonderful experience! I now have a job I really enjoy, and make a good living
|
""" “ Thank you for the wonderful experience! I now have a job I really enjoy, and make a good living
|
||||||
while doing something I love. ”
|
while doing something I love. ”
|
||||||
""",
|
""",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-white text-very-dark-blackish-blue md:col-span-1"
|
"bg-white text-very-dark-blackish-blue",
|
||||||
|
"md:col-span-1"
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-patrick.jpg",
|
"public/images/image-patrick.jpg",
|
||||||
|
@ -93,8 +111,10 @@ object Testimonial {
|
||||||
junior developer. The standard is above the rest. You will get the personal attention you need from
|
junior developer. The standard is above the rest. You will get the personal attention you need from
|
||||||
an incredible community of smart and amazing people. ”
|
an incredible community of smart and amazing people. ”
|
||||||
""",
|
""",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-very-dark-blackish-blue md:col-span-2"
|
"bg-very-dark-blackish-blue",
|
||||||
|
"md:col-span-2",
|
||||||
|
sequentSizeClasses = List("md:row-span-2", "md:col-span-2")
|
||||||
),
|
),
|
||||||
new Testimonial(
|
new Testimonial(
|
||||||
"public/images/image-kira.jpg",
|
"public/images/image-kira.jpg",
|
||||||
|
@ -112,8 +132,10 @@ object Testimonial {
|
||||||
experience. It certainly helped me land a job as a full-stack
|
experience. It certainly helped me land a job as a full-stack
|
||||||
developer after receiving multiple offers. 100% recommend! ”
|
developer after receiving multiple offers. 100% recommend! ”
|
||||||
""",
|
""",
|
||||||
55,
|
UUID.randomUUID().toString(),
|
||||||
"bg-white text-very-dark-blackish-blue md:row-span-2 md:col-end-[-1] md:row-start-1"
|
"bg-white text-very-dark-blackish-blue",
|
||||||
|
"md:row-span-2 md:col-end-[-1] md:row-start-1",
|
||||||
|
sequentSizeClasses = List("md:row-span-2","md:col-span-2")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
inherit pkgs sbt-derivation;
|
inherit pkgs sbt-derivation;
|
||||||
lib = pkgs.lib;
|
lib = pkgs.lib;
|
||||||
};
|
};
|
||||||
|
testimonials-grid = import ./13-testimonials-grid-section/default.nix {
|
||||||
|
inherit pkgs sbt-derivation;
|
||||||
|
lib = pkgs.lib;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
@ -34,6 +38,8 @@
|
||||||
nixosModules.price-grid-app = price-grid.module;
|
nixosModules.price-grid-app = price-grid.module;
|
||||||
packages.order-summary = order-summary.package;
|
packages.order-summary = order-summary.package;
|
||||||
nixosModules.order-summary = order-summary.module;
|
nixosModules.order-summary = order-summary.module;
|
||||||
|
packages.testimonials-grid = testimonials-grid.package;
|
||||||
|
nixosModules.testimonials-grid = testimonials-grid.module;
|
||||||
});
|
});
|
||||||
# see https://serokell.io/blog/practical-nix-flakes
|
# see https://serokell.io/blog/practical-nix-flakes
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue