Skip to content

Commit

Permalink
feat: add list_users api connection
Browse files Browse the repository at this point in the history
  • Loading branch information
Alvin Januar committed Sep 21, 2024
1 parent 3b1246f commit bf24738
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ resource "aws_lambda_function" "api_server" {
# TF_LOG="trace"
MAIL_BUCKET="${aws_s3_bucket.mail-bucket.bucket}"
MAIL_DB="${aws_dynamodb_table.example.name}"
USER_DB="${aws_dynamodb_table.user.name}"
}
}

Expand Down
30 changes: 29 additions & 1 deletion src/api.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::api_types::{ListEmailsResponse, Mail};
use crate::api_types::{ListEmailsResponse, ListUsersResponse, Mail, User};
use crate::state::AppState;
use aws_sdk_dynamodb as dynamodb;
use aws_sdk_s3 as s3;
Expand Down Expand Up @@ -112,4 +112,32 @@ pub async fn list_emails(state: AppState) -> ListEmailsResponse {
.collect();
ListEmailsResponse { data: mails }
}

pub async fn list_users(state: AppState) -> ListUsersResponse {
let _client = dynamodb::Client::new(&state.aws_config);
let call = _client
.query()
.table_name(&state.mail_config.user_db)
.key_condition_expression("pk = :pk")
.projection_expression("pk, sk, message_count")
.expression_attribute_values(":pk", AttributeValue::S("USER".to_string()))
.limit(20);

let resp = call.send().await.unwrap();
let users: Vec<User> = resp
.items()
.iter()
.map(|x| User {
pk: x.get("pk").unwrap().as_s().unwrap().to_string(),
sk: x.get("sk").unwrap().as_s().unwrap().to_string(),
message_count: x
.get("message_count")
.unwrap()
.as_n()
.unwrap()
.parse::<i64>()
.unwrap(),
})
.collect();
ListUsersResponse { data: users }
}
12 changes: 12 additions & 0 deletions src/api_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,15 @@ pub struct Mail {
pub struct ListEmailsResponse {
pub data: Vec<Mail>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct User {
pub pk: String,
pub sk: String,
pub message_count: i64,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ListUsersResponse {
pub data: Vec<User>,
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ cfg_if! {
}
let mail_bucket = env::var("MAIL_BUCKET").expect("MAIL_BUCKET not set");
let mail_db = env::var("MAIL_DB").expect("MAIL_DB not set");
let user_db = env::var("USER_DB").expect("USER_DB not set");
// let aws_profile_name = env::var("AWS_PROFILE").expect("AWS_PROFILE not set");

let aws_config = aws_config::defaults(BehaviorVersion::v2024_03_28())
Expand All @@ -85,6 +86,7 @@ cfg_if! {
let mail_config = MailConfig {
mail_bucket,
mail_db,
user_db
};

let state = AppState {
Expand Down
1 change: 1 addition & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ pub struct AppState {
pub struct MailConfig {
pub mail_bucket: String,
pub mail_db: String,
pub user_db: String,
}
43 changes: 42 additions & 1 deletion src/ui/mail.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use leptos::*;

use crate::api_types::{ListEmailsResponse, Mail};
use crate::api_types::{ListEmailsResponse, ListUsersResponse, Mail};
use crate::ui::components::badge::Badge;
use crate::ui::components::input::Input;
use crate::ui::components::switch::Switch;
Expand All @@ -17,11 +17,30 @@ pub async fn list_emails_fn(email: String) -> Result<ListEmailsResponse, ServerF
}
}

#[server(ListUsers, "/api_fn")]
pub async fn list_users_fn() -> Result<ListUsersResponse, ServerFnError> {
use crate::api::list_users;
use crate::state::AppState;
let state = use_context::<AppState>();

match state {
Some(state) => Ok(list_users(state).await),
None => Err(ServerFnError::ServerError("error_state".to_string())),
}
}

/// Renders the home page of your application.
#[component]
pub fn MailPage() -> impl IntoView {
// Creates a reactive value to update the button
let (count, set_count) = create_signal(50.00);

let users = create_local_resource(
count,
// every time `count` changes, this will run
move |value| async move { list_users_fn().await },
);

let mails = create_local_resource(
count,
// every time `count` changes, this will run
Expand All @@ -38,6 +57,14 @@ pub fn MailPage() -> impl IntoView {
<div class="flex flex-col py-3 ml-5 h-screen border-white w-[600px] border-x">
<div class="px-3">
<Input />
<input
type="range"
max="100"
value=count
on:change=move |event| {
set_count(event_target_value(&event).parse::<f64>().unwrap());
}
/>
</div>
<div class="relative my-1">
<div class="absolute left-0 -translate-x-1/2">
Expand All @@ -49,6 +76,20 @@ pub fn MailPage() -> impl IntoView {
<hr class="mt-2.5 w-full border-zinc-800 box-border" />
</div>
<div class="flex overflow-y-auto flex-col gap-y-3 px-3 pt-3 w-full">
{move || match users.get() {
None => view! { <p>"Loading..."</p> }.into_view(),
Some(data) => {
match data {
Ok(api) => {
api.data
.into_iter()
.map(|user| { view! { <div>{user.sk}</div> }.into_view() })
.collect()
}
Err(e) => view! { <p>{e.to_string()}</p> }.into_view(),
}
}
}}
{move || match mails.get() {
None => view! { <p>"Loading..."</p> }.into_view(),
Some(data) => {
Expand Down

0 comments on commit bf24738

Please sign in to comment.