mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-08 22:53:25 +00:00
refactor: split links controller into multiple controllers
This commit is contained in:
@@ -99,7 +99,7 @@ type FaviconGetHead = {
|
||||
type LinksCreateGetHead = {
|
||||
request: unknown;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['showCreatePage'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['showCreatePage'],
|
||||
false
|
||||
>;
|
||||
};
|
||||
@@ -110,14 +110,14 @@ type LinksPost = {
|
||||
>
|
||||
>;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['store'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['store'],
|
||||
true
|
||||
>;
|
||||
};
|
||||
type LinksEditGetHead = {
|
||||
request: unknown;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['showEditPage'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['showEditPage'],
|
||||
false
|
||||
>;
|
||||
};
|
||||
@@ -128,7 +128,7 @@ type LinksIdPut = {
|
||||
>
|
||||
>;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['update'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['update'],
|
||||
true
|
||||
>;
|
||||
};
|
||||
@@ -139,14 +139,14 @@ type LinksIdFavoritePut = {
|
||||
>
|
||||
>;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['toggleFavorite'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['toggleFavorite'],
|
||||
true
|
||||
>;
|
||||
};
|
||||
type LinksDeleteGetHead = {
|
||||
request: unknown;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['showDeletePage'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['showDeletePage'],
|
||||
false
|
||||
>;
|
||||
};
|
||||
@@ -157,7 +157,7 @@ type LinksIdDelete = {
|
||||
>
|
||||
>;
|
||||
response: MakeTuyauResponse<
|
||||
import('../app/links/controllers/links_controller.ts').default['delete'],
|
||||
import('../app/links/controllers/delete_link_controller.js').default['execute'],
|
||||
true
|
||||
>;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import AuthController from '#auth/controllers/auth_controller';
|
||||
import CollectionsController from '#collections/controllers/show_collections_controller';
|
||||
import LinksController from '#links/controllers/links_controller';
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import LinksController from '#links/controllers/delete_link_controller';
|
||||
import User from '#user/models/user';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
@@ -28,14 +28,14 @@ export default class AdminController {
|
||||
constructor(
|
||||
protected usersController: AuthController,
|
||||
protected linksController: LinksController,
|
||||
protected collectionsController: CollectionsController
|
||||
protected collectionService: CollectionService
|
||||
) {}
|
||||
|
||||
async index({ inertia }: HttpContext) {
|
||||
const users = await this.usersController.getAllUsersWithTotalRelations();
|
||||
const linksCount = await this.linksController.getTotalLinksCount();
|
||||
const collectionsCount =
|
||||
await this.collectionsController.getTotalCollectionsCount();
|
||||
await this.collectionService.getTotalCollectionsCount();
|
||||
|
||||
return inertia.render('admin/dashboard', {
|
||||
users: users.map((user) => new UserWithRelationCountDto(user).toJson()),
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import Collection from '#collections/models/collection';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
import vine from '@vinejs/vine';
|
||||
|
||||
export default class BaseCollectionController {
|
||||
protected collectionIdValidator = vine.compile(
|
||||
vine.object({
|
||||
collectionId: vine.number().positive().optional(),
|
||||
})
|
||||
);
|
||||
|
||||
async validateCollectionId(collectionIdRequired: boolean = true) {
|
||||
const ctx = HttpContext.getOrFail();
|
||||
const { collectionId } = await ctx.request.validateUsing(
|
||||
this.collectionIdValidator
|
||||
);
|
||||
if (!collectionId && collectionIdRequired) {
|
||||
console.log('redirecting to dashboard');
|
||||
ctx.response.redirectToNamedRoute('dashboard');
|
||||
return null;
|
||||
}
|
||||
console.log('collectionId', collectionId);
|
||||
return collectionId;
|
||||
}
|
||||
|
||||
redirectToCollectionId(collectionId: Collection['id']) {
|
||||
const ctx = HttpContext.getOrFail();
|
||||
return ctx.response.redirectToNamedRoute('dashboard', {
|
||||
qs: { collectionId },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
import BaseCollectionController from '#collections/controllers/base_collection_controller';
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { createCollectionValidator } from '#collections/validators/create_collection_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { type HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class CreateCollectionController extends BaseCollectionController {
|
||||
constructor(private collectionService: CollectionService) {
|
||||
super();
|
||||
}
|
||||
export default class CreateCollectionController {
|
||||
constructor(private collectionService: CollectionService) {}
|
||||
|
||||
async render({ inertia }: HttpContext) {
|
||||
const collections = await this.collectionService.getCollectionsByAuthorId();
|
||||
const collections =
|
||||
await this.collectionService.getCollectionsForAuthenticatedUser();
|
||||
return inertia.render('collections/create', {
|
||||
disableHomeLink: collections.length === 0,
|
||||
});
|
||||
@@ -20,6 +18,6 @@ export default class CreateCollectionController extends BaseCollectionController
|
||||
async execute({ request }: HttpContext) {
|
||||
const payload = await request.validateUsing(createCollectionValidator);
|
||||
const collection = await this.collectionService.createCollection(payload);
|
||||
return this.redirectToCollectionId(collection.id);
|
||||
return this.collectionService.redirectToCollectionId(collection.id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import BaseCollectionController from '#collections/controllers/base_collection_controller';
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { deleteCollectionValidator } from '#collections/validators/delete_collection_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class DeleteCollectionController extends BaseCollectionController {
|
||||
constructor(private collectionService: CollectionService) {
|
||||
super();
|
||||
}
|
||||
export default class DeleteCollectionController {
|
||||
constructor(private collectionService: CollectionService) {}
|
||||
|
||||
async render({ inertia }: HttpContext) {
|
||||
const collectionId = await this.validateCollectionId();
|
||||
const collectionId = await this.collectionService.validateCollectionId();
|
||||
if (!collectionId) return;
|
||||
|
||||
const collection =
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import BaseCollectionController from '#collections/controllers/base_collection_controller';
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import type { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class ShowCollectionsController extends BaseCollectionController {
|
||||
constructor(private collectionService: CollectionService) {
|
||||
super();
|
||||
}
|
||||
export default class ShowCollectionsController {
|
||||
constructor(private collectionService: CollectionService) {}
|
||||
|
||||
// Dashboard
|
||||
async render({ inertia, response }: HttpContext) {
|
||||
const activeCollectionId = await this.validateCollectionId(false);
|
||||
const collections = await this.collectionService.getCollectionsByAuthorId();
|
||||
const activeCollectionId =
|
||||
await this.collectionService.validateCollectionId(false);
|
||||
const collections =
|
||||
await this.collectionService.getCollectionsForAuthenticatedUser();
|
||||
if (collections.length === 0) {
|
||||
return response.redirectToNamedRoute('collection.create-form');
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import BaseCollectionController from '#collections/controllers/base_collection_controller';
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { updateCollectionValidator } from '#collections/validators/update_collection_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class UpdateCollectionController extends BaseCollectionController {
|
||||
constructor(private collectionService: CollectionService) {
|
||||
super();
|
||||
}
|
||||
export default class UpdateCollectionController {
|
||||
constructor(private collectionService: CollectionService) {}
|
||||
|
||||
async render({ inertia }: HttpContext) {
|
||||
const collectionId = await this.validateCollectionId();
|
||||
const collectionId = await this.collectionService.validateCollectionId();
|
||||
if (!collectionId) return;
|
||||
|
||||
const collection =
|
||||
@@ -28,6 +25,6 @@ export default class UpdateCollectionController extends BaseCollectionController
|
||||
} = await request.validateUsing(updateCollectionValidator);
|
||||
|
||||
await this.collectionService.updateCollection(collectionId, payload);
|
||||
return this.redirectToCollectionId(collectionId);
|
||||
return this.collectionService.redirectToCollectionId(collectionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Visibility } from '#collections/enums/visibility';
|
||||
import Collection from '#collections/models/collection';
|
||||
import { collectionIdValidator } from '#collections/validators/collection_id_validator';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
import db from '@adonisjs/lucid/services/db';
|
||||
|
||||
@@ -20,7 +21,7 @@ export class CollectionService {
|
||||
.firstOrFail();
|
||||
}
|
||||
|
||||
async getCollectionsByAuthorId() {
|
||||
async getCollectionsForAuthenticatedUser() {
|
||||
const context = this.getAuthContext();
|
||||
return await Collection.query()
|
||||
.where('author_id', context.auth.user!.id)
|
||||
@@ -67,4 +68,28 @@ export class CollectionService {
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
async validateCollectionId(collectionIdRequired: boolean = true) {
|
||||
const ctx = HttpContext.getOrFail();
|
||||
const { collectionId } = await ctx.request.validateUsing(
|
||||
collectionIdValidator
|
||||
);
|
||||
if (!collectionId && collectionIdRequired) {
|
||||
this.redirectToDashboard();
|
||||
return null;
|
||||
}
|
||||
return collectionId;
|
||||
}
|
||||
|
||||
redirectToCollectionId(collectionId: Collection['id']) {
|
||||
const ctx = HttpContext.getOrFail();
|
||||
return ctx.response.redirectToNamedRoute('dashboard', {
|
||||
qs: { collectionId },
|
||||
});
|
||||
}
|
||||
|
||||
redirectToDashboard() {
|
||||
const ctx = HttpContext.getOrFail();
|
||||
return ctx.response.redirectToNamedRoute('dashboard');
|
||||
}
|
||||
}
|
||||
|
||||
7
app/collections/validators/collection_id_validator.ts
Normal file
7
app/collections/validators/collection_id_validator.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import vine from '@vinejs/vine';
|
||||
|
||||
export const collectionIdValidator = vine.compile(
|
||||
vine.object({
|
||||
collectionId: vine.number().positive().optional(),
|
||||
})
|
||||
);
|
||||
30
app/links/controllers/create_link_controller.ts
Normal file
30
app/links/controllers/create_link_controller.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { LinkService } from '#links/services/link_service';
|
||||
import { createLinkValidator } from '#links/validators/create_link_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class CreateLinkController {
|
||||
constructor(
|
||||
private linkService: LinkService,
|
||||
private collectionsService: CollectionService
|
||||
) {}
|
||||
|
||||
async render({ inertia }: HttpContext) {
|
||||
const collections =
|
||||
await this.collectionsService.getCollectionsForAuthenticatedUser();
|
||||
return inertia.render('links/create', { collections });
|
||||
}
|
||||
|
||||
async execute({ request }: HttpContext) {
|
||||
const { collectionId, ...payload } =
|
||||
await request.validateUsing(createLinkValidator);
|
||||
|
||||
await this.linkService.createLink({
|
||||
...payload,
|
||||
collectionId,
|
||||
});
|
||||
return this.collectionsService.redirectToCollectionId(collectionId);
|
||||
}
|
||||
}
|
||||
39
app/links/controllers/delete_link_controller.ts
Normal file
39
app/links/controllers/delete_link_controller.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { LinkService } from '#links/services/link_service';
|
||||
import { deleteLinkValidator } from '#links/validators/delete_link_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
import db from '@adonisjs/lucid/services/db';
|
||||
|
||||
@inject()
|
||||
export default class DeleteLinkController {
|
||||
constructor(
|
||||
protected collectionsService: CollectionService,
|
||||
protected linkService: LinkService
|
||||
) {}
|
||||
|
||||
async render({ auth, inertia, request }: HttpContext) {
|
||||
const linkId = request.qs()?.linkId;
|
||||
if (!linkId) {
|
||||
return this.collectionsService.redirectToDashboard();
|
||||
}
|
||||
|
||||
const link = await this.linkService.getLinkById(linkId, auth.user!.id);
|
||||
await link.load('collection');
|
||||
return inertia.render('links/delete', { link });
|
||||
}
|
||||
|
||||
async execute({ request, auth }: HttpContext) {
|
||||
const { params } = await request.validateUsing(deleteLinkValidator);
|
||||
|
||||
const link = await this.linkService.getLinkById(params.id, auth.user!.id);
|
||||
await this.linkService.deleteLink(params.id);
|
||||
|
||||
return this.collectionsService.redirectToCollectionId(link.collectionId);
|
||||
}
|
||||
|
||||
async getTotalLinksCount() {
|
||||
const totalCount = await db.from('links').count('* as total');
|
||||
return Number(totalCount[0].total);
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
import CollectionsController from '#collections/controllers/show_collections_controller';
|
||||
import Link from '#links/models/link';
|
||||
import { createLinkValidator } from '#links/validators/create_link_validator';
|
||||
import { deleteLinkValidator } from '#links/validators/delete_link_validator';
|
||||
import { updateLinkFavoriteStatusValidator } from '#links/validators/update_favorite_link_validator';
|
||||
import { updateLinkValidator } from '#links/validators/update_link_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
import db from '@adonisjs/lucid/services/db';
|
||||
|
||||
@inject()
|
||||
export default class LinksController {
|
||||
constructor(protected collectionsController: CollectionsController) {}
|
||||
|
||||
async showCreatePage({ auth, inertia }: HttpContext) {
|
||||
const collections =
|
||||
await this.collectionsController.getCollectionsByAuthorId(auth.user!.id);
|
||||
return inertia.render('links/create', { collections });
|
||||
}
|
||||
|
||||
async store({ auth, request, response }: HttpContext) {
|
||||
const { collectionId, ...payload } =
|
||||
await request.validateUsing(createLinkValidator);
|
||||
|
||||
await this.collectionsController.getCollectionById(
|
||||
collectionId,
|
||||
auth.user!.id
|
||||
);
|
||||
await Link.create({
|
||||
...payload,
|
||||
collectionId,
|
||||
authorId: auth.user?.id!,
|
||||
});
|
||||
return this.collectionsController.redirectToCollectionId(
|
||||
response,
|
||||
collectionId
|
||||
);
|
||||
}
|
||||
|
||||
async showEditPage({ auth, inertia, request, response }: HttpContext) {
|
||||
const linkId = request.qs()?.linkId;
|
||||
if (!linkId) {
|
||||
return response.redirectToNamedRoute('dashboard');
|
||||
}
|
||||
|
||||
const userId = auth.user!.id;
|
||||
const collections =
|
||||
await this.collectionsController.getCollectionsByAuthorId(userId);
|
||||
const link = await this.getLinkById(linkId, userId);
|
||||
|
||||
return inertia.render('links/edit', { collections, link });
|
||||
}
|
||||
|
||||
async update({ request, auth, response }: HttpContext) {
|
||||
const { params, ...payload } =
|
||||
await request.validateUsing(updateLinkValidator);
|
||||
|
||||
// Throw if invalid link id provided
|
||||
await this.getLinkById(params.id, auth.user!.id);
|
||||
|
||||
await Link.updateOrCreate(
|
||||
{
|
||||
id: params.id,
|
||||
},
|
||||
payload
|
||||
);
|
||||
|
||||
return response.redirectToNamedRoute('dashboard', {
|
||||
qs: { collectionId: payload.collectionId },
|
||||
});
|
||||
}
|
||||
|
||||
async toggleFavorite({ request, auth, response }: HttpContext) {
|
||||
const { params, favorite } = await request.validateUsing(
|
||||
updateLinkFavoriteStatusValidator
|
||||
);
|
||||
|
||||
// Throw if invalid link id provided
|
||||
await this.getLinkById(params.id, auth.user!.id);
|
||||
|
||||
await Link.updateOrCreate(
|
||||
{
|
||||
id: params.id,
|
||||
},
|
||||
{ favorite }
|
||||
);
|
||||
|
||||
return response.json({ status: 'ok' });
|
||||
}
|
||||
|
||||
async showDeletePage({ auth, inertia, request, response }: HttpContext) {
|
||||
const linkId = request.qs()?.linkId;
|
||||
if (!linkId) {
|
||||
return response.redirectToNamedRoute('dashboard');
|
||||
}
|
||||
|
||||
const link = await this.getLinkById(linkId, auth.user!.id);
|
||||
await link.load('collection');
|
||||
return inertia.render('links/delete', { link });
|
||||
}
|
||||
|
||||
async delete({ request, auth, response }: HttpContext) {
|
||||
const { params } = await request.validateUsing(deleteLinkValidator);
|
||||
|
||||
const link = await this.getLinkById(params.id, auth.user!.id);
|
||||
await link.delete();
|
||||
|
||||
return response.redirectToNamedRoute('dashboard', {
|
||||
qs: { collectionId: link.id },
|
||||
});
|
||||
}
|
||||
|
||||
async getTotalLinksCount() {
|
||||
const totalCount = await db.from('links').count('* as total');
|
||||
return Number(totalCount[0].total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get link by id.
|
||||
*
|
||||
* /!\ Only return private link (create by the current user)
|
||||
*/
|
||||
private async getLinkById(id: Link['id'], userId: Link['id']) {
|
||||
return await Link.query()
|
||||
.where('id', id)
|
||||
.andWhere('author_id', userId)
|
||||
.firstOrFail();
|
||||
}
|
||||
}
|
||||
19
app/links/controllers/toggle_favorite_controller.ts
Normal file
19
app/links/controllers/toggle_favorite_controller.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { LinkService } from '#links/services/link_service';
|
||||
import { updateLinkFavoriteStatusValidator } from '#links/validators/update_favorite_link_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class ToggleFavoriteController {
|
||||
constructor(private linkService: LinkService) {}
|
||||
|
||||
async toggleFavorite({ request, response }: HttpContext) {
|
||||
const { params, favorite } = await request.validateUsing(
|
||||
updateLinkFavoriteStatusValidator
|
||||
);
|
||||
|
||||
await this.linkService.updateFavorite(params.id, favorite);
|
||||
|
||||
return response.json({ status: 'ok' });
|
||||
}
|
||||
}
|
||||
34
app/links/controllers/update_link_controller.ts
Normal file
34
app/links/controllers/update_link_controller.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { CollectionService } from '#collections/services/collection_service';
|
||||
import { LinkService } from '#links/services/link_service';
|
||||
import { updateLinkValidator } from '#links/validators/update_link_validator';
|
||||
import { inject } from '@adonisjs/core';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
@inject()
|
||||
export default class UpdateLinkController {
|
||||
constructor(
|
||||
private linkService: LinkService,
|
||||
private collectionsService: CollectionService
|
||||
) {}
|
||||
|
||||
async render({ auth, inertia, request, response }: HttpContext) {
|
||||
const linkId = request.qs()?.linkId;
|
||||
if (!linkId) {
|
||||
return response.redirectToNamedRoute('dashboard');
|
||||
}
|
||||
|
||||
const collections =
|
||||
await this.collectionsService.getCollectionsForAuthenticatedUser();
|
||||
const link = await this.linkService.getLinkById(linkId, auth.user!.id);
|
||||
|
||||
return inertia.render('links/edit', { collections, link });
|
||||
}
|
||||
|
||||
async execute({ request }: HttpContext) {
|
||||
const { params, ...payload } =
|
||||
await request.validateUsing(updateLinkValidator);
|
||||
|
||||
await this.linkService.updateLink(params.id, payload);
|
||||
return this.collectionsService.redirectToCollectionId(payload.collectionId);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
import { middleware } from '#start/kernel';
|
||||
import router from '@adonisjs/core/services/router';
|
||||
const LinksController = () => import('#links/controllers/links_controller');
|
||||
|
||||
const CreateLinkController = () =>
|
||||
import('#links/controllers/create_link_controller');
|
||||
const DeleteLinkController = () =>
|
||||
import('#links/controllers/delete_link_controller');
|
||||
const UpdateLinkController = () =>
|
||||
import('#links/controllers/update_link_controller');
|
||||
const ToggleFavoriteController = () =>
|
||||
import('#links/controllers/toggle_favorite_controller');
|
||||
|
||||
/**
|
||||
* Routes for authenticated users
|
||||
@@ -8,21 +16,21 @@ const LinksController = () => import('#links/controllers/links_controller');
|
||||
router
|
||||
.group(() => {
|
||||
router
|
||||
.get('/create', [LinksController, 'showCreatePage'])
|
||||
.get('/create', [CreateLinkController, 'render'])
|
||||
.as('link.create-form');
|
||||
router.post('/', [LinksController, 'store']).as('link.create');
|
||||
router.post('/', [CreateLinkController, 'execute']).as('link.create');
|
||||
|
||||
router.get('/edit', [LinksController, 'showEditPage']).as('link.edit-form');
|
||||
router.put('/:id', [LinksController, 'update']).as('link.edit');
|
||||
router.get('/edit', [UpdateLinkController, 'render']).as('link.edit-form');
|
||||
router.put('/:id', [UpdateLinkController, 'execute']).as('link.edit');
|
||||
|
||||
router
|
||||
.put('/:id/favorite', [LinksController, 'toggleFavorite'])
|
||||
.put('/:id/favorite', [ToggleFavoriteController, 'toggleFavorite'])
|
||||
.as('link.toggle-favorite');
|
||||
|
||||
router
|
||||
.get('/delete', [LinksController, 'showDeletePage'])
|
||||
.get('/delete', [DeleteLinkController, 'render'])
|
||||
.as('link.delete-form');
|
||||
router.delete('/:id', [LinksController, 'delete']).as('link.delete');
|
||||
router.delete('/:id', [DeleteLinkController, 'execute']).as('link.delete');
|
||||
})
|
||||
.middleware([middleware.auth()])
|
||||
.prefix('/links');
|
||||
|
||||
60
app/links/services/link_service.ts
Normal file
60
app/links/services/link_service.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import Link from '#links/models/link';
|
||||
import { HttpContext } from '@adonisjs/core/http';
|
||||
|
||||
type CreateLinkPayload = {
|
||||
name: string;
|
||||
description?: string;
|
||||
url: string;
|
||||
favorite: boolean;
|
||||
collectionId: number;
|
||||
};
|
||||
|
||||
type UpdateLinkPayload = CreateLinkPayload;
|
||||
|
||||
export class LinkService {
|
||||
createLink(payload: CreateLinkPayload) {
|
||||
const context = this.getAuthContext();
|
||||
return Link.create({
|
||||
...payload,
|
||||
authorId: context.auth.user!.id,
|
||||
});
|
||||
}
|
||||
|
||||
updateLink(id: number, payload: UpdateLinkPayload) {
|
||||
const context = this.getAuthContext();
|
||||
return Link.query()
|
||||
.where('id', id)
|
||||
.andWhere('author_id', context.auth.user!.id)
|
||||
.update(payload);
|
||||
}
|
||||
|
||||
deleteLink(id: number) {
|
||||
const context = this.getAuthContext();
|
||||
return Link.query()
|
||||
.where('id', id)
|
||||
.andWhere('author_id', context.auth.user!.id)
|
||||
.delete();
|
||||
}
|
||||
|
||||
async getLinkById(id: Link['id'], userId: Link['id']) {
|
||||
return await Link.query()
|
||||
.where('id', id)
|
||||
.andWhere('author_id', userId)
|
||||
.firstOrFail();
|
||||
}
|
||||
|
||||
updateFavorite(id: number, favorite: boolean) {
|
||||
return Link.query()
|
||||
.where('id', id)
|
||||
.andWhere('author_id', this.getAuthContext().auth.user!.id)
|
||||
.update({ favorite });
|
||||
}
|
||||
|
||||
getAuthContext() {
|
||||
const context = HttpContext.getOrFail();
|
||||
if (!context.auth.user || !context.auth.user.id) {
|
||||
throw new Error('User not authenticated');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user