diff --git a/client/src/App.tsx b/client/src/App.tsx
index 74f1ca6..dd4e6fe 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -11,12 +11,13 @@ import { Login } from "./Login";
import { Signup } from "./Signup";
import { Home } from "./Home";
import { loginAction, profileSelfAction, signupAction } from "./actions";
-import { homeLoader, profileLoader } from "./loaders";
+import { homeLoader, profileLoader, userListLoader } from "./loaders";
import { isError } from "./api/dto";
import { Feed } from "./Feed";
import { Messages } from "./Messages";
import { Profile } from "./Profile";
-import { getSelf } from "./api/Person";
+import { UserList } from "./UserList";
+import { getAllPerson } from "./api/Person";
const router = createBrowserRouter([
{
@@ -38,6 +39,7 @@ const router = createBrowserRouter([
children: [
{ path: "feed", element: },
{ path: "messages", element: },
+ { path: "users", element: , loader: userListLoader },
{
path: "profile",
loader: profileLoader,
diff --git a/client/src/Home.tsx b/client/src/Home.tsx
index 538e600..a579106 100644
--- a/client/src/Home.tsx
+++ b/client/src/Home.tsx
@@ -33,6 +33,9 @@ export function Home() {
Messages
+
+ Users
+
Profile
diff --git a/client/src/ProfileCard.tsx b/client/src/ProfileCard.tsx
index cd96a22..614813a 100644
--- a/client/src/ProfileCard.tsx
+++ b/client/src/ProfileCard.tsx
@@ -1,4 +1,5 @@
import "./ProfileCard.scss";
+import { Link } from "react-router-dom";
export function ProfileCard({
username,
@@ -9,8 +10,12 @@ export function ProfileCard({
}) {
return (
- {fullName}
- {username}
+
+ {fullName}
+
+
+ {username}
+
);
}
diff --git a/client/src/UserList.tsx b/client/src/UserList.tsx
new file mode 100644
index 0000000..6cf445d
--- /dev/null
+++ b/client/src/UserList.tsx
@@ -0,0 +1,26 @@
+import { useLoaderData } from "react-router-dom";
+import { LoaderToType, userListLoader } from "./loaders";
+import { isError } from "./api/dto";
+import { ProfileCard } from "./ProfileCard";
+
+export function UserList() {
+ const loaderData = useLoaderData() as LoaderToType;
+
+ if (!loaderData || isError(loaderData)) {
+ return Error
;
+ }
+
+ return (
+
+ {loaderData.map((u) => {
+ return (
+
+ );
+ })}
+
+ );
+}
diff --git a/client/src/api/Person.ts b/client/src/api/Person.ts
index 0cf5b72..9b19ba9 100644
--- a/client/src/api/Person.ts
+++ b/client/src/api/Person.ts
@@ -1,5 +1,10 @@
import { fetchJSON, fetchJSONAuth } from "./utils";
-import { PersonToResp, TPersonToResp } from "./dto";
+import {
+ PersonToArrResp,
+ PersonToResp,
+ TPersonToArrResp,
+ TPersonToResp,
+} from "./dto";
export async function signup(
username: string,
@@ -13,12 +18,24 @@ export async function signup(
});
}
+export async function getPersonByUuid(uuid: string): Promise {
+ return fetchJSONAuth("/person/by-uuid/" + uuid, "GET", PersonToResp);
+}
+
export async function getSelf(): Promise {
- return fetchJSONAuth("/person", "GET", PersonToResp);
+ return fetchJSONAuth("/person/self", "GET", PersonToResp);
+}
+
+export async function getAllPerson(): Promise {
+ return fetchJSONAuth("/person", "GET", PersonToArrResp);
}
export async function getPersonByUsername(
username: string,
): Promise {
- return fetchJSONAuth("/person/" + username, "GET", PersonToResp);
+ return fetchJSONAuth(
+ "/person/by-username/" + username,
+ "GET",
+ PersonToResp,
+ );
}
diff --git a/client/src/api/dto.ts b/client/src/api/dto.ts
index baca452..2d84724 100644
--- a/client/src/api/dto.ts
+++ b/client/src/api/dto.ts
@@ -33,6 +33,12 @@ export type TPersonTo = z.infer;
export const PersonToResp = CreateAPIResponse(PersonTo);
export type TPersonToResp = z.infer;
+export const PersonToArr = z.array(PersonTo);
+export type TPersonToArr = z.infer;
+
+export const PersonToArrResp = CreateAPIResponse(PersonToArr);
+export type TPersonToArrResp = z.infer;
+
export const TokenRequestTo = z.object({
username: z.string(),
password: z.string(),
diff --git a/client/src/loaders.ts b/client/src/loaders.ts
index 7837ef5..2f5f14a 100644
--- a/client/src/loaders.ts
+++ b/client/src/loaders.ts
@@ -1,4 +1,4 @@
-import { getPersonByUsername, getSelf } from "./api/Person";
+import { getAllPerson, getPersonByUsername, getSelf } from "./api/Person";
import { deleteToken, getToken } from "./api/utils";
import { redirect } from "react-router-dom";
import { isError } from "./api/dto";
@@ -24,14 +24,27 @@ export async function homeLoader() {
return await getCheckUserSelf();
}
+export async function userListLoader() {
+ return await getAllPerson();
+}
+
export async function profileLoader({
params,
}: {
params: { username?: string };
}) {
+ const self = await getCheckUserSelf();
+ if (!self || self instanceof Response || isError(self)) {
+ return self;
+ }
+
+ if (self.username == params.username) {
+ return redirect("/home/profile");
+ }
+
const user = params.username
? await getPersonByUsername(params.username)
- : await getCheckUserSelf();
+ : self;
if (!user || user instanceof Response || isError(user)) {
return user;
}
diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java b/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
index 98f3c34..c4410b8 100644
--- a/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
+++ b/server/src/main/java/com/usatiuk/tjv/y/server/controller/PersonController.java
@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.*;
import java.security.Principal;
import java.util.Optional;
import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
@RestController
@RequestMapping(value = "/person", produces = MediaType.APPLICATION_JSON_VALUE)
@@ -35,8 +36,8 @@ public class PersonController {
return PersonMapper.makeDto(created);
}
- @GetMapping(path = "/{username}")
- public PersonTo get(@PathVariable String username) throws UserNotFoundException {
+ @GetMapping(path = "/by-username/{username}")
+ public PersonTo getByUsername(@PathVariable String username) throws UserNotFoundException {
Optional found = personService.readByUsername(username);
if (found.isEmpty()) throw new UserNotFoundException();
@@ -44,7 +45,17 @@ public class PersonController {
return PersonMapper.makeDto(found.get());
}
- @GetMapping
+ @GetMapping(path = "/by-uuid/{uuid}")
+ public PersonTo getByUuid(@PathVariable String uuid) throws UserNotFoundException {
+ Optional found = personService.readById(uuid);
+
+ if (found.isEmpty()) throw new UserNotFoundException();
+
+ return PersonMapper.makeDto(found.get());
+ }
+
+
+ @GetMapping(path = "/self")
public PersonTo getSelf(Principal principal) throws UserNotFoundException {
Optional found = personService.readById(principal.getName());
@@ -53,6 +64,11 @@ public class PersonController {
return PersonMapper.makeDto(found.get());
}
+ @GetMapping
+ public Stream getAll() throws UserNotFoundException {
+ return StreamSupport.stream(personService.readAll().spliterator(), false).map(PersonMapper::makeDto);
+ }
+
@GetMapping(path = "/followers")
public Stream getFollowers(Principal principal) throws UserNotFoundException {
return personService.getFollowers(principal.getName()).stream().map(PersonMapper::makeDto);
diff --git a/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java b/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java
index 24c87df..a43df67 100644
--- a/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java
+++ b/server/src/main/java/com/usatiuk/tjv/y/server/security/WebSecurityConfig.java
@@ -63,7 +63,9 @@ public class WebSecurityConfig {
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post/*")).permitAll()
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post*")).permitAll()
.requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll()
- .requestMatchers(mvc.pattern(HttpMethod.GET, "/person/*")).permitAll()
+ .requestMatchers(mvc.pattern(HttpMethod.GET, "/person")).permitAll()
+ .requestMatchers(mvc.pattern(HttpMethod.GET, "/person/by-username/*")).permitAll()
+ .requestMatchers(mvc.pattern(HttpMethod.GET, "/person/by-uuid/*")).permitAll()
.requestMatchers(mvc.pattern(HttpMethod.POST, "/token")).permitAll()
.anyRequest().hasAuthority(UserRoles.ROLE_USER.name()))
.sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
diff --git a/server/src/test/java/com/usatiuk/tjv/y/server/controller/PersonControllerTest.java b/server/src/test/java/com/usatiuk/tjv/y/server/controller/PersonControllerTest.java
index 41c10ec..2dd6595 100644
--- a/server/src/test/java/com/usatiuk/tjv/y/server/controller/PersonControllerTest.java
+++ b/server/src/test/java/com/usatiuk/tjv/y/server/controller/PersonControllerTest.java
@@ -37,7 +37,7 @@ public class PersonControllerTest extends DemoDataDbTest {
@Test
void shouldGet() {
- var response = restTemplate.exchange(addr + "/person/" + person1.getUsername(),
+ var response = restTemplate.exchange(addr + "/person/by-username/" + person1.getUsername(),
HttpMethod.GET, HttpEntity.EMPTY, PersonTo.class);
Assertions.assertNotNull(response);
@@ -52,7 +52,7 @@ public class PersonControllerTest extends DemoDataDbTest {
@Test
void shouldGetSelf() {
- var response = restTemplate.exchange(addr + "/person",
+ var response = restTemplate.exchange(addr + "/person/self",
HttpMethod.GET, new HttpEntity<>(createAuthHeaders(person1Auth)), PersonTo.class);
Assertions.assertNotNull(response);