Skip to content

Commit

Permalink
feat: create MyProject view, with updated controller with findByUser
Browse files Browse the repository at this point in the history
add tests, include to router and authentication
clean console logs from tests
  • Loading branch information
henriits committed Sep 1, 2024
1 parent 9783a41 commit 2fdcafe
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 12 deletions.
10 changes: 6 additions & 4 deletions client/src/layouts/MainLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@ import { useRouter } from 'vue-router'
const router = useRouter()
const links = computed(() => [
{ label: 'Projects', name: 'Home' },
{ label: 'Home', name: 'Home' },
...(isLoggedIn.value
? [{ label: 'Create a project', name: 'CreateProject' }]
? [
{ label: 'My Projects', name: 'MyProjects' },
{ label: 'Create a project', name: 'CreateProject' }
]
: [
{ label: 'Login', name: 'Login' },
{ label: 'Signup', name: 'Signup' },
{ label: 'Signup', name: 'Signup' }
]),
])
function logoutUser() {
logout()
router.push({ name: 'Login' })
Expand Down
5 changes: 5 additions & 0 deletions client/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const router = createRouter({
name: 'EditProject',
component: () => import('../views/EditProject.vue'),
},
{
path: 'my-projects',
name: 'MyProjects',
component: () => import('../views/MyProjects.vue'),
},
],
},
{
Expand Down
72 changes: 72 additions & 0 deletions client/src/views/MyProjects.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { trpc } from '@/trpc'
import type { Selectable } from 'kysely'
import type { Projects } from '@server/shared/types'
import { FwbButton } from 'flowbite-vue'
import ProjectCard from '@/components/ProjectCard.vue'
import { authUserId, isLoggedIn, username } from '@/stores/user'
const projects = ref<Selectable<Projects>[]>([])
const fetchProjects = async () => {
try {
if (!isLoggedIn.value) {
// Handle the case where the user is not logged in
console.log('User is not logged in. Redirecting or showing appropriate message.')
return
}
// Fetch projects for the authenticated user
if (authUserId.value) {
projects.value = await trpc.projects.findByUser.query({ userId: authUserId.value })
} else {
console.error('User ID is not available.')
}
} catch (err) {
console.error('Failed to fetch projects:', err)
}
}
onMounted(fetchProjects)
</script>

<template>
<div class="dark:bg-gray-800">
<div v-if="!isLoggedIn" class="rounded-md bg-white px-6 py-8">
<div class="items-center lg:flex">
<div class="lg:w-1/2">
<h2 class="text-4xl font-bold text-gray-800 dark:text-gray-100">DIY-Platform</h2>
<p class="mt-4 text-gray-500 dark:text-gray-400 lg:max-w-md">
A place where you can share your crafting ideas with others.
</p>
<div class="mt-6 flex items-center gap-2">
<FwbButton component="RouterLink" tag="router-link" href="/signup">Sign up</FwbButton>
<FwbButton component="RouterLink" tag="router-link" color="alternative" href="/login">
Log in
</FwbButton>
</div>
</div>
<div class="mt-8 lg:mt-0 lg:w-1/2">
<div class="flex items-center justify-center lg:justify-end">
<div class="max-w-lg">
<picture>
<source srcset="../assets/illustration.webp" type="image/webp" />
<img class="h-64 w-full rounded-md object-cover object-center"
src="../assets/illustration.png" alt="Person typing" />
</picture>
</div>
</div>
</div>
</div>
</div>
<div v-if="isLoggedIn" class="mt-12 text-center">
<p>Logged in as: {{ username }}</p>
<h3 class="text-2xl font-bold text-gray-800 dark:text-gray-100">My Projects</h3>
<div v-if="projects.length" class="mt-6 grid gap-6 lg:grid-cols-3">
<ProjectCard v-for="project in projects" :key="project.id" :project="project" />
</div>
<div v-else class="text-center text-gray-500 dark:text-gray-400">No projects yet!</div>
</div>
</div>
</template>
1 change: 0 additions & 1 deletion server/src/controllers/categories/tests/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const [user] = await insertAll(db, "users", [fakeUser()]);

it("allows creating a project category", async () => {
const category = fakeProjectCategory();
console.log(category);

const { create } = createCaller(authContext({ db }, user));
const categoryReturned = await create({ name: category.name });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ it("should create a category assignment for a given project and category", async
fakeProjectCategory(),
]);

// Print inserted data for verification
// console.log("Inserted project:", project1);
// console.log("Inserted category:", category1);

// Prepare assignment
const assignment = {
projectId: project1.id,
Expand Down
1 change: 0 additions & 1 deletion server/src/controllers/comments/tests/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ const [Project] = await insertAll(

it("allows creating a comment", async () => {
const comment = fakeComment({ projectId: Project.id });
console.log(comment);

const { create } = createCaller(authContext({ db }, userOther));
const commentReturned = await create(comment);
Expand Down
28 changes: 28 additions & 0 deletions server/src/controllers/projects/findByUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// server/src/controllers/projects/findByUser.ts

import { publicProcedure } from "@server/trpc";
import provideRepos from "@server/trpc/provideRepos";
import { TRPCError } from "@trpc/server";
import { projectRepository } from "@server/repositories/projectRepository";
import { z } from "zod";

export default publicProcedure
.use(
provideRepos({
projectRepository,
})
)
.input(z.object({ userId: z.number() })) // Ensure input is defined correctly
.query(async ({ input, ctx }) => {
const { userId } = input;

if (!userId) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: "User not authenticated",
});
}

// Fetch projects for the authenticated user
return ctx.repos.projectRepository.findByUser(userId);
});
2 changes: 2 additions & 0 deletions server/src/controllers/projects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import findById from "./findById";
import update from "./update";
import deleteProject from "./delete";
import findByTitle from "./findByTitle";
import findByUser from "./findByUser";

export default router({
create,
Expand All @@ -13,4 +14,5 @@ export default router({
findByTitle,
update,
delete: deleteProject,
findByUser,
});
43 changes: 43 additions & 0 deletions server/src/controllers/projects/tests/findByUser.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { authContext } from "@server/tests/utils/context";
import { fakeProject, fakeUser } from "@server/tests/utils/fakes";
import { createTestDatabase } from "@server/tests/utils/database";
import { createCallerFactory } from "@server/trpc";
import { wrapInRollbacks } from "@server/tests/utils/transactions";
import { insertAll } from "@server/tests/utils/records";
import projectRouter from "..";

const createCaller = createCallerFactory(projectRouter);
const db = await wrapInRollbacks(createTestDatabase());

const [user1, user2] = await insertAll(db, "users", [fakeUser(), fakeUser()]);

const [project1, project2, project3] = await insertAll(db, "projects", [
fakeProject({ userId: user1.id }),
fakeProject({ userId: user1.id }), // Another project for user1
fakeProject({ userId: user2.id }), // Project for user2
]);

const { findByUser } = createCaller(authContext({ db }, user1));

describe("findByUser", () => {
it("should return projects for the authenticated user", async () => {
const projectsResponse = await findByUser({ userId: user1.id }); // Pass an object with userId
expect(projectsResponse).toHaveLength(2); // Expecting 2 projects for user1
expect(projectsResponse).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: project1.id, userId: user1.id }),
expect.objectContaining({ id: project2.id, userId: user1.id }),
])
);
});

it("should return an empty array if the user has no projects", async () => {
const projectsResponse = await findByUser({ userId: user2.id }); // Pass an object with userId
expect(projectsResponse).toHaveLength(1);
expect(projectsResponse).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: project3.id, userId: user2.id }),
])
);
});
});
16 changes: 16 additions & 0 deletions server/src/repositories/projectRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,22 @@ export function projectRepository(db: Database) {
.limit(limit)
.execute();
},
async findByUser(
userId: number
): Promise<(ProjectPublic & { username: string })[]> {
return db
.selectFrom("projects")
.innerJoin("users", "projects.userId", "users.id")
.select([
...projectKeysPublic.map(
(key) => `projects.${key}` as keyof Projects
),
"users.username",
])
.where("projects.userId", "=", userId)
.orderBy("projects.id", "desc")
.execute();
},
async findByTitle(
title: string
): Promise<(ProjectPublic & { username: string })[]> {
Expand Down
2 changes: 1 addition & 1 deletion server/src/repositories/tests/projectRepository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("create", () => {
const [user] = await insertAll(db, "users", fakeUser());
// Create a project with the valid user id
const project = fakeProject({ userId: user.id });
console.log(project);

// Insert the project and verify its creation
const createdProject = await repository.create(project);

Expand Down
2 changes: 1 addition & 1 deletion server/src/repositories/tests/userRepository.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const repository = usersRepository(db);
describe("create", () => {
it("should create a new user", async () => {
const user = fakeUser();
console.log(fakeUser());

const createdUser = await repository.create(user);

expect(createdUser).toEqual({
Expand Down

0 comments on commit 2fdcafe

Please sign in to comment.