Skip to content

Commit

Permalink
feat: create githubProfile model / implement aside on profile page / …
Browse files Browse the repository at this point in the history
…implement protected route
  • Loading branch information
SwiichyCode committed Mar 13, 2024
1 parent 84e4ba0 commit e0bb305
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 34 deletions.
27 changes: 21 additions & 6 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,43 @@ model Session {
}

model User {
id String @id @default(cuid())
id String @id @default(cuid())
name String?
username String? @unique
username String? @unique
bio String?
company String?
location String?
blog String?
email String? @unique
email String? @unique
emailVerified DateTime?
repositoryAlreadyStarred Int[]
image String?
firstConnection Boolean @default(true)
dataSharingAgreement Boolean @default(false)
firstConnection Boolean @default(true)
dataSharingAgreement Boolean @default(false)
personalAccessToken String?
githubUserID Int?
role Role @default(USER)
role Role @default(USER)
accounts Account[]
sessions Session[]
posts Post[]
repositories Repository[]
likes Like[]
Comment Comment[]
githubProfile GithubProfile?
}

model GithubProfile {
id Int @id @default(autoincrement())
username String @unique
avatarUrl String?
email String?
name String?
bio String?
company String?
location String?
blog String?
userId String @unique
user User @relation(fields: [userId], references: [id])
}

model VerificationToken {
Expand Down
2 changes: 1 addition & 1 deletion src/app/(app)/profile/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default async function ProfilePage({
params: { id: string };
searchParams: { username: string };
}) {
const { githubProfile, githubProfileSocialAccounts, repositories } =
const { githubProfile, githubProfileSocialAccounts } =
await useFetchProfilePage({
userId: params.id,
username: searchParams.username,
Expand Down
File renamed without changes.
22 changes: 20 additions & 2 deletions src/app/(app)/profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import { getServerAuthSession } from "@/config/server/auth";
import { UserIdWithRole } from "@/modules/profile/components/UserId";
import { Aside } from "@/modules/profile/components/Aside";
import { useFetchProfilePage } from "@/modules/profile/hooks/use-fetch-profile-page";

export default async function ProfilePage() {
const session = await getServerAuthSession();

return <UserIdWithRole role={session?.user.role} session={session} />;
const { githubProfile, githubProfileSocialAccounts } =
await useFetchProfilePage({
userId: session?.user.id ?? "",
username: session?.user.username ?? "",
});

if (!githubProfile) {
return <div>User not found</div>;
}

return (
<>
<Aside
githubProfile={githubProfile}
githubProfileSocialAccounts={githubProfileSocialAccounts}
/>
</>
);
}
3 changes: 3 additions & 0 deletions src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { default } from "next-auth/middleware";

export const config = { matcher: ["/profile"] };
10 changes: 5 additions & 5 deletions src/modules/profile/components/Aside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { AsideProfileUsername } from "./Aside/AsideProfileUsername";
import { AsideProfileBio } from "./Aside/AsideProfileBio";
import { AsideProfileInformations } from "./Aside/AsideProfileInformations";
import type { OctokitSocialAccountsResponse } from "@/services/types/octokit.type";
import type { User } from "@/config/types/prisma.type";
import type { GithubProfile } from "@prisma/client";

type Props = {
githubProfile: User;
githubProfile: GithubProfile;
githubProfileSocialAccounts: OctokitSocialAccountsResponse;
};

Expand All @@ -17,10 +17,10 @@ export const Aside = ({
}: Props) => {
return (
<AsideLayout>
<AsideProfilePicture profilePicture={githubProfile.image} />
<AsideProfilePicture profilePicture={githubProfile.avatarUrl} />
<AsideProfileUsername
name={githubProfile.name!}
login={githubProfile.username!}
name={githubProfile.name ?? ""}
login={githubProfile.username}
/>
<AsideProfileBio bio={githubProfile.bio} />
<AsideProfileInformations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import {
} from "@primer/octicons-react";
import { cn } from "@/lib/utils";
import type { OctokitSocialAccountsResponse } from "@/services/types/octokit.type";
import type { User } from "@/config/types/prisma.type";
import type { GithubProfile } from "@prisma/client";

type Props = {
githubProfile: User;
githubProfile: GithubProfile;
githubProfileSocialAccounts: OctokitSocialAccountsResponse;
};

// TODO:
// - Parse social url to display only necessary information
// - Parse social url to display icon based on the social url

const profileInformationsItems = (githubProfile: User) => [
const profileInformationsItems = (githubProfile: GithubProfile) => [
{
name: githubProfile.company,
icon: <OrganizationIcon className="text-grey h-4 w-4" />,
Expand Down
3 changes: 2 additions & 1 deletion src/modules/profile/hooks/use-fetch-profile-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ type Props = {
};

export const useFetchProfilePage = async ({ userId, username }: Props) => {
const githubProfile = await userService.getUser({
const githubProfile = await userService.getGithubProfile({
userId,
});

const githubProfileSocialAccounts =
await octokitService.getUserSocialAccounts(username);

Expand Down
6 changes: 5 additions & 1 deletion src/modules/repositories/hooks/use-optimistic-star.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@ export const useOptimisticStar = ({
[isPending, repository.repositoryId, setOptimisticStar, startTransition],
);

return { isPending, handleStarRepository, optimisticStar };
return {
isPending,
handleStarRepository,
optimisticStar,
};
};
2 changes: 2 additions & 0 deletions src/services/actions/star-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ export const starRepositoryAction = userAction(
userId: ctx.session.user.id,
repositoryId: repositoryId,
});
await repositoryService.decrementStargazersCount({ repositoryId });
} else {
await octokitService.starRepository({ owner, repo: repositoryName });
await userService.addStarredRepository({
userId: ctx.session.user.id,
repositoryId: repositoryId,
});
await repositoryService.incrementStargazersCount({ repositoryId });
}

revalidatePath(URL.REPOSITORIES);
Expand Down
40 changes: 40 additions & 0 deletions src/services/repository.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,46 @@ class RepositoryService {
});
}

/**
* Query to increment the stargazers count of a repository.
* @param {Object} data - The repository data to be incremented.
* @param {number} data.repositoryId - The ID of the repository to be incremented.
* @throws {Error} - Throws an error if there's an error accessing the database.
*/

async incrementStargazersCount({ repositoryId }: RepositoryEntry) {
await db.repository.update({
where: {
repositoryId,
},
data: {
repositoryStargazers: {
increment: 1,
},
},
});
}

/**
* Query to decrement the stargazers count of a repository.
* @param {Object} data - The repository data to be decremented.
* @param {number} data.repositoryId - The ID of the repository to be decremented.
* @throws {Error} - Throws an error if there's an error accessing the database.
*/

async decrementStargazersCount({ repositoryId }: RepositoryEntry) {
await db.repository.update({
where: {
repositoryId,
},
data: {
repositoryStargazers: {
decrement: 1,
},
},
});
}

/**
* Query to get all repository entries from the database by filter.
* @param {Object} data - The filter data to be used.
Expand Down
91 changes: 76 additions & 15 deletions src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ class UserService {
});
}

/**
* Query to get the GitHub profile of the user.
* @param {string} userId - The user id.
* @throws {Error} - Throws an error if there's an error accessing the database.
*/

async getGithubProfile({ userId }: GetUserType) {
return await db.githubProfile.findFirst({
where: {
userId,
},
});
}

/**
* Query to get the GitHub user id of the user.
* @param {string} userId - The user id.
Expand Down Expand Up @@ -195,21 +209,68 @@ class UserService {

await repositoryService.syncStarredRepositories(user);

return await db.user.update({
where: {
id: user.id,
},
data: {
githubUserID: githubUser.data.id,
username: githubUser.data.login,
bio: githubUser.data.bio,
company: githubUser.data.company,
location: githubUser.data.location,
blog: githubUser.data.blog,
dataSharingAgreement: agreement,
firstConnection: agreement ? false : true,
},
});
// return await db.user.update({
// where: {
// id: user.id,
// },
// data: {
// githubUserID: githubUser.data.id,
// username: githubUser.data.login,
// bio: githubUser.data.bio,
// company: githubUser.data.company,
// location: githubUser.data.location,
// blog: githubUser.data.blog,
// dataSharingAgreement: agreement,
// firstConnection: agreement ? false : true,
// },
// });

await db.$transaction([
db.user.update({
where: {
id: user.id,
},
data: {
githubUserID: githubUser.data.id,
username: githubUser.data.login,
bio: githubUser.data.bio,
company: githubUser.data.company,
location: githubUser.data.location,
blog: githubUser.data.blog,
dataSharingAgreement: agreement,
firstConnection: agreement ? false : true,
},
}),
db.githubProfile.upsert({
where: {
userId: user.id,
},

create: {
userId: user.id,
avatarUrl: githubUser.data.avatar_url,
email: githubUser.data.email,
name: githubUser.data.name,
username: githubUser.data.login,
bio: githubUser.data.bio,
company: githubUser.data.company,
location: githubUser.data.location,
blog: githubUser.data.blog,
},

update: {
userId: user.id,
avatarUrl: githubUser.data.avatar_url,
email: githubUser.data.email,
name: githubUser.data.name,
username: githubUser.data.login,
bio: githubUser.data.bio,
company: githubUser.data.company,
location: githubUser.data.location,
blog: githubUser.data.blog,
},
}),
]);
}

/**
Expand Down

0 comments on commit e0bb305

Please sign in to comment.