172 lines
4.9 KiB
TypeScript
172 lines
4.9 KiB
TypeScript
import { Input } from '@gitroom/react/form/input';
|
|
import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
|
|
import useSWR from 'swr';
|
|
import { useFetch } from '@gitroom/helpers/utils/custom.fetch';
|
|
import { useUser } from '@gitroom/frontend/components/layout/user.context';
|
|
import { Select } from '@gitroom/react/form/select';
|
|
import { pricing } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/pricing';
|
|
import { deleteDialog } from '@gitroom/react/helpers/delete.dialog';
|
|
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
|
import { setCookie } from '@gitroom/frontend/components/layout/layout.context';
|
|
|
|
export const Subscription = () => {
|
|
const fetch = useFetch();
|
|
const addSubscription: ChangeEventHandler<HTMLSelectElement> = useCallback(
|
|
async (e) => {
|
|
const value = e.target.value;
|
|
if (
|
|
await deleteDialog(
|
|
'Are you sure you want to add a user subscription?',
|
|
'Add'
|
|
)
|
|
) {
|
|
await fetch('/billing/add-subscription', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ subscription: value }),
|
|
});
|
|
|
|
window.location.reload();
|
|
}
|
|
},
|
|
[]
|
|
);
|
|
|
|
return (
|
|
<Select
|
|
onChange={addSubscription}
|
|
hideErrors={true}
|
|
disableForm={true}
|
|
name="sub"
|
|
label=""
|
|
value=""
|
|
className="text-black"
|
|
>
|
|
<option>-- ADD FREE SUBSCRIPTION --</option>
|
|
{Object.keys(pricing)
|
|
.filter((f) => !f.includes('FREE'))
|
|
.map((key) => (
|
|
<option key={key} value={key}>
|
|
{key}
|
|
</option>
|
|
))}
|
|
</Select>
|
|
);
|
|
};
|
|
export const Impersonate = () => {
|
|
const fetch = useFetch();
|
|
const [name, setName] = useState('');
|
|
const { isSecured } = useVariables();
|
|
const user = useUser();
|
|
|
|
const load = useCallback(async () => {
|
|
if (!name) {
|
|
return [];
|
|
}
|
|
|
|
const value = await (await fetch(`/user/impersonate?name=${name}`)).json();
|
|
return value;
|
|
}, [name]);
|
|
|
|
const stopImpersonating = useCallback(async () => {
|
|
if (!isSecured) {
|
|
setCookie('impersonate', '', -10);
|
|
} else {
|
|
await fetch(`/user/impersonate`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ id: '' }),
|
|
});
|
|
}
|
|
|
|
window.location.reload();
|
|
}, []);
|
|
|
|
const setUser = useCallback(
|
|
(userId: string) => async () => {
|
|
await fetch(`/user/impersonate`, {
|
|
method: 'POST',
|
|
body: JSON.stringify({ id: userId }),
|
|
});
|
|
|
|
window.location.reload();
|
|
},
|
|
[]
|
|
);
|
|
|
|
const { data } = useSWR(`/impersonate-${name}`, load, {
|
|
refreshWhenHidden: false,
|
|
revalidateOnMount: true,
|
|
revalidateOnReconnect: false,
|
|
revalidateOnFocus: false,
|
|
refreshWhenOffline: false,
|
|
revalidateIfStale: false,
|
|
refreshInterval: 0,
|
|
});
|
|
|
|
const mapData = useMemo(() => {
|
|
return data?.map(
|
|
(curr: any) => ({
|
|
id: curr.id,
|
|
name: curr.user.name,
|
|
email: curr.user.email,
|
|
}),
|
|
[]
|
|
);
|
|
}, [data]);
|
|
|
|
return (
|
|
<div>
|
|
<div className="bg-forth h-[52px] flex justify-center items-center border-input border rounded-[8px]">
|
|
<div className="relative flex flex-col w-[600px]">
|
|
<div className="relative z-[999]">
|
|
{user?.impersonate ? (
|
|
<div className="text-center flex justify-center items-center gap-[20px]">
|
|
<div>Currently Impersonating</div>
|
|
<div>
|
|
<div
|
|
className="px-[10px] rounded-[4px] bg-red-500 text-textColor cursor-pointer"
|
|
onClick={stopImpersonating}
|
|
>
|
|
X
|
|
</div>
|
|
</div>
|
|
{user?.tier?.current === 'FREE' && <Subscription />}
|
|
</div>
|
|
) : (
|
|
<Input
|
|
autoComplete="off"
|
|
placeholder="Write the user details"
|
|
name="impersonate"
|
|
disableForm={true}
|
|
label=""
|
|
removeError={true}
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
/>
|
|
)}
|
|
</div>
|
|
{!!data?.length && (
|
|
<>
|
|
<div
|
|
className="bg-primary/80 fixed left-0 top-0 w-full h-full z-[998]"
|
|
onClick={() => setName('')}
|
|
/>
|
|
<div className="absolute top-[100%] w-full left-0 bg-sixth border border-customColor6 text-textColor z-[999]">
|
|
{mapData?.map((user: any) => (
|
|
<div
|
|
onClick={setUser(user.id)}
|
|
key={user.id}
|
|
className="p-[10px] border-b border-customColor6 hover:bg-tableBorder cursor-pointer"
|
|
>
|
|
user: {user.id.split('-').at(-1)} - {user.name} -{' '}
|
|
{user.email}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|