Skip to content

Commit

Permalink
feat: rexistro correo
Browse files Browse the repository at this point in the history
  • Loading branch information
eerii committed Mar 22, 2024
1 parent 9edc6dc commit 042b88a
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 20 deletions.
8 changes: 6 additions & 2 deletions assets/style/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ Tipografias

font-family: var(--font-text);

color: var(--fg);
accent-color: var(--accent);
scroll-behavior: smooth;
}
Expand All @@ -76,6 +75,7 @@ body {
margin-top: var(--nav-height);
padding: 0 calc(var(--spacing) * 2);

color: var(--fg);
background-color: var(--bg);
}

Expand Down Expand Up @@ -363,14 +363,18 @@ textarea,
select,
button {
background-color: var(--accent);
color: var(--bg);
padding: 0.3rem 1rem;
border: none;
border-radius: var(--radius);
outline: none;
}

button:hover {
button:hover,
input[type="submit"]:hover {
transform: scale(1.05);
background-color: var(--fg);
cursor: pointer;
}

textarea,
Expand Down
22 changes: 21 additions & 1 deletion src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ use std::time::{Duration, SystemTime};

use dotenvy_macro::dotenv;
use serde::{Deserialize, Serialize};
use sqlx::{postgres::PgPoolOptions, query_as, types::time::Date, FromRow, Pool, Postgres};
use sqlx::{
postgres::{PgPoolOptions, PgQueryResult},
query_as,
types::time::Date,
FromRow, Pool, Postgres,
};
use tracing::{debug, warn};

const CACHE_DURATION: Duration = Duration::from_secs(6 * 60 * 60);
Expand All @@ -26,6 +31,11 @@ pub struct Pelicula {
pub presentado_por: Option<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize, Clone, FromRow)]
pub struct Email {
pub email: String,
}

// Caché de datos

#[derive(Debug, Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -114,6 +124,8 @@ pub trait RepoPeliculas {
async fn clear_cache(&mut self);

async fn list(&mut self) -> Vec<Pelicula>;

async fn insert_email(&mut self, email: String) -> Result<PgQueryResult, sqlx::Error>;
}

impl RepoPeliculas for Conexion {
Expand Down Expand Up @@ -149,4 +161,12 @@ impl RepoPeliculas for Conexion {

self.cache.peliculas.get().cloned().unwrap()
}

async fn insert_email(&mut self, email: String) -> Result<PgQueryResult, sqlx::Error> {
let pool = self.get().await;
sqlx::query("INSERT INTO emails (email) VALUES ($1)")
.bind(email)
.execute(pool)
.await
}
}
51 changes: 46 additions & 5 deletions src/routes.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::time::Duration;

use axum::{
extract::{MatchedPath, Request, State},
routing::get,
extract::{Form, MatchedPath, Request, State},
response::Html,
routing::{get, post},
Router,
};
use dotenvy_macro::dotenv;
use serde::Deserialize;
use tower_http::{timeout::TimeoutLayer, trace::TraceLayer};
use tracing::error;

use self::analytics::Analytics;
use crate::{db::RepoPeliculas, SharedState};
Expand Down Expand Up @@ -37,6 +40,10 @@ pub fn router() -> Router {
let api = Router::new()
.route("/ping", get(noop))
.route("/clear/cache", get(clear_cache))
.route(
"/subscribe/email",
post(registrar_correo),
)
.route(
"/peliculas/carrousel",
get(peliculas::carrousel),
Expand Down Expand Up @@ -90,12 +97,46 @@ pub fn router() -> Router {
// ···············

// Non fai nada
pub async fn noop() {}
async fn noop() {}

// Limpa o caché da base de datos
pub async fn clear_cache(State(state): State<SharedState>) {
async fn clear_cache(State(state): State<SharedState>) {
let mut state = state.write().await;
state.db.clear_cache().await;
}

// TODO: Suscribirse por correo (usar debouncer para non sobrecargar bd)
// Rexistrar o correo electrónico
#[derive(Deserialize, Debug)]
struct InputCorreo {
email: String,
}

async fn registrar_correo(
State(state): State<SharedState>,
Form(input): Form<InputCorreo>,
) -> Html<String> {
let email = input.email;

// TODO: Mejor verificación
if email.is_empty() {
return Html("O correo está vacío".into());
}

if !email.contains('@') {
return Html("O correo debe conter un '@'".into());
}

let mut state = state.write().await;
match state.db.insert_email(email).await {
Ok(_) => Html("Correo rexistrado".into()),
Err(e) => match e {
sqlx::Error::Database(e) if e.is_unique_violation() => {
Html("O correo xa está rexistrado".into())
},
_ => Html(format!(
"Error desconocido ó rexistrar o correo: {}",
e
)),
},
}
}
6 changes: 6 additions & 0 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ <h1>Nada que ver aquí 🤫</h1>
flex-grow: 1;
color: var(--accent);
}

@media md- {
body {
padding: 0 calc(var(--spacing) * 0.5);
}
}
</style>
<p>Creado con amor polo equipo CineMazarelos da facultade de Filosofía USC</p>
<script type="text/javascript">
Expand Down
16 changes: 4 additions & 12 deletions templates/paxinas/inicio.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@
flex: 50%;
}

this #enviar {
padding: 0.3rem 1rem;
}

this #enviar:hover {
cursor: pointer;
background-color: var(--fg);
transform: scale(1.05);
}

@media md- {
this { flex-direction: column; }
}
Expand All @@ -57,9 +47,11 @@
<div>
<h3>Recibe as nosas novas no teu correo</h3>
<div class="tarxeta">
<input type="email" name="email" placeholder="Email">
<input type="submit" value="Suscribirme" id="enviar">
<input type="email" name="email" placeholder="Email" required>
<input type="submit" value="Suscribirme" id="enviar"
hx-post="/api/subscribe/email" hx-target="#aviso" hx-include="[name='email']" hx-swap="innerHTML" />
</div>
<span id="aviso"></span>
</div>

<div hx-get="/api/peliculas/calendario" hx-trigger="load"></div>
Expand Down

0 comments on commit 042b88a

Please sign in to comment.