diff --git a/app/[slug]/page.tsx b/app/[slug]/page.tsx index 34e8adf..00bd750 100644 --- a/app/[slug]/page.tsx +++ b/app/[slug]/page.tsx @@ -1,11 +1,8 @@ /* Copyright (C) 2024 Manuel Bustillo*/ 'use client'; -import Link from 'next/link'; -import styles from '@/app/ui/home.module.css'; import LoginForm from '@/app/ui/components/login-form'; - - +import RegistrationForm from '@/app/ui/components/registration-form'; export default async function Page({ params }: { params: Promise<{ slug: string }> }) { @@ -14,17 +11,15 @@ export default async function Page({ params }: { params: Promise<{ slug: string - Already have an account? Sign in - Don't have an account? Register now! + - ); } diff --git a/app/api/authentication.tsx b/app/api/authentication.tsx index 6b57d06..a7648f6 100644 --- a/app/api/authentication.tsx +++ b/app/api/authentication.tsx @@ -1,10 +1,9 @@ /* Copyright (C) 2024 Manuel Bustillo*/ import { getCsrfToken, getSlug } from '@/app/lib/utils'; -import { User } from '@/app/lib/definitions'; +import { Captcha, User } from '@/app/lib/definitions'; export function login({ email, password, onLogin }: { email: string, password: string, onLogin: (user: User) => void }) { - console.log(email, password); return fetch(`/api/${getSlug()}/users/sign_in`, { method: 'POST', body: JSON.stringify({ user: { email, password } }), @@ -34,3 +33,28 @@ export function logout({ onLogout }: { onLogout: () => void }) { }).then(onLogout) .catch((error) => console.error(error)); } + +export function register({slug, email, password, passwordConfirmation, captcha, onRegister}: { + slug: string, + email: string, + password: string, + passwordConfirmation: string, + captcha: Captcha, + onRegister: () => void +}){ + fetch(`/api/${slug}/users`, { + method: 'POST', + body: JSON.stringify( + { + user: { email, password, password_confirmation: passwordConfirmation }, + captcha: { id: captcha.id, answer: captcha.answer } + } + ), + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': getCsrfToken(), + } + }).then(onRegister) + .catch((error) => console.error(error)); +} diff --git a/app/api/captcha.tsx b/app/api/captcha.tsx new file mode 100644 index 0000000..07074c7 --- /dev/null +++ b/app/api/captcha.tsx @@ -0,0 +1,17 @@ +import { data } from "autoprefixer"; +import { getCsrfToken } from "../lib/utils"; + +export function getCaptchaChallenge({onRetrieve}: {onRetrieve: (id: string, url: string) => void}){ + return fetch('/api/captcha', { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'X-CSRF-TOKEN': getCsrfToken(), + } + }) + .then((response) => response.json()) + .then((data: any) => { + onRetrieve(data.id, data.media_url) + }) + .catch((error) => console.error(error)); +} \ No newline at end of file diff --git a/app/lib/definitions.ts b/app/lib/definitions.ts index 45b5536..8e161e4 100644 --- a/app/lib/definitions.ts +++ b/app/lib/definitions.ts @@ -64,4 +64,9 @@ export type guestsTable = { export type User = { id: string; email: string; +} + +export type Captcha = { + id: string; + answer: string; } \ No newline at end of file diff --git a/app/ui/components/registration-form.tsx b/app/ui/components/registration-form.tsx new file mode 100644 index 0000000..2c2d304 --- /dev/null +++ b/app/ui/components/registration-form.tsx @@ -0,0 +1,81 @@ +/* Copyright (C) 2024 Manuel Bustillo*/ + +'use client'; + +import { FloatLabel } from 'primereact/floatlabel'; +import { InputText } from 'primereact/inputtext'; +import { useState, useEffect } from 'react'; +import { classNames } from './button'; +import { getSlug } from '@/app/lib/utils'; +import { register } from '@/app/api/authentication'; +import { getCaptchaChallenge } from '@/app/api/captcha'; + +export default function RegistrationForm() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [passwordConfirmation, setPasswordConfirmation] = useState(""); + const [slug, setSlug] = useState(getSlug()); + + const [captchaId, setCaptchaId] = useState(""); + const [captchaUrl, setCaptchaUrl] = useState(""); + const [captchaAnswer, setCaptchaAnswer] = useState(""); + + const refreshCaptcha = () => { + getCaptchaChallenge({ + onRetrieve: (id, url) => { + console.log(id, url); + setCaptchaId(id); + setCaptchaUrl(url); + } + }); + } + + useEffect(refreshCaptcha, []) + + return ( + + + setEmail(e.target.value)} /> + Email + + + setPassword(e.target.value)} /> + Password + + + setPasswordConfirmation(e.target.value)} /> + Confirm Password + + + setSlug(e.target.value)} /> + Slug + + + + setCaptchaAnswer(e.target.value)} /> + Captcha + + + + register( + { + slug: slug, + email: email, + password: password, + passwordConfirmation: passwordConfirmation, + captcha: { + id: captchaId, + answer: captchaAnswer + }, + onRegister: () => { console.log("registered") } + } + )} + > + Register + + + ); +} \ No newline at end of file