File size: 4,087 Bytes
ec4551b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 'use client';
import { FC, Fragment, useCallback } from 'react';
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
import useSWR from 'swr';
import { Button } from '@gitroom/react/form/button';
import { useToaster } from '@gitroom/react/toaster/toaster';
import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
import { useT } from '@gitroom/react/translation/get.transation.service.client';
const useApprovedApps = () => {
const fetch = useFetch();
const load = useCallback(async () => {
return (await fetch('/user/approved-apps')).json();
}, []);
return useSWR('approved-apps', load, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
revalidateIfStale: false,
});
};
export const ApprovedAppsComponent: FC = () => {
const fetch = useFetch();
const toaster = useToaster();
const t = useT();
const { data: apps, mutate } = useApprovedApps();
const revokeApp = useCallback(
(app: any) => async () => {
if (
await deleteDialog(
t(
'are_you_sure_revoke_access',
`Are you sure you want to revoke access for ${app.oauthApp?.name}?`,
{ name: app.oauthApp?.name }
)
)
) {
try {
await fetch(`/user/approved-apps/${app.id}`, {
method: 'DELETE',
});
toaster.show(
t('access_revoked', 'Access revoked successfully'),
'success'
);
mutate();
} catch {
toaster.show(t('failed_to_revoke', 'Failed to revoke access'), 'warning');
}
}
},
[]
);
if (apps === undefined) {
return null;
}
return (
<div className="flex flex-col gap-[20px]">
<div className="flex flex-col">
<h3 className="text-[20px]">
{t('approved_apps', 'Approved Apps')}
</h3>
<div className="text-customColor18 mt-[4px]">
{t(
'apps_you_have_authorized',
'Applications you have authorized to access your Postiz account.'
)}
</div>
</div>
<div className="bg-sixth border-fifth border rounded-[4px] p-[24px]">
{!apps?.length ? (
<div className="text-customColor18">
{t('no_approved_apps', 'No approved apps yet.')}
</div>
) : (
<div className="flex flex-col gap-[16px]">
{apps.map((app: any) => (
<div
key={app.id}
className="flex items-center justify-between p-[12px] border border-fifth rounded-[4px]"
>
<div className="flex items-center gap-[12px]">
{app.oauthApp?.picture?.path ? (
<img
src={app.oauthApp.picture.path}
alt={app.oauthApp.name}
className="w-[40px] h-[40px] rounded-full object-cover"
/>
) : (
<div className="w-[40px] h-[40px] rounded-full bg-fifth flex items-center justify-center text-customColor18">
{app.oauthApp?.name?.[0]?.toUpperCase() || '?'}
</div>
)}
<div>
<div className="text-[14px] font-bold">
{app.oauthApp?.name}
</div>
{app.oauthApp?.description && (
<div className="text-customColor18 text-[12px]">
{app.oauthApp.description}
</div>
)}
<div className="text-customColor18 text-[12px]">
{t('authorized_on', 'Authorized on')}{' '}
{new Date(app.createdAt).toLocaleDateString()}
</div>
</div>
</div>
<Button onClick={revokeApp(app)}>
{t('revoke', 'Revoke')}
</Button>
</div>
))}
</div>
)}
</div>
</div>
);
};
|