feat: initialize thoughts-frontend with Next.js, TypeScript, and ESLint

- Add ESLint configuration for Next.js and TypeScript support.
- Create Next.js configuration file with standalone output option.
- Initialize package.json with scripts for development, build, and linting.
- Set up PostCSS configuration for Tailwind CSS.
- Add SVG assets for UI components.
- Create TypeScript configuration for strict type checking and module resolution.
This commit is contained in:
2025-09-05 17:14:45 +02:00
parent 6bd06ff2c8
commit e5747eaaf3
104 changed files with 7484 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
use axum::{
extract::FromRequest,
response::{IntoResponse, Response},
};
use validator::Validate;
use crate::error::ApiError;
#[derive(FromRequest)]
#[from_request(via(axum::Json), rejection(ApiError))]
pub struct Json<T>(pub T);
impl<T> IntoResponse for Json<T>
where
axum::Json<T>: IntoResponse,
{
fn into_response(self) -> Response {
axum::Json(self.0).into_response()
}
}
impl<T: Validate> Validate for Json<T> {
fn validate(&self) -> Result<(), validator::ValidationErrors> {
self.0.validate()
}
}

View File

@@ -0,0 +1,5 @@
mod json;
mod valid;
pub use json::Json;
pub use valid::Valid;

View File

@@ -0,0 +1,23 @@
use axum::extract::{FromRequest, Request};
use validator::Validate;
use crate::validation::ValidRejection;
#[derive(Debug, Clone, Copy, Default)]
pub struct Valid<T>(pub T);
impl<State, Extractor> FromRequest<State> for Valid<Extractor>
where
State: Send + Sync,
Extractor: Validate + FromRequest<State>,
{
type Rejection = ValidRejection<<Extractor as FromRequest<State>>::Rejection>;
async fn from_request(req: Request, state: &State) -> Result<Self, Self::Rejection> {
let inner = Extractor::from_request(req, state)
.await
.map_err(ValidRejection::Extractor)?;
inner.validate()?;
Ok(Valid(inner))
}
}