Skip to content

Commit

Permalink
Merge pull request #13 from rust-dd/feat/references
Browse files Browse the repository at this point in the history
feat: add references ui
  • Loading branch information
dancixx authored Dec 21, 2024
2 parents 3b4e5b2 + ab1b9c0 commit c21ba65
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 83 deletions.
14 changes: 14 additions & 0 deletions schemas/reference.surql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
DEFINE TABLE OVERWRITE reference SCHEMAFULL
PERMISSIONS
FOR select FULL
FOR create, update, delete NONE;

DEFINE FIELD OVERWRITE title ON reference TYPE string;
DEFINE FIELD OVERWRITE description ON reference TYPE string;
DEFINE FIELD OVERWRITE url ON reference TYPE string;
DEFINE FIELD OVERWRITE tags ON reference TYPE array<string>;
DEFINE FIELD OVERWRITE tech_stack ON reference TYPE array<string>;
DEFINE FIELD OVERWRITE teck_stack_percentage ON reference TYPE array<int>;
DEFINE FIELD OVERWRITE is_published ON reference TYPE bool DEFAULT false;
DEFINE FIELD OVERWRITE created_at ON post TYPE datetime DEFAULT time::now();
DEFINE FIELD OVERWRITE updated_at ON post TYPE datetime VALUE time::now();
4 changes: 2 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use leptos_router::{

pub fn shell(options: LeptosOptions) -> impl IntoView {
view! {
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
Expand Down Expand Up @@ -102,7 +102,7 @@ pub fn App() -> impl IntoView {
view! { <error_template::Component outside_errors /> }.into_view()
}>
<Route path=StaticSegment("") view=home::Component ssr=SsrMode::InOrder />
// <Route path=StaticSegment("references") view=references::Component />
<Route path=StaticSegment("references") view=references::Component />
<Route path=StaticSegment("hireus") view=hireus::Component />
<Route
path=(StaticSegment("post"), ParamSegment("slug"))
Expand Down
12 changes: 6 additions & 6 deletions src/components/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ pub fn Component() -> impl IntoView {
>
blog
</a>
// <a
// href="/references"
// class="text-lg font-bold transition-all duration-500 sm:text-3xl hover:text-[#ffef5c]"
// >
// references
// </a>
<a
href="/references"
class="text-lg font-bold transition-all duration-500 sm:text-3xl hover:text-[#ffef5c]"
>
references
</a>
<a
href="/hireus"
class="text-lg font-bold transition-all duration-500 sm:text-3xl hover:text-[#ffef5c]"
Expand Down
72 changes: 71 additions & 1 deletion src/pages/references.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,76 @@
use crate::ssr::api::select_references;
use leptos::prelude::*;

#[component]
pub fn Component() -> impl IntoView {
view! { Comming soon... }
let references =
Resource::new_blocking(|| (), move |_| async move { select_references().await });

view! {
<div class="container py-12 px-4 mx-auto">
<section class="mx-auto mb-16 max-w-4xl text-center">
<h1 class="mb-8 text-5xl font-bold md:text-7xl text-[#ffef5c]">
Our Project References
</h1>
<p class="mb-8 text-lg text-gray-300 md:text-xl">
Explore our portfolio of successful projects. We specialize in building high-performance,
reliable systems that make a real impact.
</p>
</section>
<section id="projects" class="mx-auto max-w-5xl">
<div class="grid gap-8">
<Suspense fallback=|| ()>
<For
each=move || references.get().and_then(Result::ok).unwrap_or_default()
key=|r| r.id.id.to_string()
let:reference
>
<div class="relative h-[300px] group">
<div class="absolute inset-0 z-0 rounded-2xl transition-colors duration-500 bg-[#ffef5c]/8 blur-2xl group-hover:bg-[#ffef5c]/10"></div>
<div class="absolute inset-2 z-10 rounded-xl border shadow-lg bg-[#ffef5c]/10 backdrop-blur-xl shadow-[#ffef5c]/5 border-[#ffef5c]/20"></div>
<div class="overflow-hidden absolute inset-2 z-20 rounded-xl border backdrop-blur-2xl bg-white/5 border-white/10">
<div class="absolute inset-0 bg-[linear-gradient(0deg,transparent_24px,rgba(255,255,255,0.03)_25px),linear-gradient(90deg,transparent_24px,rgba(255,255,255,0.03)_25px)] bg-[size:25px_25px]"></div>
</div>
<div class="flex absolute inset-0 z-30 flex-col px-6 pt-6 pb-10">
<h3 class="mb-2 text-xl font-bold text-[#ffef5c]">
{reference.title}
</h3>
<p class="flex-grow mb-4 text-sm text-gray-300">
{reference.description}
</p>
<div class="grid grid-cols-2 gap-4">
<For
each=move || {
reference
.tech_stack
.clone()
.into_iter()
.zip(reference.teck_stack_percentage.clone().into_iter())
.collect::<Vec<_>>()
}
key=|tech| tech.0.to_string()
let:tech
>
<div class="flex justify-between items-center mb-1">
<span class="text-xs font-medium text-[#ffef5c]">
{tech.0.to_string()}
</span>
<span class="text-xs text-gray-400">{tech.1}%</span>
</div>
<div class="overflow-hidden h-1.5 rounded-full bg-black/40 backdrop-blur-sm">
<div
class="h-full bg-gradient-to-r from-[#ffef5c] to-[#ffef5c]"
style=format!("width: {}%", tech.1.min(100))
></div>
</div>
</For>
</div>
</div>
</div>
</For>
</Suspense>
</div>
</section>
</div>
}
}
1 change: 1 addition & 0 deletions src/ssr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod api;
pub mod redirect;
#[cfg(feature = "ssr")]
pub mod server_utils;
pub mod types;

#[cfg(feature = "ssr")]
pub mod app_state {
Expand Down
101 changes: 28 additions & 73 deletions src/ssr/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,8 @@ use std::collections::BTreeMap;

use leptos::prelude::{server, ServerFnError};
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Author {
pub id: Thing,
pub name: String,
pub email: String,
pub bio: Option<String>,
pub linkedin: Option<String>,
pub twitter: Option<String>,
pub github: Option<String>,
}

impl Default for Author {
fn default() -> Self {
Self {
id: Thing::from(("author", "0")),
name: String::new(),
email: String::new(),
bio: None,
linkedin: None,
twitter: None,
github: None,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Post {
pub id: Thing,
pub title: String,
pub summary: String,
pub body: String,
pub tags: Vec<String>,
pub author: Author,
pub read_time: usize,
pub total_views: usize,
pub slug: Option<String>,
pub created_at: String,
pub updated_at: String,
pub is_published: bool,
pub header_image: Option<String>,
}

impl<'a> Default for Post {
fn default() -> Self {
Self {
id: Thing::from(("post", "0")),
title: String::new(),
summary: String::new(),
body: String::new(),
tags: vec![],
author: Author::default(),
read_time: 0,
total_views: 0,
slug: None,
created_at: String::new(),
updated_at: String::new(),
is_published: true,
header_image: None,
}
}
}
use crate::ssr::types::{Post, Reference};

#[server(endpoint = "/posts")]
pub async fn select_posts(
Expand Down Expand Up @@ -191,20 +130,18 @@ pub struct HireUsRequest {

#[server(endpoint = "/hire_us")]
pub async fn hire_us(data: HireUsRequest) -> Result<(), ServerFnError> {
use std::env;
use lettre::{
transport::smtp::authentication::Credentials,
message::header::ContentType, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
message::header::ContentType, transport::smtp::authentication::Credentials,
AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor,
};
use std::env;


let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay(&env::var("SMTP_HOST")?)
?
.credentials(Credentials::new(
env::var("SMTP_USER")?,
env::var("SMTP_PASSWORD")?,
))
.build::<Tokio1Executor>();
let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay(&env::var("SMTP_HOST")?)?
.credentials(Credentials::new(
env::var("SMTP_USER")?,
env::var("SMTP_PASSWORD")?,
))
.build::<Tokio1Executor>();

let email = Message::builder()
.from(data.email.parse()?)
Expand All @@ -225,3 +162,21 @@ pub async fn hire_us(data: HireUsRequest) -> Result<(), ServerFnError> {
}
}
}

#[server(endpoint = "/references")]
pub async fn select_references() -> Result<Vec<Reference>, ServerFnError> {
use crate::ssr::app_state::AppState;
use leptos::prelude::expect_context;

let AppState { db, .. } = expect_context::<AppState>();

let query = "SELECT * from reference WHERE is_published = true ORDER BY created_at DESC;";
let query = db.query(query).await;

if let Err(e) = query {
return Err(ServerFnError::from(e));
}

let references = query?.take::<Vec<Reference>>(0)?;
Ok(references)
}
2 changes: 1 addition & 1 deletion src/ssr/server_utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::api::Post;
use super::types::Post;
use crate::ssr::app_state::AppState;
use axum::extract::State;
use axum::response::Response;
Expand Down
78 changes: 78 additions & 0 deletions src/ssr/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use serde::{Deserialize, Serialize};
use surrealdb::sql::Thing;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Author {
pub id: Thing,
pub name: String,
pub email: String,
pub bio: Option<String>,
pub linkedin: Option<String>,
pub twitter: Option<String>,
pub github: Option<String>,
}

impl Default for Author {
fn default() -> Self {
Self {
id: Thing::from(("author", "0")),
name: String::new(),
email: String::new(),
bio: None,
linkedin: None,
twitter: None,
github: None,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Post {
pub id: Thing,
pub title: String,
pub summary: String,
pub body: String,
pub tags: Vec<String>,
pub author: Author,
pub read_time: usize,
pub total_views: usize,
pub slug: Option<String>,
pub created_at: String,
pub updated_at: String,
pub is_published: bool,
pub header_image: Option<String>,
}

impl Default for Post {
fn default() -> Self {
Self {
id: Thing::from(("post", "0")),
title: String::new(),
summary: String::new(),
body: String::new(),
tags: vec![],
author: Author::default(),
read_time: 0,
total_views: 0,
slug: None,
created_at: String::new(),
updated_at: String::new(),
is_published: true,
header_image: None,
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Reference {
pub id: Thing,
pub title: String,
pub description: String,
pub url: String,
pub tags: Vec<String>,
pub tech_stack: Vec<String>,
pub teck_stack_percentage: Vec<u8>,
pub created_at: String,
pub updated_at: String,
pub is_published: bool,
}

0 comments on commit c21ba65

Please sign in to comment.