First basic homepage with times & juustodiilerit links
This commit is contained in:
commit
469bfc5640
16 changed files with 2887 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
/dist
|
2390
Cargo.lock
generated
Normal file
2390
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
37
Cargo.toml
Normal file
37
Cargo.toml
Normal file
|
@ -0,0 +1,37 @@
|
|||
[package]
|
||||
name = "homepage"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Tanguy Gérôme <tanguy@juustodiilerit.fi>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
# leptos = { version = "0.7", features = ["nightly"] }
|
||||
leptos = { version = "0.7", features = ["csr"] }
|
||||
# leptos_router = { version = "0.7", features = ["nightly"] }
|
||||
leptos_router = { version = "0.7" }
|
||||
leptos_meta = { version = "0.7" }
|
||||
console_log = "1"
|
||||
log = "0.4"
|
||||
console_error_panic_hook = "0.1"
|
||||
chrono = { version = "0.4.40", features = ["unstable-locales"] }
|
||||
calendrier = "1.0.0"
|
||||
leptos-use = "0.15.7"
|
||||
|
||||
# utils
|
||||
# strum = { version = "0.25", features = ["derive", "strum_macros"] }
|
||||
# strum_macros = "0.25"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
wasm-bindgen-test = "0.3"
|
||||
web-sys = { version = "0.3", features = ["Document", "Window"] }
|
||||
|
||||
|
||||
[profile.release]
|
||||
opt-level = 'z'
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
panic = "abort"
|
79
README.md
Normal file
79
README.md
Normal file
|
@ -0,0 +1,79 @@
|
|||
<picture>
|
||||
<source srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg" media="(prefers-color-scheme: dark)">
|
||||
<img src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg" alt="Leptos Logo">
|
||||
</picture>
|
||||
|
||||
# Leptos Client-Side Rendered (CSR) App Starter Template
|
||||
|
||||
This is a template for use with the [Leptos][Leptos] web framework using the [Trunk][Trunk] tool to compile and serve your app in development.
|
||||
|
||||
## Creating your repo from the template
|
||||
|
||||
This template requires you to have `cargo-generate` and `trunk` installed. [`leptosfmt`](https://github.com/bram209/leptosfmt) is optional but highly recommended. You can install them with
|
||||
|
||||
```sh
|
||||
cargo install cargo-generate trunk leptosfmt
|
||||
```
|
||||
|
||||
|
||||
To set up your project with this template, run
|
||||
|
||||
```sh
|
||||
cargo generate --git https://github.com/leptos-community/start-csr
|
||||
```
|
||||
|
||||
to generate your new project, then
|
||||
|
||||
```sh
|
||||
cd homepage
|
||||
```
|
||||
|
||||
to go to your newly created project.
|
||||
|
||||
By default, this template uses Rust `nightly` and requires that you've installed the `wasm` compilation target for your toolchain.
|
||||
|
||||
|
||||
Sass and Tailwind are also supported by the Trunk build tool, but are optional additions: [see here for more info on how to set those up with Trunk][Trunk-instructions].
|
||||
|
||||
|
||||
If you don't have Rust nightly, you can install it with
|
||||
```sh
|
||||
rustup toolchain install nightly --allow-downgrade
|
||||
```
|
||||
|
||||
You can add the `wasm` compilation target to rust using
|
||||
```sh
|
||||
rustup target add wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
|
||||
## Developing your Leptos CSR project
|
||||
|
||||
To develop your Leptos CSR project, running
|
||||
|
||||
```sh
|
||||
trunk serve --port 3000 --open
|
||||
```
|
||||
|
||||
will open your app in your default browser at `http://localhost:3000`.
|
||||
|
||||
|
||||
## Deploying your Leptos CSR project
|
||||
|
||||
To build a Leptos CSR app for release, use the command
|
||||
|
||||
```sh
|
||||
trunk build --release
|
||||
```
|
||||
|
||||
This will output the files necessary to run your app into the `dist` folder; you can then use any static site host to serve these files.
|
||||
|
||||
For further information about hosting Leptos CSR apps, please refer to [the Leptos Book chapter on deployment available here][deploy-csr].
|
||||
|
||||
|
||||
[Leptos]: https://github.com/leptos-rs/leptos
|
||||
|
||||
[Trunk]: https://github.com/trunk-rs/trunk
|
||||
[Trunk-instructions]: https://trunkrs.dev/assets/
|
||||
|
||||
[deploy-csr]: https://book.leptos.dev/deployment/csr.html
|
60
Trunk.toml
Normal file
60
Trunk.toml
Normal file
|
@ -0,0 +1,60 @@
|
|||
[build]
|
||||
# The index HTML file to drive the bundling process.
|
||||
target = "index.html"
|
||||
# Build in release mode.
|
||||
release = true
|
||||
# Use a custom cargo profile. Overrides the default chosen by cargo. Ignored if the 'index.html' has one configured.
|
||||
# cargo_profile = ""
|
||||
# The output dir for all final assets.
|
||||
dist = "dist"
|
||||
# The public URL from which assets are to be served.
|
||||
public_url = "/"
|
||||
# Whether to include hash values in the output file names.
|
||||
filehash = true
|
||||
# Whether to inject scripts (and module preloads) into the finalized output.
|
||||
inject_scripts = true
|
||||
# Run without network access
|
||||
# offline = false
|
||||
# Require Cargo.lock and cache are up to date
|
||||
# frozen = false
|
||||
# Require Cargo.lock is up to date
|
||||
# locked = false
|
||||
# Control minification
|
||||
# minify = "never" # can be one of: never, on_release, always
|
||||
# Allow disabling sub-resource integrity (SRI)
|
||||
# no_sri = false
|
||||
# An optional cargo profile to use
|
||||
# cargo_profile = "release-trunk"
|
||||
|
||||
[watch]
|
||||
# Paths to watch. The `build.target`'s parent folder is watched by default.
|
||||
watch = []
|
||||
# Paths to ignore.
|
||||
ignore = []
|
||||
|
||||
[serve]
|
||||
# The address to serve on.
|
||||
addresses = ["127.0.0.1"]
|
||||
# The port to serve on.
|
||||
port = 3000
|
||||
# Aliases to serve, typically found in an /etc/hosts file.
|
||||
# aliases = ["http://localhost.mywebsite.com"]
|
||||
# Disable the reverse DNS lookup during startup
|
||||
# disable_address_lookup = false
|
||||
# Open a browser tab once the initial build is complete.
|
||||
open = false
|
||||
# Whether to disable fallback to index.html for missing files.
|
||||
# no_spa = false
|
||||
# Disable auto-reload of the web app.
|
||||
# no_autoreload = false
|
||||
# Disable error reporting
|
||||
# no_error_reporting = false
|
||||
# Additional headers set for responses.
|
||||
# headers = { "test-header" = "header value", "test-header2" = "header value 2" }
|
||||
# Protocol used for autoreload WebSockets connection.
|
||||
# ws_protocol = "ws"
|
||||
# The certificate/private key pair to use for TLS, which is enabled if both are set.
|
||||
# tls_key_path = "self_signed_certs/key.pem"
|
||||
# tls_cert_path = "self_signed_certs/cert.pem"
|
||||
# Additional headers to send. NOTE: header names must be valid HTTP headers.
|
||||
# headers = { "X-Foo" = "bar" }
|
22
index.html
Normal file
22
index.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<!-- Add a plain CSS file: see https://trunkrs.dev/assets/#css -->
|
||||
<!-- If using Tailwind with Leptos CSR, see https://trunkrs.dev/assets/#tailwind instead-->
|
||||
<link data-trunk rel="scss" href="public/styles.scss" />
|
||||
|
||||
<!-- Include favicon in dist output: see https://trunkrs.dev/assets/#icon -->
|
||||
<link data-trunk rel="icon" href="public/favicon.ico" />
|
||||
|
||||
<!-- include support for `wasm-bindgen --weak-refs` - see: https://rustwasm.github.io/docs/wasm-bindgen/reference/weak-references.html -->
|
||||
<link data-trunk rel="rust" data-wasm-opt="z" data-weak-refs />
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com"/>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100..900&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"/>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
|
||||
</html>
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
130
public/styles.scss
Normal file
130
public/styles.scss
Normal file
|
@ -0,0 +1,130 @@
|
|||
$mainGreen: #2b762f;
|
||||
$darkerGreen: darken($mainGreen, 5);
|
||||
$mainGrey: #0F0F0F;
|
||||
|
||||
@mixin top-level-padding {
|
||||
padding: 0 16px;
|
||||
@media all and (max-width: 400px) {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
button {
|
||||
&.link {
|
||||
all: unset;
|
||||
text-decoration: underline;
|
||||
color: $mainGreen!important;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: $mainGreen!important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
text-align: left;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
|
||||
background: white;
|
||||
color: $mainGrey;
|
||||
|
||||
display: flex;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin: 0;
|
||||
|
||||
.main-width {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "Roboto Slab", serif;
|
||||
font-weight: 300;
|
||||
line-height: 1.3;
|
||||
}
|
||||
h1 { font-size: 42px; }
|
||||
h2 { font-size: 32px; }
|
||||
h3 { font-size: 22px; }
|
||||
h4 { font-size: 18px; }
|
||||
|
||||
.main-width {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background: $mainGrey;
|
||||
color: white;
|
||||
|
||||
h1 {
|
||||
margin: 8px 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
@include top-level-padding;
|
||||
margin-bottom: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 32px;
|
||||
|
||||
.datetime {
|
||||
}
|
||||
|
||||
.links {
|
||||
width: fit-content;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
gap: 16px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background: $mainGrey;
|
||||
color: white;
|
||||
|
||||
header {
|
||||
background: $darkerGreen;
|
||||
color: white;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white!important;
|
||||
}
|
||||
}
|
||||
}
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly"
|
15
src/components/counter_btn.rs
Normal file
15
src/components/counter_btn.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use leptos::prelude::*;
|
||||
|
||||
/// A parameterized incrementing button
|
||||
#[component]
|
||||
pub fn Button(#[prop(default = 1)] increment: i32) -> impl IntoView {
|
||||
let (count, set_count) = signal(0);
|
||||
view! {
|
||||
<button on:click=move |_| {
|
||||
set_count(count() + increment)
|
||||
}>
|
||||
|
||||
"Click me: " {count}
|
||||
</button>
|
||||
}
|
||||
}
|
1
src/components/mod.rs
Normal file
1
src/components/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod counter_btn;
|
74
src/lib.rs
Normal file
74
src/lib.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use leptos::prelude::*;
|
||||
use leptos_meta::*;
|
||||
use leptos_use::{use_timestamp};
|
||||
use chrono::prelude::{DateTime, Local, Timelike};
|
||||
use calendrier::{DateTime as FRDateTime, Timestamp as FRTimestamp};
|
||||
|
||||
#[component]
|
||||
pub fn Times() -> impl IntoView {
|
||||
let timestamp = use_timestamp();
|
||||
let timezone = Local::now().timezone();
|
||||
let seconds_since_epoch = Memo::new(move |_| (timestamp.get() / 1000.0) as i64);
|
||||
let local_now = Memo::new(move |_| DateTime::from_timestamp(seconds_since_epoch.get(), 0).unwrap().with_timezone(&timezone));
|
||||
let local_now_string = move || local_now.get().to_string();
|
||||
|
||||
let fr_date = Memo::new(move |_| FRDateTime::from_timestamp(FRTimestamp::from_unix(local_now.get().timestamp())));
|
||||
let fr_time = Memo::new(move |_| {
|
||||
let fr_seconds_from_midnight = ((local_now.get().time().num_seconds_from_midnight() as f64) * (1000.0 / 864.0)).floor() as usize;
|
||||
let fr_hours = fr_seconds_from_midnight / (100 * 100);
|
||||
let fr_seconds_from_hour = fr_seconds_from_midnight - (100 * 100 * fr_hours);
|
||||
let fr_minutes = fr_seconds_from_hour / 100;
|
||||
let fr_seconds = fr_seconds_from_hour - (100 * fr_minutes);
|
||||
let fr_time = format!("{}:{}:{}", fr_hours, fr_minutes, fr_seconds);
|
||||
fr_time
|
||||
});
|
||||
let fr_date_time = move || format!("{}, {}", fr_date.get().to_string_default(), fr_time.get());
|
||||
|
||||
let fi_date_time = move || local_now.get().format_localized("%A %e %B %Y, %T", chrono::Locale::fi_FI).to_string();
|
||||
|
||||
view! {
|
||||
<div class="datetime">
|
||||
<p class="unix">{seconds_since_epoch}</p>
|
||||
<p class="iso">{local_now_string}</p>
|
||||
<p class="fr">{fr_date_time}</p>
|
||||
<p class="fi">{fi_date_time}</p>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
// Provides context that manages stylesheets, titles, meta tags, etc.
|
||||
provide_meta_context();
|
||||
|
||||
view! {
|
||||
// <Html attr:lang="en" attr:dir="ltr" attr:data-theme="light" />
|
||||
<Html attr:lang="en" attr:dir="ltr" />
|
||||
|
||||
// sets the document title
|
||||
<Title text="homepage.juustodiilerit.fi" />
|
||||
|
||||
// injects metadata in the <head> of the page
|
||||
<Meta charset="UTF-8" />
|
||||
<Meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<header>
|
||||
<h1><span>homepage</span><span>.juustodiilerit</span><span>.fi</span></h1>
|
||||
</header>
|
||||
<main class="main-width">
|
||||
<Times/>
|
||||
<ul class="links">
|
||||
<li>
|
||||
<a href="https://forgejo.juustodiilerit.fi">git (forgejo)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://mail.juustodiilerit.fi">mail</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://passbolt.juustodiilerit.fi">passbolt</a>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
}
|
||||
}
|
14
src/main.rs
Normal file
14
src/main.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
use leptos::prelude::*;
|
||||
use homepage::App;
|
||||
|
||||
fn main() {
|
||||
// set up logging
|
||||
_ = console_log::init_with_level(log::Level::Debug);
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
mount_to_body(|| {
|
||||
view! {
|
||||
<App />
|
||||
}
|
||||
})
|
||||
}
|
52
src/pages/home.rs
Normal file
52
src/pages/home.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use crate::components::counter_btn::Button;
|
||||
use leptos::prelude::*;
|
||||
|
||||
/// Default Home Page
|
||||
#[component]
|
||||
pub fn Home() -> impl IntoView {
|
||||
view! {
|
||||
<ErrorBoundary fallback=|errors| {
|
||||
view! {
|
||||
<h1>"Uh oh! Something went wrong!"</h1>
|
||||
|
||||
<p>"Errors: "</p>
|
||||
// Render a list of errors as strings - good for development purposes
|
||||
<ul>
|
||||
{move || {
|
||||
errors
|
||||
.get()
|
||||
.into_iter()
|
||||
.map(|(_, e)| view! { <li>{e.to_string()}</li> })
|
||||
.collect_view()
|
||||
}}
|
||||
|
||||
</ul>
|
||||
}
|
||||
}>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<picture>
|
||||
<source
|
||||
srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_pref_dark_RGB.svg"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
<img
|
||||
src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg"
|
||||
alt="Leptos Logo"
|
||||
height="200"
|
||||
width="400"
|
||||
/>
|
||||
</picture>
|
||||
|
||||
<h1>"Welcome to Leptos"</h1>
|
||||
|
||||
<div class="buttons">
|
||||
<Button />
|
||||
<Button increment=5 />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
}
|
||||
}
|
2
src/pages/mod.rs
Normal file
2
src/pages/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod home;
|
||||
pub mod not_found;
|
7
src/pages/not_found.rs
Normal file
7
src/pages/not_found.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use leptos::prelude::*;
|
||||
|
||||
/// 404 Not Found Page
|
||||
#[component]
|
||||
pub fn NotFound() -> impl IntoView {
|
||||
view! { <h1>"Uh oh!" <br /> "We couldn't find that page!"</h1> }
|
||||
}
|
Loading…
Add table
Reference in a new issue