Compare commits

..

13 Commits

Author SHA1 Message Date
efim 0af0129054 feat(18): not really working docker images 2024-03-15 06:49:46 +00:00
efim 8ff2ec3766 feat(18): displaying + for positive month comparison
wrapping + into span inline, to make it behave like part of
surrounding text in a div, somewhat ok
2024-03-14 14:10:23 +00:00
efim 843c71946f feat(18): desktop styling close enough 2024-03-14 13:51:32 +00:00
efim 51e3629fa5 feat(18): resize without transform, hover states
using transform influences text size, and size of rounded corners

current way hardcodes 8rem for the columns,
maybe i'll pass it as parameter when start doing desktop, i don't know
feels like not a good choice overall, but yeah
2024-03-14 13:04:30 +00:00
efim ddc003eb13 feat(18): random input data 2024-03-13 17:23:32 +00:00
efim e81a22dd10 feat(18): adding dynamic data 2024-03-13 17:08:03 +00:00
efim 269cb2967c feat(18): total this month part styled 2024-03-13 16:42:03 +00:00
efim 6b764ae61b fix(18): prettifying styles 2024-03-13 16:07:32 +00:00
efim 44c89e6559 feat(18): google fonts fix
maybe they stopped working without tracking?
2024-03-13 15:57:42 +00:00
efim a541a2dac2 feat(18): spending bars curDay color 2024-03-13 15:25:25 +00:00
efim ff7baa0a24 feat(18): initial spending columns component
tailwind doesn't seem to allow scale-y-[var(--the-var)]
maybe that's just the scale thing

overall, still setting style variables, this time with css blocks,
i suppose that's ok
2024-03-13 15:15:10 +00:00
efim 623d05da91 feat(18): basic templates 2024-03-13 12:58:26 +00:00
efim 8601288230 feat(18): colors and fonts to tailwind 2024-03-12 09:00:57 +00:00
9 changed files with 298 additions and 69 deletions

View File

@ -25,4 +25,4 @@ run: $(GENERATED_FILES) $(OUTPUT_CSS)
# and then do `go run .` to rebuild all else # and then do `go run .` to rebuild all else
.PHONY: run/live .PHONY: run/live
run/live: run/live:
wgo -verbose -file=.go -file=.templ make run wgo -verbose -file=.go -file=.templ -file=$(INPUT_CSS) -file=$(TAILWIND_CONFIG) make run

View File

@ -1,5 +1,5 @@
rec { rec {
description = "templ-practice"; description = "expenses chart exercise";
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs"; nixpkgs.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
@ -11,7 +11,55 @@ rec {
let let
pkgs = nixpkgs.legacyPackages.${system}; pkgs = nixpkgs.legacyPackages.${system};
templPkg = templ.packages.${system}.templ; templPkg = templ.packages.${system}.templ;
in { pname = "expenses-chart";
version = "0.0.1";
in rec {
thePackage = pkgs.buildGoModule {
inherit pname version;
src = pkgs.nix-gitignore.gitignoreSource [ ] ./.;
vendorHash = "sha256-sKuP3TsRD3MXBGtdSRnX62eXBQE1ASWFQu0kLlXSlFA=";
preBuild = ''
# Adding the Tailwind build step to preBuild
${pkgs.nodePackages.tailwindcss}/bin/tailwindcss -i ./input.css -o static/output.css
# Adding generation of go code from templ files
${templPkg}/bin/templ generate
'';
};
packages = rec {
"${pname}" = thePackage;
"${pname}-image" = pkgs.dockerTools.buildLayeredImage {
name = pname;
tag = "latest";
created = "now";
config = {
Cmd = [ "${thePackage}/bin/templ-exercise" ];
ExposedPorts = { "3000/tcp" = { }; };
};
};
image-hello = pkgs.dockerTools.buildLayeredImage { # so, wow, this works
name = pname;
tag = "latest";
config.Cmd = [ "${pkgs.hello}/bin/hello" ];
};
image = pkgs.dockerTools.buildImage {
name = pname;
tag = "latest";
created = "now";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [ thePackage pkgs.dockerTools.binSh pkgs.coreutils ];
pathsToLink = [ "/bin" "/dist" "/public" ];
};
config = {
Cmd = [ "/bin/templ-exercise" ];
ExposedPorts = { "8080/tcp" = { }; };
};
};
};
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = [ buildInputs = [
pkgs.go pkgs.go
@ -20,7 +68,7 @@ rec {
pkgs.gopls pkgs.gopls
pkgs.gnumake pkgs.gnumake
templPkg templPkg
pkgs.tailwindcss pkgs.nodePackages.tailwindcss
]; ];
shellHook = '' shellHook = ''
export GOPATH=$PWD/.go export GOPATH=$PWD/.go

View File

@ -1,3 +1,7 @@
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html {
font-size: 18px;
}

View File

@ -1,17 +1,29 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"math/rand"
"net/http" "net/http"
"sunshine.industries/temp-exercise/templates" "sunshine.industries/temp-exercise/templates"
"github.com/a-h/templ"
) )
func randomDailyExpense() float32 {
return 10 + rand.Float32()*100
}
func main() { func main() {
component := templates.Hello("some name")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Handle("/", templ.Handler(component)) component := templates.IndexPage(templates.PageData{
Balance: 500 + rand.Float32()*1000,
Expenses: []float32{randomDailyExpense(), randomDailyExpense(), randomDailyExpense(), randomDailyExpense(), randomDailyExpense(), randomDailyExpense(), randomDailyExpense()},
TotalThisMonth: 50 + rand.Float32()*600,
PercentComparedToLastMonth: -5 + 10*rand.Float32(),
})
component.Render(context.Background(), w)
})
staticFs := http.FileServer(http.Dir("./static")) staticFs := http.FileServer(http.Dir("./static"))
http.Handle("/static/", http.StripPrefix("/static/", staticFs)) http.Handle("/static/", http.StripPrefix("/static/", staticFs))

View File

@ -34,3 +34,74 @@ how would i commit to subtree upstream if there are conflicting changes?
maybe i'll just get denied, as simple as that. maybe i'll just get denied, as simple as that.
allright! let's add exercise specific data (again) allright! let's add exercise specific data (again)
* so, starting dev
old process:
1. open second browser and open png with style
first mobile
2. enable view C-S-m in firefox
the responsive mode
i suppose next is adding colors to tailwind configuration?
from the styleguide file
also
3. check desktop style, whether any big rearrangements are required
so that i'd start mobile with way to rearrange things
do i have a separate note with all of these things?
i've also used some commands to vertically center my stuff
** DONE allright, tailwind config go
font, size, colors
** well, i don't really want to go on.
but yeah, i'll need hierarchy of the elements.
** ok. thoughs:
the componets would be
- my balance bubble
because it is spacially separate
- spending summary
- graph inside spending summary
or maybe don't even need that
the component should take up all space provided to it.
if parent would want to add space around - that's easy to do,
but if component insists on adding space around itself - harder to reuse?
because then if parent would want to have child take up all space - negative padding?
*** allright, @ to include sub templates
** well, last part? preparing the docker container for deployment on Render.com?
which port should be used?
also, this would be first time i'll add templ as a build step
** for some reason image doesn't work well
podman run -d -p 9090:8080 localhost/expenses-chart:latest /nix/store/l4r6glmzbvkhg97lp4dn7nm76w6hz41g-expenses-chart-0.0.1/bin/temp-exercise
this runs,
but podman run -it expenses-chart:latest
Error: crun: executable file `/nix/store/l4r6glmzbvkhg97lp4dn7nm76w6hz41g-expenses-chart-0.0.1/bin/templ-exercise` not found in $PATH: No such file or directory: OCI runtime attempted to invoke a command that was not found
oh, well
** you know what - i give up
for some reason when i open url to app running in container,
and it's on the 8080 port of the host machine - the static files are served
if i use any other port of local machine, to forward into container,
the static files are not served
maybe this is bug in go? i don't know
StripPrefix doesn't seem to do anything
and for some reason in this specific exercise CMD doesn't work in the container
so let's just give up!
i could try to write a docker file and check with that, but yeah

View File

@ -1,8 +1,28 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./**/*.templ"], content: ["./templates/index.templ"],
theme: { theme: {
extend: {}, extend: {
fontFamily: {
'sans': ['DM Sans', 'sans-serif'],
},
fontWeight: {
'normal': 400,
'bold': 700,
}
},
colors: {
primary: {
'soft-red': 'hsl(10, 79%, 65%)',
cyan: 'hsl(186, 34%, 60%)',
},
neutral: {
'dark-brown': 'hsl(25, 47%, 15%)',
'medium-brown': 'hsl(28, 10%, 53%)',
cream: 'hsl(27, 66%, 92%)',
'very-pale-orange': 'hsl(33, 100%, 98%)',
},
}
}, },
plugins: [], plugins: [],
} }

View File

@ -1,16 +0,0 @@
package templates
var myVar string = "some string, changed. and more"
var anotherVar string = "hoho, cool"
templ Hello(name string) {
<html>
<head>
<title>This is the title of the the webpage!</title>
<link href="/static/output.css" rel="stylesheet"/>
</head>
<body class="bg-blue-100 text-xl">
<p class="text-purple-700">This is an example paragraph. Anything in the <strong>body</strong> tag will appear on the page, just like this <strong>p</strong> tag and its contents.</p>
</body>
</html>
}

View File

@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
<title>Frontend Mentor | Expenses chart component</title>
<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
<style>
.attribution { font-size: 11px; text-align: center; }
.attribution a { color: hsl(228, 45%, 44%); }
</style>
</head>
<body>
My balance
$921.48
Spending - Last 7 days
mon
tue
wed
thu
fri
sat
sun
Total this month
$478.33
+2.4%
from last month
<div class="attribution">
Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
Coded by <a href="#">Your Name Here</a>.
</div>
</body>
</html>

View File

@ -0,0 +1,133 @@
package templates
import "fmt"
import "slices"
type PageData struct {
Balance float32
Expenses []float32
TotalThisMonth float32
PercentComparedToLastMonth float32
}
templ myBalanceComponent(balance float32) {
<div class="flex flex-row rounded-xl text-neutral-very-pale-orange text-xs md:text-base bg-primary-soft-red p-4 shadow md:rounded-[1rem] md:p-7">
<div class="grow ">
My balance
<p class="text-xl md:text-2xl font-bold">${ fmt.Sprintf("%.2f", balance) }</p>
</div>
<img
src="./static/images/logo.svg"
alt="App logo: a white circle overlapping from the left a filled in black circle"
/>
</div>
}
var days []string = []string{"mon", "tue", "wed", "thu", "fri", "sat", "sun"}
// returns templ SummaryComponent
// with all attributes computed from the expenses slice
// the percentages of the columns, current day number, etc
// NOTE: this seems to be the way to mix go calculations and templates
func prepareSummaryComponent(expenses []float32, totalThisMonth, percentComparedToLastMonth float32) templ.Component {
fmt.Println("hello, preparing expenses: ", expenses)
max := slices.Max(expenses)
percentages := make([]float32, 0, len(expenses))
for _, price := range expenses {
percentages = append(percentages, price/max)
}
currentDayNum := 2
return spendingSummaryComponent(expenses, percentages, currentDayNum, percentComparedToLastMonth, totalThisMonth)
}
css expenseBarVars(percentage float32) {
--height-percentage: { fmt.Sprintf("%.2f", percentage) };
height: calc(var(--height-percentage) * 8rem);
}
templ dayExpenseColumn(expense, percentage float32, day string, isCurrentDay bool) {
<div class="flex flex-col justify-end items-center h-32">
<div
class={ "rounded group relative w-full h-12",
expenseBarVars(percentage),
templ.KV("bg-primary-soft-red hover:bg-primary-soft-red/70", !isCurrentDay),
templ.KV("bg-primary-cyan hover:bg-primary-cyan/70", isCurrentDay),
"hover:cursor-pointer" }
>
<span class="absolute left-1/2 -translate-x-1/2 -translate-y-7 opacity-0 group-hover:opacity-100 bg-neutral-dark-brown text-neutral-cream rounded text-xs p-1">${ fmt.Sprintf("%.2f", expense ) }</span>
</div>
<p class="text-neutral-medium-brown text-xs py-2">{ day }</p>
</div>
}
// The 7 vertical bars of the per-day expenses
templ expensesChart(expenses, percentages []float32, currentDayNum int) {
<div class="grid grid-cols-7 place-content-between gap-x-3">
for i := 0; i < 7; i++ {
@dayExpenseColumn(expenses[i], percentages[i], days[i], currentDayNum == i)
}
</div>
}
// Big container with chard and total expenses of the week
templ spendingSummaryComponent(expenses, percentages []float32, currentDayNum int, totalThisMonth, percentComparedToLastMonth float32) {
<div class="bg-neutral-very-pale-orange rounded-xl shadow p-4 py-6 flex flex-col gap-y-4 md:p-7 md:px-10 md:rounded-[1rem] md:gap-y-5">
<p2 class="text-neutral-dark-brown text-xl font-bold pb-6 md:text-2xl md:pb-12 ">Spending - Last 7 days</p2>
@expensesChart(expenses, percentages, currentDayNum)
<hr class="bg-neutral-cream border-t-0 h-0.5"/>
<div class="grid grid-cols-2 text-sm text-neutral-medium-brown">
<p class="col-span-full">Total this month</p>
<div class="grow">
<p class="grid items-center text-neutral-dark-brown text-2xl font-bold h-full md:text-4xl md:py-2">$ { fmt.Sprintf("%.2f", totalThisMonth) }</p>
</div>
<div class="text-right grid content-center">
<div class="text-neutral-dark-brown font-bold ">
if (percentComparedToLastMonth > 0) {
<span class="inline">+</span>
}
{ fmt.Sprintf("%.2f", percentComparedToLastMonth) }%
</div>
from last month
</div>
</div>
</div>
}
templ WidgetsComponend(pageData PageData) {
<div class="flex flex-col gap-4">
@myBalanceComponent(pageData.Balance)
@prepareSummaryComponent(pageData.Expenses, pageData.PercentComparedToLastMonth, pageData.TotalThisMonth)
</div>
}
templ IndexPage(pageData PageData) {
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="/styles/templ.css"/>
<link href="/static/output.css" rel="stylesheet"/>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!-- displays site properly based on user's device -->
<link rel="icon" type="image/png" sizes="32x32" href="./static/images/favicon-32x32.png"/>
<title>Frontend Mentor | Expenses chart component</title>
<!-- Feel free to remove these styles or customise in your own stylesheet 👍 -->
<style>
.attribution { font-size: 11px; text-align: center; }
.attribution a { color: hsl(228, 45%, 44%); }
</style>
</head>
<body class="bg-neutral-cream text-bold p-4 h-full grid place-items-center">
<main class="w-full md:w-1/4">
@WidgetsComponend(pageData)
</main>
<div class="attribution fixed bottom-0 inset-x-0">
Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
Coded by <a href="#">Your Name Here</a>.
</div>
</body>
</html>
}