diff --git a/front/packages/ui/src/admin/index.tsx b/front/packages/ui/src/admin/index.tsx index 32df5d89..be715d35 100644 --- a/front/packages/ui/src/admin/index.tsx +++ b/front/packages/ui/src/admin/index.tsx @@ -18,18 +18,123 @@ * along with Kyoo. If not, see . */ -import { QueryPage } from "@kyoo/models"; -import { P, ts } from "@kyoo/primitives"; -import { ScrollView } from "react-native"; +import { QueryIdentifier, QueryPage, User, UserP, queryFn } from "@kyoo/models"; +import { Alert, Avatar, Icon, IconButton, Menu, P, Skeleton, tooltip, ts } from "@kyoo/primitives"; +import { ScrollView, View } from "react-native"; import { DefaultLayout } from "../layout"; +import { SettingsContainer } from "../settings/base"; +import { useTranslation } from "react-i18next"; +import { InfiniteFetch } from "../fetch-infinite"; +import { Layout, WithLoading } from "../fetch"; +import { px, useYoshiki } from "yoshiki/native"; + +import UserI from "@material-symbols/svg-400/rounded/account_circle.svg"; +import Admin from "@material-symbols/svg-400/rounded/shield_person.svg"; +import MoreVert from "@material-symbols/svg-400/rounded/more_vert.svg"; +import Delete from "@material-symbols/svg-400/rounded/delete.svg"; +import { useQueryClient } from "@tanstack/react-query"; + +const UserGrid = ({ + isLoading, + slug, + username, + avatar, + isAdmin, + ...props +}: WithLoading<{ slug: string; username: string; avatar: string; isAdmin: boolean }>) => { + const { css } = useYoshiki(); + const { t } = useTranslation(); + const queryClient = useQueryClient(); + + return ( + + + + + +

{username}

+
+ + { + Alert.alert( + t("admin.users.delete"), + t("login.delete-confirmation"), + [ + { text: t("misc.cancel"), style: "cancel" }, + { + text: t("misc.delete"), + onPress: async () => { + await queryFn({ path: ["users", slug], method: "DELETE" }); + await queryClient.invalidateQueries({ queryKey: ["users"] }); + }, + style: "destructive", + }, + ], + { + cancelable: true, + icon: "warning", + }, + ); + }} + /> + +
+
+ ); +}; + +UserGrid.layout = { + size: px(150), + numColumns: { xs: 3, sm: 4, md: 5, lg: 6, xl: 8 }, + gap: { xs: ts(1), sm: ts(2), md: ts(4) }, + layout: "grid", +} satisfies Layout; + +const UserList = () => { + const { t } = useTranslation(); + + return ( + + + {(user) => ( + + )} + + + ); +}; + +UserList.query = (): QueryIdentifier => ({ + parser: UserP, + path: ["users"], + infinite: true, +}); export const AdminPage: QueryPage = () => { return ( -

hbgen

+
); }; AdminPage.getLayout = DefaultLayout; AdminPage.requiredPermissions = ["admin.read"]; + +AdminPage.getFetchUrls = () => [UserList.query()]; diff --git a/front/translations/en.json b/front/translations/en.json index 5192ad20..6c0c4a39 100644 --- a/front/translations/en.json +++ b/front/translations/en.json @@ -208,5 +208,13 @@ "size": "Size", "novideo": "No video", "nocontainer": "Invalid container" + }, + "admin": { + "users": { + "label": "Users", + "adminUser": "Admin", + "regularUser": "User", + "delete": "Delete user" + } } } diff --git a/front/translations/fr.json b/front/translations/fr.json index 4a5a6555..7cbe3b29 100644 --- a/front/translations/fr.json +++ b/front/translations/fr.json @@ -208,5 +208,13 @@ "size": "Taille", "novideo": "Pas de video", "nocontainer": "Conteneur invalide" + }, + "admin": { + "users": { + "label": "Comptes", + "adminUser": "Admin", + "regularUser": "Utilisateur", + "delete": "Supprimer l'utilisateur" + } } }