Skip to content

Commit

Permalink
UI/register (#34)
Browse files Browse the repository at this point in the history
* TOS, Privacy, Register, TODO: contact

* Contact ability
  • Loading branch information
andrewwippler authored Mar 29, 2023
1 parent a5242e1 commit 22be3de
Show file tree
Hide file tree
Showing 22 changed files with 719 additions and 28 deletions.
35 changes: 35 additions & 0 deletions api/app/Controllers/Http/ContactsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import Contact from 'App/Models/Contact'
import CreateContactValidator from 'App/Validators/CreateContactValidator'

export default class ContactsController {
// public async index({}: HttpContextContract) {}

// public async create({}: HttpContextContract) {}

public async store({ request, response }: HttpContextContract) {

try {
await request.validate(CreateContactValidator)
} catch (error) {
return response.status(400).send(error.messages)
}
const { email, reason, message } = request.all()

const contact = await Contact.create({
email,
reason,
message
})

return response.send({message: 'Created successfully', id: contact.id})
}

// public async show({}: HttpContextContract) {}

// public async edit({}: HttpContextContract) {}

// public async update({}: HttpContextContract) {}

// public async destroy({}: HttpContextContract) {}
}
22 changes: 22 additions & 0 deletions api/app/Models/Contact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@ioc:Adonis/Lucid/Orm'

export default class Contact extends BaseModel {
@column({ isPrimary: true })
public id: number

@column({ serializeAs: null })
public email: string

@column()
public reason: string

@column()
public message: string

@column.dateTime({ autoCreate: true })
public createdAt: DateTime

@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
7 changes: 6 additions & 1 deletion api/app/Models/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Tag from './Tag'
import Place from './Place'
import { v4 } from 'uuid'


export default class User extends BaseModel {
@column({ isPrimary: true })
public id: number
Expand All @@ -18,6 +17,12 @@ export default class User extends BaseModel {
@column()
public email: string

@column({ serializeAs: null })
public tos: boolean

@column({ serializeAs: null })
public thirteen: boolean

@column({ serializeAs: null })
public password: string

Expand Down
26 changes: 26 additions & 0 deletions api/app/Validators/CreateContactValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { schema, CustomMessages, rules } from '@ioc:Adonis/Core/Validator'
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class CreateContactValidator {
constructor(protected ctx: HttpContextContract) {}

public schema = schema.create({
email: schema.string({ trim: true },[
rules.email(),
rules.required(),
]),
reason: schema.string({ trim: true }, [
rules.required(),
]),
message: schema.string({ trim: true }, [
rules.required(),
]),
})

public messages: CustomMessages = {
'email.required': 'The email field is required',
'email.email': 'Enter a valid email address',
'reason.required': 'The reason field is required',
'message.required': 'The message field is required',
}
}
2 changes: 1 addition & 1 deletion api/app/Validators/CreateUserValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class CreateUserValidator {
password: schema.string({ trim: true }, [
rules.required(),
rules.confirmed(),
rules.regex(/^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}/)
rules.regex(/^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*].{8,}/)
]),
})

Expand Down
2 changes: 1 addition & 1 deletion api/database/factories/UserFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import User from 'App/Models/User'
import Factory from '@ioc:Adonis/Lucid/Factory'

export default Factory.define(User, ({ faker }) => {
const same_password = faker.internet.password()
const same_password = faker.internet.password(32,false,/[a-zA-Z0-9!@#$%^&*]/)
return {
email: faker.internet.email(),
password: same_password,
Expand Down
19 changes: 19 additions & 0 deletions api/database/migrations/1679925871360_users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class extends BaseSchema {
protected tableName = 'users'

public async up () {
this.schema.table(this.tableName, (table) => {
table.boolean('thirteen').defaultTo(false)
table.boolean('tos').defaultTo(false)
})
}

public async down () {
this.schema.table(this.tableName, (table) => {
table.dropColumn('thirteen')
table.dropColumn('tos')
})
}
}
24 changes: 24 additions & 0 deletions api/database/migrations/1680097562256_contacts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class extends BaseSchema {
protected tableName = 'contacts'

public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('email')
table.string('reason')
table.text('message')

/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})
}

public async down () {
this.schema.dropTable(this.tableName)
}
}
2 changes: 2 additions & 0 deletions api/start/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Route from '@ioc:Adonis/Core/Route'
import HealthCheck from '@ioc:Adonis/Core/HealthCheck'
// import Upload from 'App/Models/Upload'

Route.post('contact', 'ContactsController.store')

//auth
Route.post('register', 'UsersController.store')
Route.post('login', 'UsersController.login')
Expand Down
29 changes: 29 additions & 0 deletions api/tests/functional/contact.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { test } from '@japa/runner'
import Contact from 'App/Models/Contact'
import Database from '@ioc:Adonis/Lucid/Database'

test.group('Contact', (group) => {
group.each.setup(async () => {
await Database.beginGlobalTransaction()
return () => Database.rollbackGlobalTransaction()
})
// group.setup(async () => {

// })

// group.teardown(async () => {

// })

test('Can submit a contact form request', async ({ client }) => {
const response = await client.post('/contact').json({
email: '[email protected]',
reason: 'general',
message: 'stuff here'
})
response.assertStatus(200)
await Contact.findOrFail(response.body().id)

})

})
2 changes: 1 addition & 1 deletion api/tests/functional/user.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ test.group('Users', (group) => {

const response = await client.post('/register').json(fixedUser)

response.assertStatus(200)
response.assertBodyContains({message: 'Created successfully'})
response.assertBodyContains({uid: response.body().uid})
response.assertStatus(200)

const loggedInUser = await client.post('/login').json({email: user.email, password: user.password})

Expand Down
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"eslint-config-next": "13.2.4",
"iron-session": "^6.3.1",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"next": "13.2.4",
"next-redux-wrapper": "^8.1.0",
"octokit": "^2.0.14",
Expand Down
16 changes: 3 additions & 13 deletions frontend/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,19 @@ export default function Form({
}) {
return (
<>
{/*
This example requires updating your template:
```
<html class="h-full bg-gray-50">
<body class="h-full">
```
*/}
<div className="flex min-h-full items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="w-full max-w-md space-y-8">
<div>

<h2 className="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900">
Sign in to your account
</h2>
{/* <p className="mt-2 text-center text-sm text-gray-600">
<p className="mt-2 text-center text-sm text-gray-600">
Or{' '}
<Link href="/register" className="font-medium text-sky-600 hover:text-sky-500">
register your account
register a new account
</Link>
</p> */}
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={onSubmit}>
<input type="hidden" name="remember" defaultValue="true" />
Expand All @@ -48,7 +40,6 @@ export default function Form({
required
className="relative block w-full rounded-t-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-sky-600 sm:text-sm sm:leading-6"
placeholder="Email address"
defaultValue="[email protected]"
/>
</div>
<div>
Expand All @@ -63,7 +54,6 @@ export default function Form({
required
className="relative block w-full rounded-b-md border-0 py-1.5 text-gray-900 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-sky-600 sm:text-sm sm:leading-6"
placeholder="Password"
defaultValue="Test1234"
/>
</div>
</div>
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Head from 'next/head'
import Header from '@/components/Header'
import Flash from './Flash'
import moment from 'moment'
import { format } from 'date-fns'
import Link from 'next/link'

export default function Layout({ children }: { children: React.ReactNode }) {

Expand All @@ -18,7 +19,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
</main>
<footer className="flex min-h-full items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div className="w-full max-w-screen-lg text-sky-500">
Speaker Windows &copy; Copyright 2017-{moment().year()} Andrew Wippler
Speaker Windows &copy; Copyright 2017-{format(new Date(),'yyyy')} Andrew Wippler | <Link className='underline text-sky-300' href='/tos'>Terms of Service</Link> | <Link className='underline text-sky-300' href='/privacy-policy'>Privacy Policy</Link>
</div>
</footer>
</>
Expand Down
1 change: 0 additions & 1 deletion frontend/src/pages/api/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ async function loginRoute(req: NextApiRequest, res: NextApiResponse) {
await req.session.save()
res.json(user)
} catch (error) {
console.log(error)
res.status(500).json({ message: (error as Error).message })
}
}
Expand Down
Loading

0 comments on commit 22be3de

Please sign in to comment.