My personal website, in gleam+lustre!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Some final round-ups?


Signed-off-by: MLC Bloeiman <mar@strawmelonjuice.com>

+261 -312
+261 -312
src/homepage/view/cv.gleam
··· 1 1 import gleam/dict 2 + import gleam/list 2 3 import lustre/attribute.{attribute} 3 4 import lustre/element.{type Element} 4 5 import lustre/element/html ··· 152 153 #("skills-php-desc", #( 153 154 "7 & 8, SymfonyPHP, API's and fullstack applications", 154 155 "7 & 8, SymfonyPHP, API's en volledige applicaties", 156 + )), 157 + #("skills-js-title", #( 158 + "JavaScript / TypeScript (programming language)", 159 + "JavaScript / TypeScript (programmeertaal)", 160 + )), 161 + #("skills-js-desc", #( 162 + "Fullstack, NodeJS/BunJS, backend, ExpressJS, browsers", 163 + "Fullstack, NodeJS/BunJS, backend, ExpressJS, browsers", 155 164 )), 156 165 #("view-source", #("[source code]", "[broncode]")), 157 166 #("translate", #("to Dutch", "naar Engels")), ··· 497 506 html.div( 498 507 [ 499 508 attribute("style", "grid-template-columns: repeat(1, 1fr);"), 500 - attribute.class("grid gap-x-6 gap-y-3"), 509 + attribute.class("grid gap-x-6 gap-y-0"), 501 510 ], 502 511 [ 503 512 html.div( ··· 748 757 attribute.class("grid gap-x-6 gap-y-3"), 749 758 ], 750 759 [ 751 - html.div( 752 - [ 753 - attribute.class( 754 - "relative space-y-2 pl-4 group-[.sidebar]:pl-0", 755 - ), 756 - ], 757 - [ 758 - html.div( 759 - [ 760 - attribute.class( 761 - "relative -ml-4 group-[.sidebar]:ml-0", 762 - ), 763 - ], 764 - [ 765 - html.div( 766 - [ 767 - attribute.class("pl-4 group-[.sidebar]:pl-0"), 768 - ], 769 - [ 770 - html.div([], [ 771 - html.div([attribute.class("font-bold")], [ 772 - localise("skills-language-title"), 773 - ]), 774 - html.div([], []), 775 - ]), 776 - ], 777 - ), 778 - html.div( 779 - [ 780 - attribute.class( 781 - "absolute inset-y-0 -left-px border-l-4 border-primary group-[.sidebar]:hidden", 782 - ), 783 - ], 784 - [], 785 - ), 786 - ], 787 - ), 788 - html.div( 789 - [ 790 - attribute.class( 791 - "absolute inset-y-0 left-0 border-l border-primary group-[.sidebar]:hidden", 792 - ), 793 - ], 794 - [], 795 - ), 760 + skill_item( 761 + name: [ 762 + localise("skills-language-title"), 796 763 ], 764 + description: [], 765 + strength: -1.0, 797 766 ), 798 - html.div( 799 - [ 800 - attribute.class( 801 - "relative space-y-2 pl-4 group-[.sidebar]:pl-0", 802 - ), 767 + skill_item( 768 + name: [ 769 + localise("skills-rust-title"), 803 770 ], 804 - [ 805 - html.div( 806 - [ 807 - attribute.class( 808 - "relative -ml-4 group-[.sidebar]:ml-0", 809 - ), 810 - ], 811 - [ 812 - html.div( 813 - [ 814 - attribute.class("pl-4 group-[.sidebar]:pl-0"), 815 - ], 816 - [ 817 - html.div([], [ 818 - html.div([attribute.class("font-bold")], [ 819 - localise("skills-rust-title"), 820 - ]), 821 - html.div([], [ 822 - html.text( 823 - "Rocket, Actix, Axum, Ratatui, Tauri, Sync & Async", 824 - ), 825 - ]), 826 - ]), 827 - ], 828 - ), 829 - html.div( 830 - [ 831 - attribute.class( 832 - "absolute inset-y-0 -left-px border-l-4 border-primary group-[.sidebar]:hidden", 833 - ), 834 - ], 835 - [], 836 - ), 837 - ], 838 - ), 839 - html.div( 840 - [attribute.class("flex items-center gap-x-1.5")], 841 - [ 842 - html.div( 843 - [ 844 - attribute.class( 845 - "h-2 w-4 border border-primary bg-primary", 846 - ), 847 - ], 848 - [], 849 - ), 850 - html.div( 851 - [ 852 - attribute.class( 853 - "h-2 w-4 border border-primary bg-primary", 854 - ), 855 - ], 856 - [], 857 - ), 858 - html.div( 859 - [ 860 - attribute.class( 861 - "h-2 w-4 border border-primary bg-primary", 862 - ), 863 - ], 864 - [], 865 - ), 866 - html.div( 867 - [ 868 - attribute.class( 869 - "h-2 w-4 border border-primary bg-primary/25", 870 - ), 871 - ], 872 - [], 873 - ), 874 - html.div( 875 - [ 876 - attribute.class("h-2 w-4 border border-primary"), 877 - ], 878 - [], 879 - ), 880 - ], 881 - ), 882 - html.div( 883 - [ 884 - attribute.class( 885 - "absolute inset-y-0 left-0 border-l border-primary group-[.sidebar]:hidden", 886 - ), 887 - ], 888 - [], 771 + description: [ 772 + html.text( 773 + "Rocket, Actix, Axum, Ratatui, Tauri, Sync & Async", 889 774 ), 890 775 ], 776 + strength: 3.75, 891 777 ), 892 - html.div( 893 - [ 894 - attribute.class( 895 - "relative space-y-2 pl-4 group-[.sidebar]:pl-0", 896 - ), 778 + skill_item( 779 + name: [ 780 + localise("skills-gleam-title"), 897 781 ], 898 - [ 899 - html.div( 900 - [ 901 - attribute.class( 902 - "relative -ml-4 group-[.sidebar]:ml-0", 903 - ), 904 - ], 905 - [ 906 - html.div( 907 - [ 908 - attribute.class("pl-4 group-[.sidebar]:pl-0"), 909 - ], 910 - [ 911 - html.div([], [ 912 - html.div([attribute.class("font-bold")], [ 913 - localise("skills-gleam-title"), 914 - ]), 915 - html.div([], [ 916 - html.text( 917 - "Lustre, JS interop, Erlang & BEAM", 918 - ), 919 - ]), 920 - ]), 921 - ], 922 - ), 923 - html.div( 924 - [ 925 - attribute.class( 926 - "absolute inset-y-0 -left-px border-l-4 border-primary group-[.sidebar]:hidden", 927 - ), 928 - ], 929 - [], 930 - ), 931 - ], 932 - ), 933 - html.div( 934 - [attribute.class("flex items-center gap-x-1.5")], 935 - [ 936 - html.div( 937 - [ 938 - attribute.class( 939 - "h-2 w-4 border border-primary bg-primary", 940 - ), 941 - ], 942 - [], 943 - ), 944 - html.div( 945 - [ 946 - attribute.class( 947 - "h-2 w-4 border border-primary bg-primary", 948 - ), 949 - ], 950 - [], 951 - ), 952 - html.div( 953 - [ 954 - attribute.class( 955 - "h-2 w-4 border border-primary bg-primary", 956 - ), 957 - ], 958 - [], 959 - ), 960 - html.div( 961 - [ 962 - attribute.class( 963 - "h-2 w-4 border border-primary bg-primary", 964 - ), 965 - ], 966 - [], 967 - ), 968 - html.div( 969 - [ 970 - attribute.class("h-2 w-4 border border-primary"), 971 - ], 972 - [], 973 - ), 974 - ], 975 - ), 976 - html.div( 977 - [ 978 - attribute.class( 979 - "absolute inset-y-0 left-0 border-l border-primary group-[.sidebar]:hidden", 980 - ), 981 - ], 982 - [], 983 - ), 782 + description: [ 783 + html.text("Lustre, JS interop, Erlang & BEAM"), 984 784 ], 785 + strength: 4.5, 985 786 ), 986 - html.div( 987 - [ 988 - attribute.class( 989 - "relative space-y-2 pl-4 group-[.sidebar]:pl-0", 990 - ), 787 + skill_item( 788 + name: [ 789 + localise("skills-php-title"), 991 790 ], 992 - [ 993 - html.div( 994 - [ 995 - attribute.class( 996 - "relative -ml-4 group-[.sidebar]:ml-0", 997 - ), 998 - ], 999 - [ 1000 - html.div( 1001 - [ 1002 - attribute.class("pl-4 group-[.sidebar]:pl-0"), 1003 - ], 1004 - [ 1005 - html.div([], [ 1006 - html.div([attribute.class("font-bold")], [ 1007 - localise("skills-php-title"), 1008 - ]), 1009 - html.div([], [localise("skills-php-desc")]), 1010 - ]), 1011 - ], 1012 - ), 1013 - html.div( 1014 - [ 1015 - attribute.class( 1016 - "absolute inset-y-0 -left-px border-l-4 border-primary group-[.sidebar]:hidden", 1017 - ), 1018 - ], 1019 - [], 1020 - ), 1021 - ], 1022 - ), 1023 - html.div( 1024 - [attribute.class("flex items-center gap-x-1.5")], 1025 - [ 1026 - html.div( 1027 - [ 1028 - attribute.class( 1029 - "h-2 w-4 border border-primary bg-primary", 1030 - ), 1031 - ], 1032 - [], 1033 - ), 1034 - html.div( 1035 - [ 1036 - attribute.class( 1037 - "h-2 w-4 border border-primary bg-primary", 1038 - ), 1039 - ], 1040 - [], 1041 - ), 1042 - html.div( 1043 - [ 1044 - attribute.class( 1045 - "h-2 w-4 border border-primary bg-primary", 1046 - ), 1047 - ], 1048 - [], 1049 - ), 1050 - html.div( 1051 - [ 1052 - attribute.class("h-2 w-4 border border-primary"), 1053 - ], 1054 - [], 1055 - ), 1056 - html.div( 1057 - [ 1058 - attribute.class("h-2 w-4 border border-primary"), 1059 - ], 1060 - [], 1061 - ), 1062 - ], 1063 - ), 1064 - html.div( 1065 - [ 1066 - attribute.class( 1067 - "absolute inset-y-0 left-0 border-l border-primary group-[.sidebar]:hidden", 1068 - ), 1069 - ], 1070 - [], 1071 - ), 791 + description: [localise("skills-php-desc")], 792 + strength: 2.5, 793 + ), 794 + skill_item( 795 + name: [ 796 + localise("skills-js-title"), 1072 797 ], 798 + description: [localise("skills-js-desc")], 799 + strength: 4.0, 1073 800 ), 1074 801 ], 1075 802 ), ··· 1535 1262 ), 1536 1263 ]) 1537 1264 } 1265 + 1266 + fn skill_item( 1267 + name skillname: List(Element(a)), 1268 + description skilldesc: List(element.Element(a)), 1269 + strength strength: Float, 1270 + ) { 1271 + let unfilled_skill_block = 1272 + html.div([attribute.class("h-2 w-4 border border-primary")], []) 1273 + let filled_skill_block = 1274 + html.div([attribute.class("h-2 w-4 border border-primary bg-primary")], []) 1275 + let p25_skill_block = 1276 + html.div( 1277 + [attribute.class("h-2 w-4 border border-primary bg-primary/25")], 1278 + [], 1279 + ) 1280 + let p50_skill_block = 1281 + html.div( 1282 + [attribute.class("h-2 w-4 border border-primary bg-primary/50")], 1283 + [], 1284 + ) 1285 + let p75_skill_block = 1286 + html.div( 1287 + [attribute.class("h-2 w-4 border border-primary bg-primary/75")], 1288 + [], 1289 + ) 1290 + html.div([attribute.class("relative space-y-2 pl-4 group-[.sidebar]:pl-0")], [ 1291 + html.div([attribute.class("relative -ml-4 group-[.sidebar]:ml-0")], [ 1292 + html.div([attribute.class("pl-4 group-[.sidebar]:pl-0")], [ 1293 + html.div([], [ 1294 + html.div([attribute.class("font-bold")], skillname), 1295 + html.div([], skilldesc), 1296 + ]), 1297 + ]), 1298 + html.div( 1299 + [ 1300 + attribute.class( 1301 + "absolute inset-y-0 -left-px border-l-4 border-primary group-[.sidebar]:hidden", 1302 + ), 1303 + ], 1304 + [], 1305 + ), 1306 + ]), 1307 + case strength <. 0.0 { 1308 + True -> element.none() 1309 + False -> 1310 + html.div( 1311 + [attribute.class("flex items-center gap-x-1.5")], 1312 + case strength { 1313 + 0.0 -> [ 1314 + unfilled_skill_block, 1315 + unfilled_skill_block, 1316 + unfilled_skill_block, 1317 + unfilled_skill_block, 1318 + unfilled_skill_block, 1319 + ] 1320 + 1321 + 0.25 -> [ 1322 + p25_skill_block, 1323 + unfilled_skill_block, 1324 + unfilled_skill_block, 1325 + unfilled_skill_block, 1326 + unfilled_skill_block, 1327 + ] 1328 + 1329 + 0.5 -> [ 1330 + p50_skill_block, 1331 + unfilled_skill_block, 1332 + unfilled_skill_block, 1333 + unfilled_skill_block, 1334 + unfilled_skill_block, 1335 + ] 1336 + 1337 + 0.75 -> [ 1338 + p75_skill_block, 1339 + unfilled_skill_block, 1340 + unfilled_skill_block, 1341 + unfilled_skill_block, 1342 + unfilled_skill_block, 1343 + ] 1344 + 1345 + 1.0 -> [ 1346 + filled_skill_block, 1347 + unfilled_skill_block, 1348 + unfilled_skill_block, 1349 + unfilled_skill_block, 1350 + unfilled_skill_block, 1351 + ] 1352 + 1353 + 1.25 -> [ 1354 + filled_skill_block, 1355 + p25_skill_block, 1356 + unfilled_skill_block, 1357 + unfilled_skill_block, 1358 + unfilled_skill_block, 1359 + ] 1360 + 1361 + 1.5 -> [ 1362 + filled_skill_block, 1363 + p50_skill_block, 1364 + unfilled_skill_block, 1365 + unfilled_skill_block, 1366 + unfilled_skill_block, 1367 + ] 1368 + 1369 + 1.75 -> [ 1370 + filled_skill_block, 1371 + p75_skill_block, 1372 + unfilled_skill_block, 1373 + unfilled_skill_block, 1374 + unfilled_skill_block, 1375 + ] 1376 + 1377 + 2.0 -> [ 1378 + filled_skill_block, 1379 + filled_skill_block, 1380 + unfilled_skill_block, 1381 + unfilled_skill_block, 1382 + unfilled_skill_block, 1383 + ] 1384 + 1385 + 2.25 -> [ 1386 + filled_skill_block, 1387 + filled_skill_block, 1388 + p25_skill_block, 1389 + unfilled_skill_block, 1390 + unfilled_skill_block, 1391 + ] 1392 + 1393 + 2.5 -> [ 1394 + filled_skill_block, 1395 + filled_skill_block, 1396 + p50_skill_block, 1397 + unfilled_skill_block, 1398 + unfilled_skill_block, 1399 + ] 1400 + 1401 + 2.75 -> [ 1402 + filled_skill_block, 1403 + filled_skill_block, 1404 + p75_skill_block, 1405 + unfilled_skill_block, 1406 + unfilled_skill_block, 1407 + ] 1408 + 1409 + 3.0 -> [ 1410 + filled_skill_block, 1411 + filled_skill_block, 1412 + filled_skill_block, 1413 + unfilled_skill_block, 1414 + unfilled_skill_block, 1415 + ] 1416 + 1417 + 3.25 -> [ 1418 + filled_skill_block, 1419 + filled_skill_block, 1420 + filled_skill_block, 1421 + p25_skill_block, 1422 + unfilled_skill_block, 1423 + ] 1424 + 1425 + 3.5 -> [ 1426 + filled_skill_block, 1427 + filled_skill_block, 1428 + filled_skill_block, 1429 + p50_skill_block, 1430 + unfilled_skill_block, 1431 + ] 1432 + 1433 + 3.75 -> [ 1434 + filled_skill_block, 1435 + filled_skill_block, 1436 + filled_skill_block, 1437 + p75_skill_block, 1438 + unfilled_skill_block, 1439 + ] 1440 + 1441 + 4.0 -> [ 1442 + filled_skill_block, 1443 + filled_skill_block, 1444 + filled_skill_block, 1445 + filled_skill_block, 1446 + unfilled_skill_block, 1447 + ] 1448 + 1449 + 4.25 -> [ 1450 + filled_skill_block, 1451 + filled_skill_block, 1452 + filled_skill_block, 1453 + filled_skill_block, 1454 + p25_skill_block, 1455 + ] 1456 + 1457 + 4.5 -> [ 1458 + filled_skill_block, 1459 + filled_skill_block, 1460 + filled_skill_block, 1461 + filled_skill_block, 1462 + p50_skill_block, 1463 + ] 1464 + 1465 + 4.75 -> [ 1466 + filled_skill_block, 1467 + filled_skill_block, 1468 + filled_skill_block, 1469 + filled_skill_block, 1470 + p75_skill_block, 1471 + ] 1472 + 5.0 -> filled_skill_block |> list.repeat(5) 1473 + _ -> [element.none()] 1474 + }, 1475 + ) 1476 + }, 1477 + html.div( 1478 + [ 1479 + attribute.class( 1480 + "absolute inset-y-0 left-0 border-l border-primary group-[.sidebar]:hidden", 1481 + ), 1482 + ], 1483 + [], 1484 + ), 1485 + ]) 1486 + }