diff --git a/src/BHC24.Api/Controllers/ProfileController.cs b/src/BHC24.Api/Controllers/ProfileController.cs index f1a1f9c..1a458c7 100644 --- a/src/BHC24.Api/Controllers/ProfileController.cs +++ b/src/BHC24.Api/Controllers/ProfileController.cs @@ -1,5 +1,6 @@ using BHC24.Api.Models; using BHC24.Api.Models.Profile; +using BHC24.Api.Models.Projects; using BHC24.Api.Persistence; using BHC24.Api.Persistence.Models; using BHC24.Api.Services; @@ -20,7 +21,7 @@ public ProfileController(BhcDbContext dbContext, AuthUserProvider authUser) _dbContext = dbContext; _authUser = authUser; } - + [HttpGet("{userId}")] public async Task> GetProfileAsync([FromRoute] Guid userId, CancellationToken ct) { @@ -33,23 +34,41 @@ public async Task> GetProfileAsync([FromRoute] Guid u ProfilePicture = x.ProfilePicture, UserCv = x.UserCv, Description = x.Description, - AppUser = x.AppUser, - Tags = x.Tags + UserName = x.AppUser.Name, + FirstName = x.AppUser.Name, + LastName = x.AppUser.Surname, + Tags = x.Tags.Select(t => new TagResponse + { + Id = t.Id, + Name = t.Name, + ImagePath = t.ImagePath + } + ).ToList(), + Projects = x.AppUser.Profile.Projects.Select(p => new GetProjectResponse + { + Title = p.Title, + Description = p.Description, + Owner = p.Owner.AppUser.Name, + OwnerId = p.Owner.AppUserId, + GithubUrl = p.GithubRepositoryUrl, + CollaboratorsCount = p.CollaboratorsCount, + Tags = p.Tags.Select(t => new TagResponse + { + Id = t.Id, + Name = t.Name, + ImagePath = t.ImagePath + } + ).ToList(), + }).ToList() }).FirstOrDefaultAsync(ct); - - if (profile.AppUser.Id != (await _authUser.GetAsync()).Id) - { - return Result.Forbidden("Forbidden"); - } - return Result.Ok(profile); } - + [HttpPost("/create")] public async Task CreateProfileAsync([FromBody] CreateProfileRequest request, CancellationToken ct) { var user = await _authUser.GetAsync(); - + var profile = new Profile { GithubAccountUrl = request.GithubAccountUrl, @@ -60,13 +79,13 @@ public async Task CreateProfileAsync([FromBody] CreateProfileRequest req AppUserId = user.Id, Tags = request.Tags }; - + _dbContext.Profiles.Add(profile); await _dbContext.SaveChangesAsync(ct); - + return Result.Ok(); } - + [HttpPut("{userId}")] public async Task UpdateProfileAsync([FromRoute] Guid userId, [FromBody] UpdateProfileRequest request, CancellationToken ct) { @@ -77,11 +96,11 @@ public async Task UpdateProfileAsync([FromRoute] Guid userId, [FromBody] var tagsToAdd = new List(); tagsToAdd.AddRange(request.Tags); - + var all_tags = await _dbContext.Profiles.Where(x => x.AppUserId == userId).SelectMany(x => x.Tags).ToListAsync(ct); - + tagsToAdd.AddRange(all_tags); - + var profile = await _dbContext.Profiles .Where(p => p.AppUserId == userId) .ExecuteUpdateAsync(b => @@ -91,10 +110,10 @@ public async Task UpdateProfileAsync([FromRoute] Guid userId, [FromBody] .SetProperty(p => p.UserCv, request.UserCv) .SetProperty(p => p.Description, request.Description) .SetProperty(p => p.Tags, tagsToAdd.Distinct()), ct); - + return Result.Ok(); } - + [HttpDelete("{userId}")] public async Task DeleteProfileAsync([FromRoute] Guid userId, CancellationToken ct) { @@ -106,15 +125,15 @@ public async Task DeleteProfileAsync([FromRoute] Guid userId, Can var profile = await _dbContext.Profiles .Where(p => p.AppUserId == userId) .SingleOrDefaultAsync(ct); - + if (profile == null) { return NotFound(); } - + _dbContext.Profiles.Remove(profile); await _dbContext.SaveChangesAsync(ct); - + return Ok(); } } \ No newline at end of file diff --git a/src/BHC24.Api/Controllers/ProjectController.cs b/src/BHC24.Api/Controllers/ProjectController.cs index f870675..a800f8f 100644 --- a/src/BHC24.Api/Controllers/ProjectController.cs +++ b/src/BHC24.Api/Controllers/ProjectController.cs @@ -34,6 +34,7 @@ public async Task>> GetList([FromQ Title = p.Title, Description = p.Description, Owner = p.Owner.AppUser.UserName, + OwnerId = p.Owner.AppUserId, GithubUrl = p.GithubRepositoryUrl, CollaboratorsCount = p.CollaboratorsCount, Tags = p.Tags.Select(t => new TagResponse diff --git a/src/BHC24.Api/Controllers/SearchController.cs b/src/BHC24.Api/Controllers/SearchController.cs index c1f34e1..ea759d8 100644 --- a/src/BHC24.Api/Controllers/SearchController.cs +++ b/src/BHC24.Api/Controllers/SearchController.cs @@ -51,6 +51,7 @@ public async Task>> SearchProjects Title = p.Title, Description = p.Description, Owner = p.Owner.AppUser.UserName, + OwnerId = p.Owner.AppUserId, GithubUrl = p.GithubRepositoryUrl, Tags = p.Tags.Select(t => new TagResponse { diff --git a/src/BHC24.Api/Models/Profile/GetProfileResponse.cs b/src/BHC24.Api/Models/Profile/GetProfileResponse.cs index 8ab81f6..c4fd384 100644 --- a/src/BHC24.Api/Models/Profile/GetProfileResponse.cs +++ b/src/BHC24.Api/Models/Profile/GetProfileResponse.cs @@ -1,3 +1,4 @@ +using BHC24.Api.Models.Projects; using BHC24.Api.Persistence.Models; namespace BHC24.Api.Models.Profile; @@ -10,6 +11,10 @@ public class GetProfileResponse public byte[]? UserCv { get; set; } public string? Description { get; set; } - public AppUser AppUser { get; set; } - public ICollection? Tags { get; set; } + public required string FirstName { get; set; } + public required string LastName { get; set; } + + public required string UserName { get; set; } + public ICollection? Tags { get; set; } + public ICollection Projects { get; set; } } \ No newline at end of file diff --git a/src/BHC24.Api/Models/Projects/Project.cs b/src/BHC24.Api/Models/Projects/Project.cs index 1ce0f94..484ff57 100644 --- a/src/BHC24.Api/Models/Projects/Project.cs +++ b/src/BHC24.Api/Models/Projects/Project.cs @@ -7,6 +7,7 @@ public record GetProjectResponse public string Title { get; init; } public string Description { get; init; } public string Owner { get; init; } + public Guid OwnerId { get; init; } public string GithubUrl { get; init; } public int CollaboratorsCount { get; init; } public IEnumerable Tags { get; init; } diff --git a/src/BHC24.Client/src/App.tsx b/src/BHC24.Client/src/App.tsx index 500e73c..4931369 100644 --- a/src/BHC24.Client/src/App.tsx +++ b/src/BHC24.Client/src/App.tsx @@ -34,7 +34,7 @@ const router = createBrowserRouter([ ] }, { - path: 'profile', + path: 'profile/:id', element: }, { diff --git a/src/BHC24.Client/src/components/ProjectItem.tsx b/src/BHC24.Client/src/components/ProjectItem.tsx new file mode 100644 index 0000000..dfb5d3e --- /dev/null +++ b/src/BHC24.Client/src/components/ProjectItem.tsx @@ -0,0 +1,18 @@ +import { GetProjectResponse } from "../utils/models"; +import { Divider } from "./Divider/Divider"; +import { TagBlock } from "./TagBlock/TagBlock"; + +export const ProjectItem = ({ project }: { project: GetProjectResponse }) => ( +
+

{project.title}

+

{project.description}

+

Właściciel: {project.owner}

+

Współpracownicy: {project.collaboratorsCount}

+
+ {project.tags.map(tag => ( + + ))} +
+ +
+) \ No newline at end of file diff --git a/src/BHC24.Client/src/components/TagBlock/TagBlock.tsx b/src/BHC24.Client/src/components/TagBlock/TagBlock.tsx new file mode 100644 index 0000000..7dc47ac --- /dev/null +++ b/src/BHC24.Client/src/components/TagBlock/TagBlock.tsx @@ -0,0 +1,16 @@ +import { GetTagResponse } from "../../utils/models"; + +export const TagBlock = ({ tag }: { tag: GetTagResponse }) => ( +
+ +
+); \ No newline at end of file diff --git a/src/BHC24.Client/src/pages/Profile/ProfilePage.tsx b/src/BHC24.Client/src/pages/Profile/ProfilePage.tsx index 93b1731..a678ae5 100644 --- a/src/BHC24.Client/src/pages/Profile/ProfilePage.tsx +++ b/src/BHC24.Client/src/pages/Profile/ProfilePage.tsx @@ -1,49 +1,79 @@ import AnimatedMain from "../../components/AnimatedComps/AnimatedMain"; import styles from "./ProfilePage.module.css"; import myImg from "../../assets/pic.jpg"; +import { useParams } from "react-router-dom"; +import { useGetProfile } from "../../hooks/useGetProfile"; +import { TagBlock } from "../../components/TagBlock/TagBlock"; +import { Divider } from "../../components/Divider/Divider"; +import { ProjectItem } from "../../components/ProjectItem"; export function ProfilePage() { + const params = useParams<{ id: string }>(); + + const { data: profile, isLoading, error } = useGetProfile(params.id!); + const UserSection = () => { return (
- +
-

Nazwa użytkownika

-

@nazwa_identyfikacyjna

+

{profile?.data?.firstName} {profile?.data?.lastName}

+

@{profile?.data?.userName}

- Opis użytkownika: Lorem ipsum dolor sit amet, consectetur adipiscing elit. - Vestibulum laoreet ligula in porttitor congue. Sed euismod lectus et feugiat porta. - Proin finibus mauris ac mauris rutrum venenatis. Ut gravida condimentum accumsan. - Etiam congue nulla pellentesque lobortis dignissim. Maecenas nec nisi in nisi hendrerit aliquam. - Pellentesque placerat vitae lectus id ullamcorper. + Opis użytkownika: Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Vestibulum laoreet ligula in porttitor congue. Sed euismod lectus et feugiat porta. + Proin finibus mauris ac mauris rutrum venenatis. Ut gravida condimentum accumsan. + Etiam congue nulla pellentesque lobortis dignissim. Maecenas nec nisi in nisi hendrerit aliquam. + Pellentesque placerat vitae lectus id ullamcorper.
) } - const Skills = () => { + const SkillsSection = () => { return (
-

Umiejętności

- HTML - CSS - JavaScript - React - Node.js +

Umiejętności

+ +
+ {profile?.data?.tags.map(tag => ( + + ))} +
- ); + ) + } + + const ProjectsSection = () => { + return ( +
+
+

Projekty

+ +
+ {profile?.data?.projects.map(project => ( + + ))} +
+
+
+ ) } return ( - - + <> + {isLoading &&

Loading...

} + + + +
) } \ No newline at end of file diff --git a/src/BHC24.Client/src/pages/ProjectSearch/ProjectSearch.tsx b/src/BHC24.Client/src/pages/ProjectSearch/ProjectSearch.tsx index e410d63..749999a 100644 --- a/src/BHC24.Client/src/pages/ProjectSearch/ProjectSearch.tsx +++ b/src/BHC24.Client/src/pages/ProjectSearch/ProjectSearch.tsx @@ -8,6 +8,7 @@ import {GetTagResponse, PaginationRequest} from "../../utils/models"; import {isLastPage} from "../../utils/helpers"; import styles from './ProjectSearch.module.css'; import {useGetTags as useGetTags} from "../../hooks/useGetTags"; +import { ProjectItem } from "../../components/ProjectItem"; import AnimatedDiv from "../../components/AnimatedComps/AnimatedDiv.tsx"; import {AnimatePresence} from "framer-motion"; @@ -48,19 +49,7 @@ export function ProjectSearch() { {isLoading && searchQuery !== '' &&

Loading...

} {error &&

Error: {error.message}

} {projects && searchQuery !== '' && projects.data?.data.map((project, index) => ( -
-

{project.title}

-

{project.description}

- -

Właściciel: {project.owner}

-

Współpracownicy: {project.collaboratorsCount}

-
- {project.tags.map(tag => ( - - ))} -
- -
+ ))} ); @@ -129,10 +118,10 @@ export function ProjectSearch() { ))} - {/*
*/} - {/* */} - {/* setOwnerName(e.target.value)}/>*/} - {/*
*/} +
+ + setOwnerName(e.target.value)}/> +
{/*
*/} {/* */} {/* */} diff --git a/src/BHC24.Client/src/utils/models.ts b/src/BHC24.Client/src/utils/models.ts index 7b8ad9a..e003330 100644 --- a/src/BHC24.Client/src/utils/models.ts +++ b/src/BHC24.Client/src/utils/models.ts @@ -42,7 +42,11 @@ export type GetProfileResponse = { profilePicture: string; userCv: string; description: string; - appUser: UserModel; + firstName: string; + lastName: string; + userName: string; + projects: GetProjectResponse[]; + tags: GetTagResponse[]; } export type PaginationRequest = { @@ -54,6 +58,7 @@ export type GetProjectResponse = { title: string; description: string; owner: string; + ownerId: string; collaboratorsCount: number; collaborators: string[]; tags: GetTagResponse[];