feat(dashboard-v2): add node about public key needing configuration

This commit is contained in:
Michał Leszczyk 2022-03-25 12:44:09 +01:00
parent 9dd4b8eb17
commit 08bab146ec
No known key found for this signature in database
GPG Key ID: FA123CA8BAA2FBF4
5 changed files with 63 additions and 3 deletions

View File

@ -1,12 +1,16 @@
import dayjs from "dayjs"; import dayjs from "dayjs";
import cn from "classnames";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { Alert } from "../Alert"; import { Alert } from "../Alert";
import { Button } from "../Button"; import { Button } from "../Button";
import { AddSkylinkToAPIKeyForm } from "../forms/AddSkylinkToAPIKeyForm"; import { AddSkylinkToAPIKeyForm } from "../forms/AddSkylinkToAPIKeyForm";
import { CogIcon, TrashIcon } from "../Icons"; import { CogIcon, ImportantNoteIcon, TrashIcon } from "../Icons";
import { Modal } from "../Modal"; import { Modal } from "../Modal";
import { useAPIKeyEdit } from "./useAPIKeyEdit"; import { useAPIKeyEdit } from "./useAPIKeyEdit";
import { useAPIKeyRemoval } from "./useAPIKeyRemoval"; import { useAPIKeyRemoval } from "./useAPIKeyRemoval";
import { Tooltip } from "../Tooltip/Tooltip";
export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => { export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => {
const { id, name, createdAt, skylinks } = apiKey; const { id, name, createdAt, skylinks } = apiKey;
@ -49,9 +53,23 @@ export const APIKey = ({ apiKey, onRemoved, onEdited, onRemovalError }) => {
abortEdit(); abortEdit();
}, [abortEdit]); }, [abortEdit]);
const needsAttention = isPublic && skylinks?.length === 0;
return ( return (
<li className="grid grid-cols-2 sm:grid-cols-[1fr_repeat(2,_max-content)] py-6 sm:py-4 px-4 gap-x-8 bg-white odd:bg-palette-100/50"> <li
<span className="truncate col-span-2 sm:col-span-1">{name || id}</span> className={cn("grid grid-cols-2 sm:grid-cols-[1fr_repeat(2,_max-content)] py-6 sm:py-4 px-4 gap-x-8", {
"bg-red-100": needsAttention,
"bg-white odd:bg-palette-100/50": !needsAttention,
})}
>
<span className="col-span-2 sm:col-span-1 flex items-center">
<span className={cn("truncate", { "text-palette-300": !name })}>{name || "unnamed key"}</span>
{needsAttention && (
<Tooltip message="This key has no Skylinks configured.">
<ImportantNoteIcon className="text-error -mt-2" size={24} />
</Tooltip>
)}
</span>
<span className="col-span-2 my-4 border-t border-t-palette-200/50 sm:hidden" /> <span className="col-span-2 my-4 border-t border-t-palette-200/50 sm:hidden" />
<span className="text-palette-400">{dayjs(createdAt).format("MMM DD, YYYY")}</span> <span className="text-palette-400">{dayjs(createdAt).format("MMM DD, YYYY")}</span>
<span className="flex items-center justify-end"> <span className="flex items-center justify-end">

View File

@ -0,0 +1,11 @@
import { withIconProps } from "../withIconProps";
export const ImportantNoteIcon = withIconProps(({ size, ...props }) => (
<svg width={size} height={size} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" {...props}>
<g fill="none" fillRule="evenodd">
<g fill="currentColor" fillRule="nonzero">
<path d="M16.028 6c5.523 0 10 4.477 10 10s-4.477 10-10 10h-9c-.405.017-.78-.212-.95-.58-.156-.372-.074-.802.21-1.09l2-2C6.82 20.549 6.02 18.31 6.028 16c0-5.523 4.477-10 10-10zm3.05 2.607c-3.526-1.458-7.592-.222-9.71 2.953-2.119 3.174-1.7 7.403 1 10.1.189.185.296.436.3.7 0 .267-.109.523-.3.71l-.93.93h6.59c3.817-.003 7.1-2.701 7.841-6.445.742-3.744-1.264-7.49-4.79-8.948zM16.028 18c.552 0 1 .448 1 1s-.448 1-1 1-1-.448-1-1 .448-1 1-1zM17 12v5h-2v-5h2z" />
</g>
</g>
</svg>
));

View File

@ -14,3 +14,4 @@ export * from "./icons/CopyIcon";
export * from "./icons/ShareIcon"; export * from "./icons/ShareIcon";
export * from "./icons/SimpleUploadIcon"; export * from "./icons/SimpleUploadIcon";
export * from "./icons/TrashIcon"; export * from "./icons/TrashIcon";
export * from "./icons/ImportantNoteIcon";

View File

@ -0,0 +1,29 @@
import React, { Children, cloneElement, useState } from "react";
import styled, { keyframes } from "styled-components";
const fadeIn = keyframes`
0% { opacity: 0; }
100% { opacity: 1; }
`;
const Popper = styled.div.attrs({
className: `absolute left-full top-1/2 z-10 px-2 py-1 text-xs
bg-black/90 text-white rounded`,
})`
transform: translateY(-50%);
animation: ${fadeIn} 0.2s ease-in-out;
`;
export const Tooltip = ({ message, children, className }) => {
const [visible, setVisible] = useState(false);
const show = () => setVisible(true);
const hide = () => setVisible(false);
return (
<span className="relative" onMouseEnter={show} onMouseLeave={hide}>
{children}
{visible && <Popper className={className}>{message}</Popper>}
</span>
);
};

View File

@ -39,6 +39,7 @@ export const AddSkylinkToAPIKeyForm = ({ addSkylink }) => (
id="skylink" id="skylink"
name="skylink" name="skylink"
label="New Skylink" label="New Skylink"
placeholder="Paste a new Skylink here"
error={errors.skylink} error={errors.skylink}
touched={touched.skylink} touched={touched.skylink}
/> />