gluestick/src/components/Connection.tsx

79 lines
2.1 KiB
TypeScript

import React from "react";
import styles from "./Connection.module.css";
import classnames from "classnames";
import CheckIcon from "./icons/CheckIcon";
import { type AuthProviderState } from "@/auth/AuthProvider";
import { useRouter } from "next/navigation";
import unlink from "@/actions/unlink";
export default function Connection({
service,
unavailable = false,
authState,
icon
}: {
service: string;
unavailable?: boolean;
authState?: AuthProviderState;
icon?: () => JSX.Element;
}) {
const router = useRouter();
const holdTime = authState?.connected ? 3000 : 0;
const interval = React.useRef<NodeJS.Timeout | null>();
const execute = async () => {
const name = authState?.name;
if (!authState?.connected) {
router.push(`/oauth/${name?.toLowerCase()}/login`);
} else {
await unlink(name);
router.refresh();
}
};
const down = (e: React.MouseEvent | React.TouchEvent) => {
e.preventDefault();
interval.current = setTimeout(execute, holdTime);
};
const up = (e: React.MouseEvent | React.TouchEvent) => {
e.preventDefault();
if (interval.current) clearTimeout(interval.current);
};
return (
<button
type="button"
className={classnames(
styles.connection,
unavailable ? styles.unavailable : null,
!authState?.connected ? styles.disconnected : styles.progress
)}
disabled={unavailable}
onMouseDown={down}
onMouseUp={up}
onTouchStart={down}
onTouchEnd={up}
>
<div className={styles.iconContainer}>
{icon ? icon() : <span className={styles.dot}></span>}
</div>
<div className={styles.info}>
<div className={styles.serviceName}>{service}</div>
{authState?.connected !== false ? (
<div
className={styles.linkedIdentity}
title={
authState?.id ?? "This integration is currently unavailable."
}
>
{unavailable ? "Unavailable" : authState!.username}
</div>
) : null}
</div>
{authState?.connected && !unavailable ? <CheckIcon /> : null}
</button>
);
}