;
+};
+
+/**
+ * フォロー/フォロワーリスト
+ * @param follows
+ * @constructor
+ */
+export default function FollowList({ follows }: Props) {
+ const { data, isLoading, size, setSize } = follows;
+
+ if (isLoading) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+ <>
+ 現在のページ: {size}
+
+ {data?.map((follows, index) => (
+
+ {follows?.users.map((User, number) => (
+
+ ))}
+
+ ))}
+ >
+ );
+}
diff --git a/src/app/(menu)/(public)/[username]/followers/page.tsx b/src/app/(menu)/(public)/[username]/followers/page.tsx
index acda81f8..58b923bf 100644
--- a/src/app/(menu)/(public)/[username]/followers/page.tsx
+++ b/src/app/(menu)/(public)/[username]/followers/page.tsx
@@ -1,10 +1,40 @@
-import ComingSoon from '@/app/(menu)/_components/main/ComingSoon';
import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn';
+import { cache } from 'react';
+import { usersApi } from '@/libs/cuculus-client';
+import { notFound } from 'next/navigation';
+import Following from '@/app/(menu)/(public)/[username]/_components/Following';
+
+type Params = { params: { username: string } };
+
+const getUser = cache(async (username: string) => {
+ try {
+ return await usersApi.getUserByUsername(
+ { username },
+ {
+ next: {
+ revalidate: 300,
+ },
+ },
+ );
+ } catch {
+ return undefined;
+ }
+});
+
+/**
+ * フォロワー一覧ページ
+ * @param params
+ */
+export default async function page({ params }: Params) {
+ const username = decodeURIComponent(params.username);
+ const user = await getUser(username);
+ if (!user) {
+ notFound();
+ }
-export default function page({}: { params: { userName: string } }) {
return (
-
+ {/* */}
);
}
diff --git a/src/app/(menu)/(public)/[username]/following/page.tsx b/src/app/(menu)/(public)/[username]/following/page.tsx
index acda81f8..08a45a79 100644
--- a/src/app/(menu)/(public)/[username]/following/page.tsx
+++ b/src/app/(menu)/(public)/[username]/following/page.tsx
@@ -1,10 +1,40 @@
-import ComingSoon from '@/app/(menu)/_components/main/ComingSoon';
import PrimaryColumn from '@/app/(menu)/_components/main/PrimaryColumn';
+import { cache } from 'react';
+import { usersApi } from '@/libs/cuculus-client';
+import { notFound } from 'next/navigation';
+import Following from '@/app/(menu)/(public)/[username]/_components/Following';
+
+type Params = { params: { username: string } };
+
+const getUser = cache(async (username: string) => {
+ try {
+ return await usersApi.getUserByUsername(
+ { username },
+ {
+ next: {
+ revalidate: 300,
+ },
+ },
+ );
+ } catch {
+ return undefined;
+ }
+});
+
+/**
+ * フォロー一覧ページ
+ * @param params
+ */
+export default async function page({ params }: Params) {
+ const username = decodeURIComponent(params.username);
+ const user = await getUser(username);
+ if (!user) {
+ notFound();
+ }
-export default function page({}: { params: { userName: string } }) {
return (
-
+
);
}
diff --git a/src/swr/client/follows.ts b/src/swr/client/follows.ts
new file mode 100644
index 00000000..0d89ffba
--- /dev/null
+++ b/src/swr/client/follows.ts
@@ -0,0 +1,53 @@
+import { useAuth } from '@/swr/client/auth';
+import { usersApi } from '@/libs/cuculus-client';
+import { getAuthorizationHeader } from '@/libs/auth';
+import useSWRInfinite from 'swr/infinite';
+import { FollowList } from '@cuculus/cuculus-api';
+
+// FIXME 確認用に一旦10件にしている
+const LIMIT = 10;
+
+type SWRKey = {
+ key: string;
+ authId?: number;
+ userId: number;
+ nextUntil?: Date;
+};
+
+/**
+ * フォロー一覧の取得
+ * @param userId
+ */
+export const useFollowing = (userId: number) => {
+ const { data: authId } = useAuth();
+ return useSWRInfinite<
+ FollowList | undefined,
+ Error,
+ (index: number, prev: FollowList | undefined) => SWRKey | null
+ >(
+ (index, previousPageData) => {
+ // 取得結果が空の場合は次のページがないと判断して終了
+ if (previousPageData && !previousPageData.users.length) {
+ return null;
+ }
+ return {
+ key: 'useFollowing',
+ authId,
+ userId,
+ nextUntil: previousPageData?.nextUntil,
+ };
+ },
+ async (args) => {
+ try {
+ return await usersApi.getUserFollowing(
+ { id: args.userId, until: args.nextUntil, limit: LIMIT },
+ {
+ headers: await getAuthorizationHeader(authId),
+ },
+ );
+ } catch (error) {
+ throw error;
+ }
+ },
+ );
+};