[frontend]: add followers page
This commit is contained in:
parent
ed59327cb7
commit
0f16f9d209
@ -30,6 +30,7 @@
|
|||||||
"@radix-ui/react-switch": "1.2.5",
|
"@radix-ui/react-switch": "1.2.5",
|
||||||
"@radix-ui/react-tabs": "^1.1.12",
|
"@radix-ui/react-tabs": "^1.1.12",
|
||||||
"@radix-ui/react-tooltip": "1.2.7",
|
"@radix-ui/react-tooltip": "1.2.7",
|
||||||
|
"@tanstack/react-table": "8.21.3",
|
||||||
"apollo-upload-client": "18.0.1",
|
"apollo-upload-client": "18.0.1",
|
||||||
"class-variance-authority": "0.7.1",
|
"class-variance-authority": "0.7.1",
|
||||||
"clsx": "2.1.1",
|
"clsx": "2.1.1",
|
||||||
|
|||||||
20
frontend/src/app/(site)/dashboard/followers/page.tsx
Normal file
20
frontend/src/app/(site)/dashboard/followers/page.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { getTranslations } from 'next-intl/server';
|
||||||
|
|
||||||
|
import { FollowersTable } from '@/components/features/follow/table/FollowersTable';
|
||||||
|
import { NO_INDEX_PAGE } from '@/libs/constants/seo.constants';
|
||||||
|
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
|
||||||
|
export async function generateMetadata(): Promise<Metadata> {
|
||||||
|
const t = await getTranslations('dashboard.followers.header');
|
||||||
|
|
||||||
|
return {
|
||||||
|
title: t('heading'),
|
||||||
|
description: t('description'),
|
||||||
|
...NO_INDEX_PAGE,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const FollowersPage = () => <FollowersTable />;
|
||||||
|
|
||||||
|
export default FollowersPage;
|
||||||
106
frontend/src/components/features/follow/table/FollowersTable.tsx
Normal file
106
frontend/src/components/features/follow/table/FollowersTable.tsx
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { MoreHorizontal, User } from 'lucide-react';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
|
import { Button } from '@/components/ui/common/Button';
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '@/components/ui/common/DropdownMenu';
|
||||||
|
import { ChannelAvatar } from '@/components/ui/elements/ChannelAvatar';
|
||||||
|
import { ChannelVerified } from '@/components/ui/elements/ChannelVerified';
|
||||||
|
import { DataTable, DataTableSkeleton } from '@/components/ui/elements/DataTable';
|
||||||
|
import { Heading } from '@/components/ui/elements/Heading';
|
||||||
|
import {
|
||||||
|
type FindMyFollowersQuery,
|
||||||
|
useFindMyFollowersQuery,
|
||||||
|
} from '@/graphql/generated/output';
|
||||||
|
import { formatDate } from '@/utils/format-date';
|
||||||
|
|
||||||
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
|
|
||||||
|
const FollowerCell = ({ row }: any) => (
|
||||||
|
<div className="flex items-center gap-x-2">
|
||||||
|
<ChannelAvatar channel={row.original.follower} size="sm" />
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
{row.original.follower.name}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{row.original.follower.isVerified ? <ChannelVerified size="sm" /> : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const FollowerActionCell = ({ row }: any) => {
|
||||||
|
const t = useTranslations('dashboard.followers');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<Button className="size-8 p-0" variant="ghost">
|
||||||
|
<MoreHorizontal className="size-4" />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
|
||||||
|
<DropdownMenuContent side="right">
|
||||||
|
<Link
|
||||||
|
href={`/${row.original.follower.name}`}
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<DropdownMenuItem>
|
||||||
|
<User className="mr-2 size-4" />
|
||||||
|
|
||||||
|
{t('columns.viewChannel')}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</Link>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FollowersTable = () => {
|
||||||
|
const t = useTranslations('dashboard.followers');
|
||||||
|
|
||||||
|
const { data, loading: isLoadingFollowers } = useFindMyFollowersQuery();
|
||||||
|
const followers = data?.findMyFollowers ?? [];
|
||||||
|
|
||||||
|
const followersColumns: ColumnDef<FindMyFollowersQuery['findMyFollowers'][0]>[] = [
|
||||||
|
{
|
||||||
|
accessorKey: 'createdAt',
|
||||||
|
header: t('columns.date'),
|
||||||
|
cell: ({ row }) => formatDate(row.original.createdAt),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'follower',
|
||||||
|
header: t('columns.user'),
|
||||||
|
cell: FollowerCell,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'actions',
|
||||||
|
header: t('columns.actions'),
|
||||||
|
cell: FollowerActionCell,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="lg:px-10">
|
||||||
|
<Heading
|
||||||
|
description={t('header.description')}
|
||||||
|
size="lg"
|
||||||
|
title={t('header.heading')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="mt-5">
|
||||||
|
{
|
||||||
|
isLoadingFollowers
|
||||||
|
? <DataTableSkeleton />
|
||||||
|
: <DataTable columns={followersColumns} data={followers} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
124
frontend/src/components/ui/common/Table.tsx
Normal file
124
frontend/src/components/ui/common/Table.tsx
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import {
|
||||||
|
type HTMLAttributes,
|
||||||
|
type TdHTMLAttributes,
|
||||||
|
type ThHTMLAttributes,
|
||||||
|
forwardRef,
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
|
import { cn } from '@/utils/tw-merge';
|
||||||
|
|
||||||
|
const Table = forwardRef<HTMLTableElement, HTMLAttributes<HTMLTableElement>>(
|
||||||
|
({ className, ...props }, ref) => (
|
||||||
|
<div className="relative w-full overflow-auto">
|
||||||
|
<table
|
||||||
|
ref={ref}
|
||||||
|
className={cn('w-full caption-bottom text-sm', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
);
|
||||||
|
Table.displayName = 'Table';
|
||||||
|
|
||||||
|
const TableHeader = forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
|
||||||
|
));
|
||||||
|
TableHeader.displayName = 'TableHeader';
|
||||||
|
|
||||||
|
const TableBody = forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tbody
|
||||||
|
ref={ref}
|
||||||
|
className={cn('[&_tr:last-child]:border-0', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableBody.displayName = 'TableBody';
|
||||||
|
|
||||||
|
const TableFooter = forwardRef<
|
||||||
|
HTMLTableSectionElement,
|
||||||
|
HTMLAttributes<HTMLTableSectionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tfoot
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableFooter.displayName = 'TableFooter';
|
||||||
|
|
||||||
|
const TableRow = forwardRef<
|
||||||
|
HTMLTableRowElement,
|
||||||
|
HTMLAttributes<HTMLTableRowElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<tr
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'border-b transition-colors hover:bg-card data-[state=selected]:bg-muted',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableRow.displayName = 'TableRow';
|
||||||
|
|
||||||
|
const TableHead = forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
ThHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<th
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableHead.displayName = 'TableHead';
|
||||||
|
|
||||||
|
const TableCell = forwardRef<
|
||||||
|
HTMLTableCellElement,
|
||||||
|
TdHTMLAttributes<HTMLTableCellElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<td
|
||||||
|
ref={ref}
|
||||||
|
className={cn(
|
||||||
|
'px-4 py-2 align-middle [&:has([role=checkbox])]:pr-0',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableCell.displayName = 'TableCell';
|
||||||
|
|
||||||
|
const TableCaption = forwardRef<
|
||||||
|
HTMLTableCaptionElement,
|
||||||
|
HTMLAttributes<HTMLTableCaptionElement>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<caption
|
||||||
|
ref={ref}
|
||||||
|
className={cn('mt-4 text-sm text-muted-foreground', className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
TableCaption.displayName = 'TableCaption';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCaption,
|
||||||
|
TableCell,
|
||||||
|
TableFooter,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
};
|
||||||
99
frontend/src/components/ui/elements/DataTable.tsx
Normal file
99
frontend/src/components/ui/elements/DataTable.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
type ColumnDef,
|
||||||
|
flexRender,
|
||||||
|
getCoreRowModel,
|
||||||
|
useReactTable,
|
||||||
|
} from '@tanstack/react-table';
|
||||||
|
import { Loader } from 'lucide-react';
|
||||||
|
import { useTranslations } from 'next-intl';
|
||||||
|
|
||||||
|
import { Card } from '../common/Card';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '../common/Table';
|
||||||
|
|
||||||
|
type DataTableProps<TData, TValue> = {
|
||||||
|
columns: ColumnDef<TData, TValue>[];
|
||||||
|
data: TData[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DataTable = <TData, TValue>({
|
||||||
|
columns,
|
||||||
|
data,
|
||||||
|
}: DataTableProps<TData, TValue>) => {
|
||||||
|
const t = useTranslations('components.dataTable');
|
||||||
|
|
||||||
|
const table = useReactTable({
|
||||||
|
data,
|
||||||
|
columns,
|
||||||
|
getCoreRowModel: getCoreRowModel(),
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="rounded-lg border">
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
<TableRow key={headerGroup.id}>
|
||||||
|
{headerGroup.headers.map((header) => (
|
||||||
|
<TableHead key={header.id}>
|
||||||
|
{header.isPlaceholder
|
||||||
|
? null
|
||||||
|
: flexRender(
|
||||||
|
header.column.columnDef
|
||||||
|
.header,
|
||||||
|
header.getContext(),
|
||||||
|
)}
|
||||||
|
</TableHead>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableHeader>
|
||||||
|
|
||||||
|
<TableBody>
|
||||||
|
{table.getRowModel().rows?.length
|
||||||
|
? table.getRowModel().rows.map((row) => (
|
||||||
|
<TableRow
|
||||||
|
key={row.id}
|
||||||
|
data-state={row.getIsSelected() && 'selected'}
|
||||||
|
>
|
||||||
|
{row.getVisibleCells().map((cell) => (
|
||||||
|
<TableCell key={cell.id}>
|
||||||
|
{flexRender(
|
||||||
|
cell.column.columnDef.cell,
|
||||||
|
cell.getContext(),
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
))}
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
: (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell
|
||||||
|
className="h-24 text-center"
|
||||||
|
colSpan={columns.length}
|
||||||
|
>
|
||||||
|
{t('notFound')}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DataTableSkeleton = () => (
|
||||||
|
<div className="mx-auto mb-10 w-full max-w-(--breakpoint-2xl)">
|
||||||
|
<Card className="mt-6 flex h-[500px] w-full items-center justify-center">
|
||||||
|
<Loader className="size-8 animate-spin text-muted-foreground" />
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@ -764,6 +764,16 @@ export type FindRecommendedChannelsQueryVariables = Exact<{ [key: string]: never
|
|||||||
|
|
||||||
export type FindRecommendedChannelsQuery = { __typename?: 'Query', findRecommendedChannels: Array<{ __typename?: 'UserModel', id: string, name: string, avatar?: string | null, isVerified: boolean, stream: { __typename?: 'StreamModel', isLive: boolean } }> };
|
export type FindRecommendedChannelsQuery = { __typename?: 'Query', findRecommendedChannels: Array<{ __typename?: 'UserModel', id: string, name: string, avatar?: string | null, isVerified: boolean, stream: { __typename?: 'StreamModel', isLive: boolean } }> };
|
||||||
|
|
||||||
|
export type FindMyFollowersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type FindMyFollowersQuery = { __typename?: 'Query', findMyFollowers: Array<{ __typename?: 'FollowModel', createdAt: any, follower: { __typename?: 'UserModel', name: string, avatar?: string | null, isVerified: boolean } }> };
|
||||||
|
|
||||||
|
export type FindMyFollowingsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
|
export type FindMyFollowingsQuery = { __typename?: 'Query', findMyFollowings: Array<{ __typename?: 'FollowModel', createdAt: any, followingId: string }> };
|
||||||
|
|
||||||
export type FindCurrentSessionQueryVariables = Exact<{ [key: string]: never; }>;
|
export type FindCurrentSessionQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
@ -1676,6 +1686,90 @@ export type FindRecommendedChannelsQueryHookResult = ReturnType<typeof useFindRe
|
|||||||
export type FindRecommendedChannelsLazyQueryHookResult = ReturnType<typeof useFindRecommendedChannelsLazyQuery>;
|
export type FindRecommendedChannelsLazyQueryHookResult = ReturnType<typeof useFindRecommendedChannelsLazyQuery>;
|
||||||
export type FindRecommendedChannelsSuspenseQueryHookResult = ReturnType<typeof useFindRecommendedChannelsSuspenseQuery>;
|
export type FindRecommendedChannelsSuspenseQueryHookResult = ReturnType<typeof useFindRecommendedChannelsSuspenseQuery>;
|
||||||
export type FindRecommendedChannelsQueryResult = Apollo.QueryResult<FindRecommendedChannelsQuery, FindRecommendedChannelsQueryVariables>;
|
export type FindRecommendedChannelsQueryResult = Apollo.QueryResult<FindRecommendedChannelsQuery, FindRecommendedChannelsQueryVariables>;
|
||||||
|
export const FindMyFollowersDocument = gql`
|
||||||
|
query FindMyFollowers {
|
||||||
|
findMyFollowers {
|
||||||
|
createdAt
|
||||||
|
follower {
|
||||||
|
name
|
||||||
|
avatar
|
||||||
|
isVerified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useFindMyFollowersQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useFindMyFollowersQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useFindMyFollowersQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useFindMyFollowersQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useFindMyFollowersQuery(baseOptions?: Apollo.QueryHookOptions<FindMyFollowersQuery, FindMyFollowersQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<FindMyFollowersQuery, FindMyFollowersQueryVariables>(FindMyFollowersDocument, options);
|
||||||
|
}
|
||||||
|
export function useFindMyFollowersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FindMyFollowersQuery, FindMyFollowersQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<FindMyFollowersQuery, FindMyFollowersQueryVariables>(FindMyFollowersDocument, options);
|
||||||
|
}
|
||||||
|
export function useFindMyFollowersSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<FindMyFollowersQuery, FindMyFollowersQueryVariables>) {
|
||||||
|
const options = baseOptions === Apollo.skipToken ? baseOptions : {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useSuspenseQuery<FindMyFollowersQuery, FindMyFollowersQueryVariables>(FindMyFollowersDocument, options);
|
||||||
|
}
|
||||||
|
export type FindMyFollowersQueryHookResult = ReturnType<typeof useFindMyFollowersQuery>;
|
||||||
|
export type FindMyFollowersLazyQueryHookResult = ReturnType<typeof useFindMyFollowersLazyQuery>;
|
||||||
|
export type FindMyFollowersSuspenseQueryHookResult = ReturnType<typeof useFindMyFollowersSuspenseQuery>;
|
||||||
|
export type FindMyFollowersQueryResult = Apollo.QueryResult<FindMyFollowersQuery, FindMyFollowersQueryVariables>;
|
||||||
|
export const FindMyFollowingsDocument = gql`
|
||||||
|
query FindMyFollowings {
|
||||||
|
findMyFollowings {
|
||||||
|
createdAt
|
||||||
|
followingId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useFindMyFollowingsQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useFindMyFollowingsQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useFindMyFollowingsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useFindMyFollowingsQuery({
|
||||||
|
* variables: {
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useFindMyFollowingsQuery(baseOptions?: Apollo.QueryHookOptions<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>(FindMyFollowingsDocument, options);
|
||||||
|
}
|
||||||
|
export function useFindMyFollowingsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>(FindMyFollowingsDocument, options);
|
||||||
|
}
|
||||||
|
export function useFindMyFollowingsSuspenseQuery(baseOptions?: Apollo.SkipToken | Apollo.SuspenseQueryHookOptions<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>) {
|
||||||
|
const options = baseOptions === Apollo.skipToken ? baseOptions : {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useSuspenseQuery<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>(FindMyFollowingsDocument, options);
|
||||||
|
}
|
||||||
|
export type FindMyFollowingsQueryHookResult = ReturnType<typeof useFindMyFollowingsQuery>;
|
||||||
|
export type FindMyFollowingsLazyQueryHookResult = ReturnType<typeof useFindMyFollowingsLazyQuery>;
|
||||||
|
export type FindMyFollowingsSuspenseQueryHookResult = ReturnType<typeof useFindMyFollowingsSuspenseQuery>;
|
||||||
|
export type FindMyFollowingsQueryResult = Apollo.QueryResult<FindMyFollowingsQuery, FindMyFollowingsQueryVariables>;
|
||||||
export const FindCurrentSessionDocument = gql`
|
export const FindCurrentSessionDocument = gql`
|
||||||
query FindCurrentSession {
|
query FindCurrentSession {
|
||||||
findCurrentSession {
|
findCurrentSession {
|
||||||
|
|||||||
10
frontend/src/graphql/queries/follow/FindMyFollowers.graphql
Normal file
10
frontend/src/graphql/queries/follow/FindMyFollowers.graphql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
query FindMyFollowers {
|
||||||
|
findMyFollowers {
|
||||||
|
createdAt
|
||||||
|
follower {
|
||||||
|
name
|
||||||
|
avatar
|
||||||
|
isVerified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
query FindMyFollowings {
|
||||||
|
findMyFollowings {
|
||||||
|
createdAt
|
||||||
|
followingId
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2169,6 +2169,18 @@
|
|||||||
postcss "^8.4.41"
|
postcss "^8.4.41"
|
||||||
tailwindcss "4.1.11"
|
tailwindcss "4.1.11"
|
||||||
|
|
||||||
|
"@tanstack/react-table@8.21.3":
|
||||||
|
version "8.21.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.21.3.tgz#2c38c747a5731c1a07174fda764b9c2b1fb5e91b"
|
||||||
|
integrity sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==
|
||||||
|
dependencies:
|
||||||
|
"@tanstack/table-core" "8.21.3"
|
||||||
|
|
||||||
|
"@tanstack/table-core@8.21.3":
|
||||||
|
version "8.21.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.21.3.tgz#2977727d8fc8dfa079112d9f4d4c019110f1732c"
|
||||||
|
integrity sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==
|
||||||
|
|
||||||
"@theguild/federation-composition@^0.19.0":
|
"@theguild/federation-composition@^0.19.0":
|
||||||
version "0.19.1"
|
version "0.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/@theguild/federation-composition/-/federation-composition-0.19.1.tgz#b3907bfcbdbd69d4628a3b1270936615f56b904f"
|
resolved "https://registry.yarnpkg.com/@theguild/federation-composition/-/federation-composition-0.19.1.tgz#b3907bfcbdbd69d4628a3b1270936615f56b904f"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user