diff --git a/api/functions/graphql/nexus-typegen.ts b/api/functions/graphql/nexus-typegen.ts index bd8c67e..68d20f0 100644 --- a/api/functions/graphql/nexus-typegen.ts +++ b/api/functions/graphql/nexus-typegen.ts @@ -28,6 +28,13 @@ declare global { } export interface NexusGenInputs { + MakerRoleInput: { // input type + id: number; // Int! + level: NexusGenEnums['RoleLevelEnum']; // RoleLevelEnum! + } + MakerSkillInput: { // input type + id: number; // Int! + } ProfileDetailsInput: { // input type avatar?: string | null; // String bio?: string | null; // String @@ -41,6 +48,10 @@ export interface NexusGenInputs { twitter?: string | null; // String website?: string | null; // String } + ProfileRolesInput: { // input type + roles: NexusGenInputs['MakerRoleInput'][]; // [MakerRoleInput!]! + skills: NexusGenInputs['MakerSkillInput'][]; // [MakerSkillInput!]! + } StoryInputType: { // input type body: string; // String! cover_image?: string | null; // String @@ -57,6 +68,7 @@ export interface NexusGenInputs { export interface NexusGenEnums { POST_TYPE: "Bounty" | "Question" | "Story" + RoleLevelEnum: 3 | 0 | 1 | 2 | 4 VOTE_ITEM_TYPE: "Bounty" | "PostComment" | "Project" | "Question" | "Story" | "User" } @@ -124,6 +136,11 @@ export interface NexusGenObjects { prizes: string; // String! touranments: string; // String! } + GenericMakerRole: { // root type + icon: string; // String! + id: number; // Int! + title: string; // String! + } Hackathon: { // root type cover_image: string; // String! description: string; // String! @@ -140,6 +157,16 @@ export interface NexusGenObjects { metadata?: string | null; // String minSendable?: number | null; // Int } + MakerRole: { // root type + icon: string; // String! + id: number; // Int! + level: NexusGenEnums['RoleLevelEnum']; // RoleLevelEnum! + title: string; // String! + } + MakerSkill: { // root type + id: number; // Int! + title: string; // String! + } Mutation: {}; MyProfile: { // root type avatar: string; // String! @@ -208,6 +235,16 @@ export interface NexusGenObjects { isOfficial?: boolean | null; // Boolean title: string; // String! } + Tournament: { // root type + cover_image: string; // String! + description: string; // String! + end_date: NexusGenScalars['Date']; // Date! + id: number; // Int! + start_date: NexusGenScalars['Date']; // Date! + thumbnail_image: string; // String! + title: string; // String! + website: string; // String! + } User: { // root type avatar: string; // String! bio?: string | null; // String @@ -315,6 +352,11 @@ export interface NexusGenFieldTypes { prizes: string; // String! touranments: string; // String! } + GenericMakerRole: { // field return type + icon: string; // String! + id: number; // Int! + title: string; // String! + } Hackathon: { // field return type cover_image: string; // String! description: string; // String! @@ -332,6 +374,16 @@ export interface NexusGenFieldTypes { metadata: string | null; // String minSendable: number | null; // Int } + MakerRole: { // field return type + icon: string; // String! + id: number; // Int! + level: NexusGenEnums['RoleLevelEnum']; // RoleLevelEnum! + title: string; // String! + } + MakerSkill: { // field return type + id: number; // Int! + title: string; // String! + } Mutation: { // field return type confirmDonation: NexusGenRootTypes['Donation']; // Donation! confirmVote: NexusGenRootTypes['Vote']; // Vote! @@ -339,6 +391,7 @@ export interface NexusGenFieldTypes { deleteStory: NexusGenRootTypes['Story'] | null; // Story donate: NexusGenRootTypes['Donation']; // Donation! updateProfileDetails: NexusGenRootTypes['MyProfile'] | null; // MyProfile + updateProfileRoles: NexusGenRootTypes['MyProfile'] | null; // MyProfile updateUserPreferences: NexusGenRootTypes['MyProfile']; // MyProfile! vote: NexusGenRootTypes['Vote']; // Vote! } @@ -357,7 +410,11 @@ export interface NexusGenFieldTypes { nostr_prv_key: string | null; // String nostr_pub_key: string | null; // String role: string | null; // String + roles: NexusGenRootTypes['MakerRole'][]; // [MakerRole!]! + similar_makers: NexusGenRootTypes['User'][]; // [User!]! + skills: NexusGenRootTypes['MakerSkill'][]; // [MakerSkill!]! stories: NexusGenRootTypes['Story'][]; // [Story!]! + tournaments: NexusGenRootTypes['Tournament'][]; // [Tournament!]! twitter: string | null; // String walletsKeys: NexusGenRootTypes['WalletKey'][]; // [WalletKey!]! website: string | null; // String @@ -389,6 +446,8 @@ export interface NexusGenFieldTypes { allCategories: NexusGenRootTypes['Category'][]; // [Category!]! allProjects: NexusGenRootTypes['Project'][]; // [Project!]! getAllHackathons: NexusGenRootTypes['Hackathon'][]; // [Hackathon!]! + getAllMakersRoles: NexusGenRootTypes['GenericMakerRole'][]; // [GenericMakerRole!]! + getAllMakersSkills: NexusGenRootTypes['MakerSkill'][]; // [MakerSkill!]! getCategory: NexusGenRootTypes['Category']; // Category! getDonationsStats: NexusGenRootTypes['DonationsStats']; // DonationsStats! getFeed: NexusGenRootTypes['Post'][]; // [Post!]! @@ -405,6 +464,7 @@ export interface NexusGenFieldTypes { profile: NexusGenRootTypes['User'] | null; // User projectsByCategory: NexusGenRootTypes['Project'][]; // [Project!]! searchProjects: NexusGenRootTypes['Project'][]; // [Project!]! + similarMakers: NexusGenRootTypes['User'][]; // [User!]! } Question: { // field return type author: NexusGenRootTypes['Author']; // Author! @@ -442,6 +502,17 @@ export interface NexusGenFieldTypes { isOfficial: boolean | null; // Boolean title: string; // String! } + Tournament: { // field return type + cover_image: string; // String! + description: string; // String! + end_date: NexusGenScalars['Date']; // Date! + id: number; // Int! + start_date: NexusGenScalars['Date']; // Date! + tags: NexusGenRootTypes['Tag'][]; // [Tag!]! + thumbnail_image: string; // String! + title: string; // String! + website: string; // String! + } User: { // field return type avatar: string; // String! bio: string | null; // String @@ -455,7 +526,11 @@ export interface NexusGenFieldTypes { location: string | null; // String name: string; // String! role: string | null; // String + roles: NexusGenRootTypes['MakerRole'][]; // [MakerRole!]! + similar_makers: NexusGenRootTypes['User'][]; // [User!]! + skills: NexusGenRootTypes['MakerSkill'][]; // [MakerSkill!]! stories: NexusGenRootTypes['Story'][]; // [Story!]! + tournaments: NexusGenRootTypes['Tournament'][]; // [Tournament!]! twitter: string | null; // String website: string | null; // String } @@ -485,7 +560,11 @@ export interface NexusGenFieldTypes { location: string | null; // String name: string; // String! role: string | null; // String + roles: NexusGenRootTypes['MakerRole'][]; // [MakerRole!]! + similar_makers: NexusGenRootTypes['User'][]; // [User!]! + skills: NexusGenRootTypes['MakerSkill'][]; // [MakerSkill!]! stories: NexusGenRootTypes['Story'][]; // [Story!]! + tournaments: NexusGenRootTypes['Tournament'][]; // [Tournament!]! twitter: string | null; // String website: string | null; // String } @@ -564,6 +643,11 @@ export interface NexusGenFieldTypeNames { prizes: 'String' touranments: 'String' } + GenericMakerRole: { // field return type name + icon: 'String' + id: 'Int' + title: 'String' + } Hackathon: { // field return type name cover_image: 'String' description: 'String' @@ -581,6 +665,16 @@ export interface NexusGenFieldTypeNames { metadata: 'String' minSendable: 'Int' } + MakerRole: { // field return type name + icon: 'String' + id: 'Int' + level: 'RoleLevelEnum' + title: 'String' + } + MakerSkill: { // field return type name + id: 'Int' + title: 'String' + } Mutation: { // field return type name confirmDonation: 'Donation' confirmVote: 'Vote' @@ -588,6 +682,7 @@ export interface NexusGenFieldTypeNames { deleteStory: 'Story' donate: 'Donation' updateProfileDetails: 'MyProfile' + updateProfileRoles: 'MyProfile' updateUserPreferences: 'MyProfile' vote: 'Vote' } @@ -606,7 +701,11 @@ export interface NexusGenFieldTypeNames { nostr_prv_key: 'String' nostr_pub_key: 'String' role: 'String' + roles: 'MakerRole' + similar_makers: 'User' + skills: 'MakerSkill' stories: 'Story' + tournaments: 'Tournament' twitter: 'String' walletsKeys: 'WalletKey' website: 'String' @@ -638,6 +737,8 @@ export interface NexusGenFieldTypeNames { allCategories: 'Category' allProjects: 'Project' getAllHackathons: 'Hackathon' + getAllMakersRoles: 'GenericMakerRole' + getAllMakersSkills: 'MakerSkill' getCategory: 'Category' getDonationsStats: 'DonationsStats' getFeed: 'Post' @@ -654,6 +755,7 @@ export interface NexusGenFieldTypeNames { profile: 'User' projectsByCategory: 'Project' searchProjects: 'Project' + similarMakers: 'User' } Question: { // field return type name author: 'Author' @@ -691,6 +793,17 @@ export interface NexusGenFieldTypeNames { isOfficial: 'Boolean' title: 'String' } + Tournament: { // field return type name + cover_image: 'String' + description: 'String' + end_date: 'Date' + id: 'Int' + start_date: 'Date' + tags: 'Tag' + thumbnail_image: 'String' + title: 'String' + website: 'String' + } User: { // field return type name avatar: 'String' bio: 'String' @@ -704,7 +817,11 @@ export interface NexusGenFieldTypeNames { location: 'String' name: 'String' role: 'String' + roles: 'MakerRole' + similar_makers: 'User' + skills: 'MakerSkill' stories: 'Story' + tournaments: 'Tournament' twitter: 'String' website: 'String' } @@ -734,7 +851,11 @@ export interface NexusGenFieldTypeNames { location: 'String' name: 'String' role: 'String' + roles: 'MakerRole' + similar_makers: 'User' + skills: 'MakerSkill' stories: 'Story' + tournaments: 'Tournament' twitter: 'String' website: 'String' } @@ -772,6 +893,9 @@ export interface NexusGenArgTypes { updateProfileDetails: { // args data?: NexusGenInputs['ProfileDetailsInput'] | null; // ProfileDetailsInput } + updateProfileRoles: { // args + data?: NexusGenInputs['ProfileRolesInput'] | null; // ProfileRolesInput + } updateUserPreferences: { // args userKeys?: NexusGenInputs['UserKeyInputType'][] | null; // [UserKeyInputType!] } @@ -833,6 +957,9 @@ export interface NexusGenArgTypes { skip?: number | null; // Int take: number | null; // Int } + similarMakers: { // args + id: number; // Int! + } } } diff --git a/api/functions/graphql/schema.graphql b/api/functions/graphql/schema.graphql index 8a3947c..226590b 100644 --- a/api/functions/graphql/schema.graphql +++ b/api/functions/graphql/schema.graphql @@ -31,7 +31,11 @@ interface BaseUser { location: String name: String! role: String + roles: [MakerRole!]! + similar_makers: [User!]! + skills: [MakerSkill!]! stories: [Story!]! + tournaments: [Tournament!]! twitter: String website: String } @@ -92,6 +96,12 @@ type DonationsStats { touranments: String! } +type GenericMakerRole { + icon: String! + id: Int! + title: String! +} + type Hackathon { cover_image: String! description: String! @@ -111,6 +121,27 @@ type LnurlDetails { minSendable: Int } +type MakerRole { + icon: String! + id: Int! + level: RoleLevelEnum! + title: String! +} + +input MakerRoleInput { + id: Int! + level: RoleLevelEnum! +} + +type MakerSkill { + id: Int! + title: String! +} + +input MakerSkillInput { + id: Int! +} + type Mutation { confirmDonation(payment_request: String!, preimage: String!): Donation! confirmVote(payment_request: String!, preimage: String!): Vote! @@ -118,6 +149,7 @@ type Mutation { deleteStory(id: Int!): Story donate(amount_in_sat: Int!): Donation! updateProfileDetails(data: ProfileDetailsInput): MyProfile + updateProfileRoles(data: ProfileRolesInput): MyProfile updateUserPreferences(userKeys: [UserKeyInputType!]): MyProfile! vote(amount_in_sat: Int!, item_id: Int!, item_type: VOTE_ITEM_TYPE!): Vote! } @@ -137,7 +169,11 @@ type MyProfile implements BaseUser { nostr_prv_key: String nostr_pub_key: String role: String + roles: [MakerRole!]! + similar_makers: [User!]! + skills: [MakerSkill!]! stories: [Story!]! + tournaments: [Tournament!]! twitter: String walletsKeys: [WalletKey!]! website: String @@ -185,6 +221,11 @@ input ProfileDetailsInput { website: String } +input ProfileRolesInput { + roles: [MakerRoleInput!]! + skills: [MakerSkillInput!]! +} + type Project { awards: [Award!]! category: Category! @@ -205,6 +246,8 @@ type Query { allCategories: [Category!]! allProjects(skip: Int = 0, take: Int = 50): [Project!]! getAllHackathons(sortBy: String, tag: Int): [Hackathon!]! + getAllMakersRoles: [GenericMakerRole!]! + getAllMakersSkills: [MakerSkill!]! getCategory(id: Int!): Category! getDonationsStats: DonationsStats! getFeed(skip: Int = 0, sortBy: String, tag: Int = 0, take: Int = 10): [Post!]! @@ -221,6 +264,7 @@ type Query { profile(id: Int!): User projectsByCategory(category_id: Int!, skip: Int = 0, take: Int = 10): [Project!]! searchProjects(search: String!, skip: Int = 0, take: Int = 50): [Project!]! + similarMakers(id: Int!): [User!]! } type Question implements PostBase { @@ -237,6 +281,14 @@ type Question implements PostBase { votes_count: Int! } +enum RoleLevelEnum { + Advanced + Beginner + Hobbyist + Intermediate + Pro +} + type Story implements PostBase { author: Author! body: String! @@ -271,6 +323,18 @@ type Tag { title: String! } +type Tournament { + cover_image: String! + description: String! + end_date: Date! + id: Int! + start_date: Date! + tags: [Tag!]! + thumbnail_image: String! + title: String! + website: String! +} + type User implements BaseUser { avatar: String! bio: String @@ -284,7 +348,11 @@ type User implements BaseUser { location: String name: String! role: String + roles: [MakerRole!]! + similar_makers: [User!]! + skills: [MakerSkill!]! stories: [Story!]! + tournaments: [Tournament!]! twitter: String website: String } diff --git a/api/functions/graphql/types/tournaments.js b/api/functions/graphql/types/tournaments.js new file mode 100644 index 0000000..9f04081 --- /dev/null +++ b/api/functions/graphql/types/tournaments.js @@ -0,0 +1,55 @@ +const { + intArg, + objectType, + stringArg, + extendType, + nonNull, +} = require('nexus'); +const { prisma } = require('../../../prisma'); + + + +const Tournament = objectType({ + name: 'Tournament', + definition(t) { + t.nonNull.int('id'); + t.nonNull.string('title'); + t.nonNull.string('description'); + t.nonNull.string('thumbnail_image'); + t.nonNull.string('cover_image'); + t.nonNull.date('start_date'); + t.nonNull.date('end_date'); + t.nonNull.string('website'); + t.nonNull.list.nonNull.field('tags', { + type: "Tag", + resolve: (parent) => { + // return prisma.hackathon.findUnique({ where: { id: parent.id } }).tags(); + return []; + } + }); + } +}) + +const getAllTournaments = extendType({ + type: "Query", + definition(t) { + t.nonNull.list.nonNull.field('getAllTournaments', { + type: Tournament, + args: { + sortBy: stringArg(), + tag: intArg(), + }, + resolve(_, args) { + const { sortBy, tag } = args; + return []; + } + }) + } +}) + +module.exports = { + // Types + Tournament, + // Queries + getAllTournaments, +} \ No newline at end of file diff --git a/api/functions/graphql/types/users.js b/api/functions/graphql/types/users.js index b633464..7173b36 100644 --- a/api/functions/graphql/types/users.js +++ b/api/functions/graphql/types/users.js @@ -1,8 +1,9 @@ const { prisma } = require('../../../prisma'); -const { objectType, extendType, intArg, nonNull, inputObjectType, interfaceType, list } = require("nexus"); +const { objectType, extendType, intArg, nonNull, inputObjectType, interfaceType, list, enumType } = require("nexus"); const { getUserByPubKey } = require("../../../auth/utils/helperFuncs"); const { removeNulls } = require("./helpers"); +const { Tournament } = require('./tournaments'); @@ -24,6 +25,54 @@ const BaseUser = interfaceType({ t.string('linkedin') t.string('bio') t.string('location') + t.nonNull.list.nonNull.field('roles', { + type: MakerRole, + resolve: async (parent) => { + const data = await prisma.user.findUnique({ + where: { + id: parent.id + }, + select: { + roles: { + select: { + role: true, + level: true + } + }, + } + }) + return data.roles.map(data => { + return ({ ...data.role, level: data.level }) + }) + } + }) + t.nonNull.list.nonNull.field('skills', { + type: MakerSkill, + resolve: (parent) => { + return prisma.user.findUnique({ where: { id: parent.id } }).skills(); + } + }) + t.nonNull.list.nonNull.field('tournaments', { + type: Tournament, + resolve: (parent) => { + return [] + } + }) + t.nonNull.list.nonNull.field('similar_makers', { + type: "User", + resolve(parent,) { + return prisma.user.findMany({ + where: { + AND: { + id: { + not: parent.id + } + } + }, + take: 3, + }) + } + }) t.nonNull.list.nonNull.field('stories', { @@ -40,6 +89,72 @@ const BaseUser = interfaceType({ }, }) + + +const RoleLevelEnum = enumType({ + name: 'RoleLevelEnum', + members: { + Beginner: 0, + Hobbyist: 1, + Intermediate: 2, + Advanced: 3, + Pro: 4, + }, +}); + +const GenericMakerRole = objectType({ + name: 'GenericMakerRole', + definition(t) { + t.nonNull.int('id'); + t.nonNull.string('title'); + t.nonNull.string('icon'); + } +}) + +const MakerRole = objectType({ + name: 'MakerRole', + definition(t) { + t.nonNull.int('id'); + t.nonNull.string('title'); + t.nonNull.string('icon'); + t.nonNull.field('level', { type: RoleLevelEnum }) + } +}) + +const getAllMakersRoles = extendType({ + type: "Query", + definition(t) { + t.nonNull.list.nonNull.field('getAllMakersRoles', { + type: GenericMakerRole, + async resolve(parent, args, context) { + return prisma.workRole.findMany(); + } + }) + } +}) + + +const MakerSkill = objectType({ + name: 'MakerSkill', + definition(t) { + t.nonNull.int('id'); + t.nonNull.string('title'); + } +}) + +const getAllMakersSkills = extendType({ + type: "Query", + definition(t) { + t.nonNull.list.nonNull.field('getAllMakersSkills', { + type: MakerSkill, + async resolve(parent, args, context) { + return prisma.skill.findMany(); + } + }) + } +}) + + const User = objectType({ name: 'User', definition(t) { @@ -93,6 +208,30 @@ const profile = extendType({ } }) +const similarMakers = extendType({ + type: "Query", + definition(t) { + t.nonNull.list.nonNull.field('similarMakers', { + type: "User", + args: { + id: nonNull(intArg()) + }, + async resolve(parent, { id }, ctx) { + return prisma.user.findMany({ + where: { + AND: { + id: { + not: id + } + } + }, + take: 3, + }) + } + }) + } +}) + const ProfileDetailsInput = inputObjectType({ name: 'ProfileDetailsInput', definition(t) { @@ -225,9 +364,88 @@ const updateUserPreferences = extendType({ +const MakerRoleInput = inputObjectType({ + name: "MakerRoleInput", + definition(t) { + t.nonNull.int('id'); + t.nonNull.field('level', { type: RoleLevelEnum }) + } +}) + +const MakerSkillInput = inputObjectType({ + name: "MakerSkillInput", + definition(t) { + t.nonNull.int('id'); + } +}) + + +const ProfileRolesInput = inputObjectType({ + name: 'ProfileRolesInput', + definition(t) { + t.nonNull.list.nonNull.field('roles', { + type: MakerRoleInput, + }) + t.nonNull.list.nonNull.field('skills', { + type: MakerSkillInput, + }) + } +}) + +const updateProfileRoles = extendType({ + type: 'Mutation', + definition(t) { + t.field('updateProfileRoles', { + type: 'MyProfile', + args: { data: ProfileRolesInput }, + async resolve(_root, args, ctx) { + const user = await getUserByPubKey(ctx.userPubKey); + + // Do some validation + if (!user) + throw new Error("You have to login"); + + await prisma.user.update({ + where: { + id: user.id, + }, + data: { + skills: { + set: [], + }, + roles: { + deleteMany: {} + }, + }, + } + ) + + + return prisma.user.update({ + where: { + id: user.id, + }, + data: { + skills: { + connect: args.data.skills, + }, + roles: { + create: args.data.roles.map(r => ({ roleId: r.id, level: r.level })) + } + } + }) + } + }) + }, +}) + + + + module.exports = { // Types + BaseUser, User, MyProfile, @@ -235,7 +453,11 @@ module.exports = { // Queries me, profile, + similarMakers, + getAllMakersRoles, + getAllMakersSkills, // Mutations updateProfileDetails, updateUserPreferences, + updateProfileRoles, } diff --git a/prisma/migrations/20220822112427_add_roles_skills_to_users_table/migration.sql b/prisma/migrations/20220822112427_add_roles_skills_to_users_table/migration.sql new file mode 100644 index 0000000..e1a4a18 --- /dev/null +++ b/prisma/migrations/20220822112427_add_roles_skills_to_users_table/migration.sql @@ -0,0 +1,57 @@ +-- AlterTable +ALTER TABLE "UserKey" ALTER COLUMN "name" SET DEFAULT E'My new wallet key'; + +-- CreateTable +CREATE TABLE "UsersOnWorkRoles" ( + "userId" INTEGER NOT NULL, + "roleId" INTEGER NOT NULL, + + CONSTRAINT "UsersOnWorkRoles_pkey" PRIMARY KEY ("userId","roleId") +); + +-- CreateTable +CREATE TABLE "WorkRole" ( + "id" SERIAL NOT NULL, + "title" TEXT NOT NULL, + "icon" TEXT NOT NULL, + + CONSTRAINT "WorkRole_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Skill" ( + "id" SERIAL NOT NULL, + "title" TEXT NOT NULL, + + CONSTRAINT "Skill_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_SkillToUser" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "WorkRole_title_key" ON "WorkRole"("title"); + +-- CreateIndex +CREATE UNIQUE INDEX "Skill_title_key" ON "Skill"("title"); + +-- CreateIndex +CREATE UNIQUE INDEX "_SkillToUser_AB_unique" ON "_SkillToUser"("A", "B"); + +-- CreateIndex +CREATE INDEX "_SkillToUser_B_index" ON "_SkillToUser"("B"); + +-- AddForeignKey +ALTER TABLE "UsersOnWorkRoles" ADD CONSTRAINT "UsersOnWorkRoles_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "UsersOnWorkRoles" ADD CONSTRAINT "UsersOnWorkRoles_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "WorkRole"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_SkillToUser" ADD FOREIGN KEY ("A") REFERENCES "Skill"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_SkillToUser" ADD FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20220822113244_add_level_field_to_user_roles_table/migration.sql b/prisma/migrations/20220822113244_add_level_field_to_user_roles_table/migration.sql new file mode 100644 index 0000000..16db1e9 --- /dev/null +++ b/prisma/migrations/20220822113244_add_level_field_to_user_roles_table/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `level` to the `UsersOnWorkRoles` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "UsersOnWorkRoles" ADD COLUMN "level" TEXT NOT NULL; diff --git a/prisma/migrations/20220822122053_change_level_field_to_int/migration.sql b/prisma/migrations/20220822122053_change_level_field_to_int/migration.sql new file mode 100644 index 0000000..019c60e --- /dev/null +++ b/prisma/migrations/20220822122053_change_level_field_to_int/migration.sql @@ -0,0 +1,9 @@ +/* + Warnings: + + - Changed the type of `level` on the `UsersOnWorkRoles` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- AlterTable +ALTER TABLE "UsersOnWorkRoles" DROP COLUMN "level", +ADD COLUMN "level" INTEGER NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index bd4c89a..1a5b903 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -65,6 +65,8 @@ model User { posts_comments PostComment[] donations Donation[] userKeys UserKey[] + skills Skill[] + roles UsersOnWorkRoles[] } model UserKey { @@ -75,6 +77,31 @@ model UserKey { user_id Int? } +model UsersOnWorkRoles { + user User @relation(fields: [userId], references: [id]) + userId Int + role WorkRole @relation(fields: [roleId], references: [id]) + roleId Int + + level Int + + @@id([userId, roleId]) +} + +model WorkRole { + id Int @id @default(autoincrement()) + title String @unique + icon String + users UsersOnWorkRoles[] +} + +model Skill { + id Int @id @default(autoincrement()) + title String @unique + + users User[] +} + // ----------------- // Projects // ----------------- diff --git a/prisma/seed/data.js b/prisma/seed/data.js index 4f22d06..cc482df 100644 --- a/prisma/seed/data.js +++ b/prisma/seed/data.js @@ -418,10 +418,103 @@ const hackathons = [ }, ] +const roles = [ + { + id: 1, + title: "Frontend Dev", + icon: "πŸ’„" + }, + { + id: 2, + title: "Backend Dev", + icon: "πŸ’»οΈ" + }, { + id: 3, + title: "UI/UX Designer", + icon: "🌈️️" + }, + { + id: 4, + title: "Community Manager", + icon: "πŸŽ‰οΈοΈ" + }, + { + id: 5, + title: "Founder", + icon: "πŸ¦„οΈ" + }, + { + id: 6, + title: "Marketer", + icon: "🚨️" + }, + { + id: 7, + title: "Content Creator", + icon: "πŸŽ₯️" + }, + { + id: 8, + title: "Researcher", + icon: "πŸ”¬" + }, + { + id: 9, + title: "Data engineer", + icon: "πŸ’ΏοΈ" + }, + { + id: 10, + title: "Growth hacker", + icon: "πŸ“‰οΈ" + }, + { + id: 11, + title: "Technical Writer", + icon: "✍️️" + }, +] + +const skills = [ + { + id: 1, + title: "Figma" + }, + { + id: 2, + title: "Prototyping" + }, { + id: 3, + title: "Writing" + }, { + id: 4, + title: "CSS" + }, { + id: 5, + title: "React.js" + }, { + id: 6, + title: "Wordpress" + }, { + id: 7, + title: "Principle app" + }, { + id: 8, + title: "UX design" + }, { + id: 9, + title: "User research" + }, { + id: 10, + title: "User testing" + }, +] module.exports = { categories, projects, tags, hackathons, + roles, + skills, } \ No newline at end of file diff --git a/prisma/seed/index.js b/prisma/seed/index.js index 1484395..abc52d5 100644 --- a/prisma/seed/index.js +++ b/prisma/seed/index.js @@ -1,6 +1,6 @@ const { PrismaClient } = require("@prisma/client"); const { generatePrivateKey, getPublicKey } = require("../../api/utils/nostr-tools"); -const { categories, projects, tags, hackathons } = require("./data"); +const { categories, projects, tags, hackathons, roles, skills } = require("./data"); const Chance = require('chance'); const { getCoverImage, randomItems, random } = require("./helpers"); @@ -58,7 +58,11 @@ async function main() { // await createHackathons(); - await fillUserKeysTable() + // await fillUserKeysTable() + + // await createRoles(); + + // await createSkills(); } @@ -169,6 +173,26 @@ async function fillUserKeysTable() { }) } +async function createRoles() { + console.log("Creating Users Roles"); + await prisma.workRole.createMany({ + data: roles.map(item => ({ + id: item.id, + title: item.title, + icon: item.icon, + })) + }) +} + +async function createSkills() { + console.log("Creating Users Skills"); + await prisma.skill.createMany({ + data: skills.map(item => ({ + id: item.id, + title: item.title, + })) + }) +} main() diff --git a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx index 99f5cfd..8404bf5 100644 --- a/src/features/Posts/Components/TrendingCard/TrendingCard.tsx +++ b/src/features/Posts/Components/TrendingCard/TrendingCard.tsx @@ -14,7 +14,7 @@ export default function TrendingCard() { return ( -

Trending on BOLT.FUN

+

Trending on BOLTπŸ”©FUN