feat: built api & db tables for skills/roles and updating/querying them

This commit is contained in:
MTG2000
2022-08-22 15:58:24 +03:00
parent bf7825b4fe
commit 1895a8cf16
9 changed files with 273 additions and 15 deletions

View File

@@ -27,14 +27,29 @@ const BaseUser = interfaceType({
t.string('location')
t.nonNull.list.nonNull.field('roles', {
type: MakerRole,
resolve: (parent) => {
return []
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 []
return prisma.user.findUnique({ where: { id: parent.id } }).skills();
}
})
t.nonNull.list.nonNull.field('tournaments', {
@@ -112,7 +127,7 @@ const getAllMakersRoles = extendType({
t.nonNull.list.nonNull.field('getAllMakersRoles', {
type: GenericMakerRole,
async resolve(parent, args, context) {
return []
return prisma.workRole.findMany();
}
})
}
@@ -133,7 +148,7 @@ const getAllMakersSkills = extendType({
t.nonNull.list.nonNull.field('getAllMakersSkills', {
type: MakerSkill,
async resolve(parent, args, context) {
return []
return prisma.skill.findMany();
}
})
}
@@ -389,16 +404,38 @@ const updateProfileRoles = extendType({
// Do some validation
if (!user)
throw new Error("You have to login");
// TODO: validate new data
await prisma.user.update({
where: {
id: user.id,
},
data: {
skills: {
set: [],
},
roles: {
deleteMany: {}
},
},
}
)
// Preprocess & insert
return prisma.user.update({
where: {
id: user.id,
},
// data: removeNulls(args.data)
data: {
skills: {
connect: args.data.skills,
},
roles: {
create: args.data.roles.map(r => {
console.log(({ roleId: r.id, level: r.level }));
return ({ roleId: r.id, level: r.level })
})
}
}
})
}
})

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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
// -----------------

View File

@@ -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,
}

View File

@@ -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()

View File

@@ -25,7 +25,7 @@ const schema: yup.SchemaOf<IRolesSkillsForm> = yup.object({
roles: yup.array().of(
yup.object().shape({
id: yup.number().required(),
role: yup.string().required(),
level: yup.string().required(),
}).required()
).required(),
skills: yup.array().of(
@@ -70,7 +70,10 @@ export default function PreferencesTab() {
const toastId = toast.loading("Saving changes...", NotificationsService.defaultOptions)
mutate({
variables: {
data
data: {
roles: data.roles.map(v => ({ id: v.id, level: v.level })),
skills: data.skills.map(v => ({ id: v.id })),
}
},
onCompleted: ({ updateProfileRoles }) => {
if (updateProfileRoles) {
@@ -113,7 +116,7 @@ export default function PreferencesTab() {
<SaveChangesCard
isLoading={mutationStatus.loading}
isDirty={isDirty}
onSubmit={handleSubmit(onSubmit)}
onSubmit={handleSubmit(onSubmit, e => console.log(e))}
onCancel={() => reset()}
/>
</div>

View File

@@ -59,7 +59,7 @@ export default function UpdateRolesCard(props: Props) {
{props.value.map(role => {
const { title, icon } = props.allRoles.find(r => r.id === role.id)!;
return <>
return <React.Fragment key={role.id}>
<p className="shrink-0 text-body4 whitespace-nowrap">{icon} {title}</p>
<div className="flex flex-wrap gap-8 grow text-body5 mb-8 last-of-type:mb-0">
{[RoleLevelEnum.Beginner, RoleLevelEnum.Hobbyist, RoleLevelEnum.Intermediate, RoleLevelEnum.Advanced, RoleLevelEnum.Pro].map(r =>
@@ -71,7 +71,7 @@ export default function UpdateRolesCard(props: Props) {
onClick={() => setLevel(role.id, r)}
>{r}</button>
)}</div>
</>
</React.Fragment >
})}
</ul>
</div>}