feat: add create link form

This commit is contained in:
Sonny
2024-05-09 23:14:42 +02:00
committed by Sonny
parent 2cf8c5ae02
commit 73f8c0c513
16 changed files with 244 additions and 64 deletions

View File

@@ -1,26 +1,26 @@
import PATHS from '#constants/paths';
import Collection from '#models/collection';
import User from '#models/user';
import { collectionValidator } from '#validators/collection';
import type { HttpContext } from '@adonisjs/core/http';
export default class CollectionsController {
async index({ auth, inertia }: HttpContext) {
const collections = await Collection.findManyBy('author_id', auth.user!.id);
// Dashboard
async index({ auth, inertia, response }: HttpContext) {
const collections = await this.getCollectionByAuthorId(auth.user!.id);
if (collections.length === 0) {
return response.redirect('/collections/create');
}
const collectionsWithLinks = await Promise.all(
collections.map(async (collection) => {
await collection.load('links');
return collection;
})
);
return inertia.render('dashboard', { collections: collectionsWithLinks });
return inertia.render('dashboard', { collections });
}
// Create collection form
async showCreatePage({ inertia }: HttpContext) {
return inertia.render('collections/create');
}
// Method called when creating a collection
async store({ request, response, auth }: HttpContext) {
const payload = await request.validateUsing(collectionValidator);
const collection = await Collection.create({
@@ -30,7 +30,17 @@ export default class CollectionsController {
return this.redirectToCollectionId(response, collection.id);
}
private redirectToCollectionId(
async getCollectionById(id: Collection['id']) {
return await Collection.find(id);
}
async getCollectionByAuthorId(authorId: User['id']) {
return await Collection.query()
.where('author_id', authorId)
.preload('links');
}
redirectToCollectionId(
response: HttpContext['response'],
collectionId: Collection['id']
) {

View File

@@ -0,0 +1,32 @@
import CollectionsController from '#controllers/collections_controller';
import Link from '#models/link';
import { linkValidator } from '#validators/link';
import { inject } from '@adonisjs/core';
import type { HttpContext } from '@adonisjs/core/http';
@inject()
export default class LinksController {
constructor(protected collectionsController: CollectionsController) {}
async showCreatePage({ auth, inertia }: HttpContext) {
const collections =
await this.collectionsController.getCollectionByAuthorId(auth.user!.id);
return inertia.render('links/create', { collections });
}
async store({ auth, request, response }: HttpContext) {
const { collectionId, ...payload } =
await request.validateUsing(linkValidator);
await this.collectionsController.getCollectionById(collectionId);
await Link.create({
...payload,
collectionId,
authorId: auth.user?.id!,
});
return this.collectionsController.redirectToCollectionId(
response,
collectionId
);
}
}

View File

@@ -1,8 +1,8 @@
import AppBaseModel from '#models/app_base_model';
import Link from '#models/link';
import User from '#models/user';
import { belongsTo, column, manyToMany } from '@adonisjs/lucid/orm';
import type { BelongsTo, ManyToMany } from '@adonisjs/lucid/types/relations';
import { belongsTo, column, hasMany } from '@adonisjs/lucid/orm';
import type { BelongsTo, HasMany } from '@adonisjs/lucid/types/relations';
import { Visibility } from '../enums/visibility.js';
export default class Collection extends AppBaseModel {
@@ -24,6 +24,6 @@ export default class Collection extends AppBaseModel {
@belongsTo(() => User, { foreignKey: 'authorId' })
declare author: BelongsTo<typeof User>;
@manyToMany(() => Link)
declare links: ManyToMany<typeof Link>;
@hasMany(() => Link)
declare links: HasMany<typeof Link>;
}

11
app/validators/link.ts Normal file
View File

@@ -0,0 +1,11 @@
import vine from '@vinejs/vine';
export const linkValidator = vine.compile(
vine.object({
name: vine.string().trim().minLength(1).maxLength(254),
description: vine.string().trim().maxLength(300).optional(),
url: vine.string().trim(),
favorite: vine.boolean(),
collectionId: vine.string().trim(),
})
);