mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 10:19:20 +03:00
feat: added colors to category model & added some helper funcs
This commit is contained in:
parent
aae79b582b
commit
10f72f3090
10
app/Helpers/ColorHelper.ts
Normal file
10
app/Helpers/ColorHelper.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import Color from 'App/Models/Color';
|
||||
import * as utils from 'App/Utils';
|
||||
|
||||
export default class ColorHelper {
|
||||
public static async generateRandomColor(): Promise<Color | null> {
|
||||
const colors = await Color.query();
|
||||
if (colors.length === 0) return null;
|
||||
return colors[utils.generateRandomInt({ min: 0, max: colors.length - 1 })];
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,9 @@
|
||||
/* eslint-disable import/no-cycle */
|
||||
import { DateTime } from 'luxon';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { BaseModel, beforeCreate, column } from '@ioc:Adonis/Lucid/Orm';
|
||||
import { BaseModel, beforeCreate, belongsTo, BelongsTo, column } from '@ioc:Adonis/Lucid/Orm';
|
||||
import ColorHelper from 'App/Helpers/ColorHelper';
|
||||
import Color from './Color';
|
||||
|
||||
export default class Category extends BaseModel {
|
||||
@column({ isPrimary: true })
|
||||
@ -14,6 +16,14 @@ export default class Category extends BaseModel {
|
||||
@column()
|
||||
public description: string;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
public color_id: number | null;
|
||||
|
||||
@belongsTo(() => Color, {
|
||||
foreignKey: 'color_id',
|
||||
})
|
||||
public color: BelongsTo<typeof Color>;
|
||||
|
||||
@column.dateTime({ autoCreate: true, serializeAs: null })
|
||||
public createdAt: DateTime;
|
||||
|
||||
@ -28,4 +38,13 @@ export default class Category extends BaseModel {
|
||||
public static assignCategoryId(category: Category) {
|
||||
category.id = nanoid();
|
||||
}
|
||||
|
||||
@beforeCreate()
|
||||
public static async assignRandomColor(category: Category) {
|
||||
const color = await ColorHelper.generateRandomColor();
|
||||
|
||||
if (color) {
|
||||
category.color_id = color.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,10 +14,12 @@ import {
|
||||
manyToMany,
|
||||
} from '@ioc:Adonis/Lucid/Orm';
|
||||
import { attachment, AttachmentContract } from '@ioc:Adonis/Addons/AttachmentLite';
|
||||
import ColorHelper from 'App/Helpers/ColorHelper';
|
||||
import Category from 'App/Models/Category';
|
||||
import Lesson from 'App/Models/Lesson';
|
||||
import User from 'App/Models/User';
|
||||
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
|
||||
import Color from './Color';
|
||||
|
||||
export default class Course extends BaseModel {
|
||||
@column({ isPrimary: true })
|
||||
@ -38,6 +40,14 @@ export default class Course extends BaseModel {
|
||||
@column({ serializeAs: null })
|
||||
public category_id: string;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
public color_id: number | null;
|
||||
|
||||
@belongsTo(() => Color, {
|
||||
foreignKey: 'color_id',
|
||||
})
|
||||
public color: BelongsTo<typeof Color>;
|
||||
|
||||
@column()
|
||||
public status: CourseStatusEnum;
|
||||
|
||||
@ -86,6 +96,15 @@ export default class Course extends BaseModel {
|
||||
course.id = nanoid();
|
||||
}
|
||||
|
||||
@beforeCreate()
|
||||
public static async assignRandomColor(course: Course) {
|
||||
const color = await ColorHelper.generateRandomColor();
|
||||
|
||||
if (color) {
|
||||
course.color_id = color.id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the `$extras` object
|
||||
*/
|
||||
|
||||
@ -29,7 +29,7 @@ export default class Lesson extends BaseModel {
|
||||
public course: BelongsTo<typeof Course>;
|
||||
|
||||
@column({ serializeAs: null })
|
||||
public color_id: number;
|
||||
public color_id: number | null;
|
||||
|
||||
@belongsTo(() => Color, {
|
||||
foreignKey: 'color_id',
|
||||
|
||||
@ -21,7 +21,7 @@ export default class CategoryRepository {
|
||||
* @returns Array of categories
|
||||
*/
|
||||
public async getAll(): Promise<Category[]> {
|
||||
const categories = await this.Category.query();
|
||||
const categories = await this.Category.query().preload('color');
|
||||
return categories;
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ export default class CategoryRepository {
|
||||
* @returns Category or null
|
||||
*/
|
||||
public async getById(id: string | number): Promise<Category | null> {
|
||||
const category = await this.Category.query().where('id', id).first();
|
||||
const category = await this.Category.query().preload('color').where('id', id).first();
|
||||
return category;
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +61,12 @@ export default class CourseRepository {
|
||||
query.andWhere('status', status);
|
||||
}
|
||||
|
||||
const courses = await query.preload('category').withCount('students').withCount('likes').withCount('lessons');
|
||||
const courses = await query
|
||||
.preload('color')
|
||||
.preload('category')
|
||||
.withCount('students')
|
||||
.withCount('likes')
|
||||
.withCount('lessons');
|
||||
|
||||
return courses;
|
||||
}
|
||||
@ -75,6 +80,7 @@ export default class CourseRepository {
|
||||
public async getById(id: string | number): Promise<Course | null> {
|
||||
const course = await this.Course.query()
|
||||
.preload('teacher')
|
||||
.preload('color')
|
||||
.preload('category')
|
||||
.preload('lessons', q => q.preload('color'))
|
||||
.preload('students')
|
||||
@ -192,6 +198,9 @@ export default class CourseRepository {
|
||||
course.teacher_id = data.teacher_id;
|
||||
course.category_id = data.category_id;
|
||||
|
||||
/**
|
||||
* Attach image
|
||||
*/
|
||||
if (data.image) {
|
||||
course.image = Attachment.fromFile(data.image);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ export default class MeService {
|
||||
*/
|
||||
if (RoleHelper.userHasRoles(user.roles, [RoleEnum.STUDENT])) {
|
||||
await user.load('courses', q => {
|
||||
q.preload('category');
|
||||
q.preload('category', loader => loader.preload('color'));
|
||||
q.withCount('students');
|
||||
q.withCount('likes');
|
||||
q.withCount('lessons');
|
||||
|
||||
4
app/Utils/index.ts
Normal file
4
app/Utils/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const generateRandomInt = ({ min, max }: { min: number; max: number }): number => {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
};
|
||||
@ -1,4 +1,5 @@
|
||||
import Factory from '@ioc:Adonis/Lucid/Factory';
|
||||
import { string } from '@ioc:Adonis/Core/Helpers';
|
||||
|
||||
/**
|
||||
* Datatypes
|
||||
@ -21,7 +22,7 @@ const makeFakeUser = (faker: Faker.FakerStatic, loginPrefix?: string) => {
|
||||
return {
|
||||
first_name: faker.name.firstName(),
|
||||
last_name: faker.name.lastName(),
|
||||
login: `${loginPrefix || 'user'}${faker.datatype.number(10000)}`,
|
||||
login: `${loginPrefix || 'user'}-${string.generateRandom(5)}`,
|
||||
email: faker.internet.exampleEmail(),
|
||||
password: '123456',
|
||||
};
|
||||
|
||||
@ -11,7 +11,7 @@ export default class Colors extends BaseSchema {
|
||||
.enu('name', Object.keys(ColorEnum), {
|
||||
useNative: true,
|
||||
enumName: 'color_name_enum',
|
||||
existingType: false,
|
||||
existingType: true,
|
||||
schemaName: 'public',
|
||||
})
|
||||
.notNullable();
|
||||
|
||||
@ -8,6 +8,7 @@ export default class Categories extends BaseSchema {
|
||||
table.string('id', 21).primary();
|
||||
table.string('title').notNullable();
|
||||
table.string('description');
|
||||
table.integer('color_id').unsigned().references('colors.id');
|
||||
table.timestamp('created_at', { useTz: true });
|
||||
table.timestamp('updated_at', { useTz: true });
|
||||
});
|
||||
|
||||
@ -16,11 +16,12 @@ export default class Courses extends BaseSchema {
|
||||
table.string('description').notNullable();
|
||||
table.string('teacher_id', 21).unsigned().references('users.id').notNullable().onDelete('CASCADE');
|
||||
table.string('category_id', 21).unsigned().references('categories.id').notNullable().onDelete('CASCADE');
|
||||
table.integer('color_id').unsigned().references('colors.id');
|
||||
table
|
||||
.enu('status', Object.values(CourseStatusEnum), {
|
||||
useNative: true,
|
||||
enumName: 'course_status_enum',
|
||||
existingType: false,
|
||||
existingType: true,
|
||||
schemaName: 'public',
|
||||
})
|
||||
.notNullable();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user