Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add skeletons for studio app #71

Merged
merged 5 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/studio/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@biolnk/studio",
"version": "0.7.0",
"version": "0.8.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand All @@ -22,6 +22,7 @@
"react-beautiful-dnd": "^13.1.0",
"react-dom": "17.0.2",
"react-hook-form": "^7.21.0",
"react-loading-skeleton": "^3.0.2",
"react-query": "^3.34.0",
"sharp": "^0.29.3",
"validator": "^13.7.0",
Expand Down
104 changes: 104 additions & 0 deletions apps/studio/src/components/account/AccountSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import Skeleton from "react-loading-skeleton";
import { AccountLayout } from "~/components/layouts";
import { Flex } from "@biolnk/ui";
import { FC } from "react";

const AccountSkeleton: FC = () => {
return (
<AccountLayout>
<section className="bg-mauve-50 rounded pt-4 pb-5 px-6 shadow-sm">
<Skeleton width={100} height={19} className="mb-2" />
<Skeleton width={220} height={15} />

<Flex className="mt-9 space-y-4" layout="vertical">
<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>

<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>

<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>
</Flex>
</section>

<section className="bg-mauve-50 rounded pt-4 pb-5 px-6 shadow-sm">
<div className="w-full h-0.5 bg-mauve-300 mb-7 mt-1" />
<Skeleton width={100} height={19} className="mb-2" />
<Skeleton width={220} height={15} />

<Flex className="mt-9 space-y-4" layout="vertical">
<Flex className="w-full" align="center">
<Skeleton circle width={20} height={20} />
<Skeleton containerClassName="ml-3" width={170} height={40} />
</Flex>

<Flex className="w-full" align="center">
<Skeleton circle width={20} height={20} />
<Skeleton containerClassName="ml-3" width={170} height={40} />
</Flex>

<Flex className="w-full" align="center">
<Skeleton circle width={20} height={20} />
<Skeleton containerClassName="ml-3" width={170} height={40} />
</Flex>
</Flex>

<Flex layout="vertical">
<div className="w-full h-0.5 bg-mauve-300 mt-9 mb-7" />

<Flex justify="between">
<Skeleton width={130} height={19} className="mb-2" />

<Skeleton width={70} height={34} className="!rounded-2xl" />
</Flex>

<Skeleton width={260} height={15} />
</Flex>

<Flex layout="vertical">
<div className="w-full h-0.5 bg-mauve-300 mt-7 mb-7" />

<Flex justify="between">
<Skeleton width={130} height={19} className="mb-2" />

<Skeleton width={70} height={34} className="!rounded-2xl" />
</Flex>

<Skeleton width={260} height={15} />
</Flex>
</section>

<section className="bg-mauve-50 rounded pt-4 pb-5 px-6 shadow-sm">
<div className="w-full h-0.5 bg-mauve-300 mb-7" />
<Skeleton width={100} height={19} className="mb-2" />
<Skeleton width={220} height={15} />

<Flex className="mt-9 space-y-4" layout="vertical">
<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>

<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>

<Flex className="w-full">
<Skeleton width={135} height={16} />
<Skeleton containerClassName="block w-full ml-20" height={37} />
</Flex>
</Flex>
</section>
</AccountLayout>
);
};

export default AccountSkeleton;
25 changes: 12 additions & 13 deletions apps/studio/src/components/account/GeneralSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ import { ACCOUNT_GENERAL_SCHEMA } from "~/data/validations";
import { FC } from "react";
import { AccountGeneralDto, PageWithMetadata } from "~/types";

const GeneralSection: FC<PageWithMetadata["user"]> = ({
id,
email,
full_name,
username,
}) => {
export interface GeneralSectionProps {
user: PageWithMetadata["user"] | null;
}

const GeneralSection: FC<GeneralSectionProps> = ({ user }) => {
const DEFAULT_FORM_VALUES: AccountGeneralDto = {
email: email,
full_name: full_name,
username: username,
email: user?.email,
full_name: user?.full_name,
username: user?.username,
};

const { authUser } = useSupabase();
Expand All @@ -35,10 +34,10 @@ const GeneralSection: FC<PageWithMetadata["user"]> = ({
const updateDto = {
full_name: formData.full_name,
} as AccountGeneralDto;
const setEmail = formData.email !== email;
const setEmail = formData.email !== user?.email;

// if curr username is different from new username -> add
if (formData.username !== username) {
if (formData.username !== user?.username) {
// check db to see if the new username doesn't already exist
const checkUsername = await doesUsernameExist(formData.username);

Expand All @@ -57,12 +56,12 @@ const GeneralSection: FC<PageWithMetadata["user"]> = ({

mutate({
data: updateDto,
userId: id,
userId: user?.id,
newEmail: setEmail ? formData.email : null,
});
};

const emailNotConfirmed = !!(authUser as any)?.new_email;
const emailNotConfirmed = !!authUser?.new_email;

return (
<section
Expand Down
14 changes: 7 additions & 7 deletions apps/studio/src/components/account/PreferenceSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface PreferenceSectionProps {
const PreferenceSection: FC<PreferenceSectionProps> = ({ page }) => {
const [domainPreference, setDomainPreference] = useState(page.user.page_link);

const username = page.user.username;
const username = page?.user.username;

const sensitiveToggle = useDisclosure({ defaultIsOpen: page.nsfw_content });
const supportToggle = useDisclosure({ defaultIsOpen: page.show_branding });
Expand All @@ -28,30 +28,30 @@ const PreferenceSection: FC<PreferenceSectionProps> = ({ page }) => {

// Update page link preference
useUpdateEffect(() => {
if (page.user.page_link !== domainPreference) {
if (page?.user.page_link !== domainPreference) {
updateUser.mutate({
data: { page_link: domainPreference },
userId: page.user.id,
userId: page?.user.id,
});
}
}, [domainPreference]);

// Update sensitive [nsfw_content] content
useUpdateEffect(() => {
if (sensitiveToggle.isOpen !== page.nsfw_content) {
if (sensitiveToggle.isOpen !== page?.nsfw_content) {
updatePage.mutate({
data: { nsfw_content: sensitiveToggle.isOpen },
userId: page.user.id,
userId: page?.user.id,
});
}
}, [sensitiveToggle.isOpen]);

// Update support [show_branding]
useUpdateEffect(() => {
if (supportToggle.isOpen !== page.show_branding) {
if (supportToggle.isOpen !== page?.show_branding) {
updatePage.mutate({
data: { show_branding: supportToggle.isOpen },
userId: page.user.id,
userId: page?.user.id,
});
}
}, [supportToggle.isOpen]);
Expand Down
10 changes: 7 additions & 3 deletions apps/studio/src/components/account/SecuritySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import { Routes } from "~/data/enums";
import { PageWithMetadata } from "~/types";
import { FC } from "react";

const SecuritySection: FC<PageWithMetadata["user"]> = ({ username }) => {
export interface SecuritySectionProps {
user: PageWithMetadata["user"] | null;
}

const SecuritySection: FC<SecuritySectionProps> = ({ user }) => {
const { mutateAsync, isLoading } = useDeleteUser();
const { session } = useSupabase();
const { replace } = useRouter();
Expand Down Expand Up @@ -45,8 +49,8 @@ const SecuritySection: FC<PageWithMetadata["user"]> = ({ username }) => {
message={
<p>
Are you sure you want to delete the account, including all the data
for <span className="font-medium">{username}</span> ? This action
cannot be undone!
for <span className="font-medium">{user?.username}</span> ? This
action cannot be undone!
</p>
}
/>
Expand Down
6 changes: 6 additions & 0 deletions apps/studio/src/components/account/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { default as AccountSkeleton } from "./AccountSkeleton";
export { default as ChangePasswordSection } from "./ChangePasswordSection";
export { default as GeneralSection } from "./GeneralSection";
export { default as PreferenceSection } from "./PreferenceSection";
export { default as SecuritySection } from "./SecuritySection";
export { default as SideNavigation } from "./SideNavigation";
77 changes: 44 additions & 33 deletions apps/studio/src/components/dashboard/LinkCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import {
BaseIcon,
Button,
Edit,
Eye,
Flex,
MoreVertical,
Tooltip,
Text,
Toggle,
Trash2,
ArrowUpLeft,
Eye,
} from "@biolnk/ui";
import { Link } from "~/types";

Expand Down Expand Up @@ -89,7 +91,7 @@ const LinkCard: FC<Link> = ({
{({ innerRef, draggableProps, dragHandleProps }, snapshot) => (
<Flex
as="li"
className="bg-white shadow-sm rounded border border-mauve-200"
className="bg-white shadow-sm rounded border border-mauve-200 !cursor-default"
ref={innerRef}
{...draggableProps}
{...dragHandleProps}
Expand Down Expand Up @@ -117,46 +119,55 @@ const LinkCard: FC<Link> = ({
{title}
</Text>

<Toggle
aria-label="Toggle visibility"
label="Toggle visibility"
checked={previewToggle.isOpen}
onCheckedChange={previewToggle.onToggle}
size="sm"
variant="blue"
/>
<Tooltip content="Preview Mode">
<Toggle
aria-label="Toggle visibility"
label="Toggle visibility"
checked={previewToggle.isOpen}
onCheckedChange={previewToggle.onToggle}
size="sm"
variant="blue"
/>
</Tooltip>
</Flex>
<Text as="p" variant="light" size="sm" className="truncate">
{url}
</Text>

<Flex className="mt-5" align="center" justify="between">
<div className="space-x-3">
<Button
aria-label="Edit"
icon={Edit}
variant="text"
noSpace
onClick={updateDialog.onOpen}
/>
<Button
aria-label="Delete"
icon={Trash2}
variant="text"
noSpace
onClick={deleteDialog.onOpen}
/>
<Tooltip content="Edit link">
<Button
aria-label="Edit"
icon={Edit}
variant="text"
noSpace
onClick={updateDialog.onOpen}
/>
</Tooltip>

<Tooltip content="Delete link">
<Button
aria-label="Delete"
icon={Trash2}
variant="text"
noSpace
onClick={deleteDialog.onOpen}
/>
</Tooltip>
</div>

<Flex
className="text-mauve-800 sm:mr-1 md:mr-0 lg:mr-1"
align="center"
>
<BaseIcon icon={Eye} size="lg" />
<span className="text-mauve-1000 ml-2.5">
{total_clicks}
</span>
</Flex>
<Tooltip content="Total link clicks">
<Flex
className="text-mauve-800 sm:mr-1 md:mr-0 lg:mr-1 cursor-help"
align="center"
>
<BaseIcon icon={Eye} size="lg" />
<span className="text-mauve-1000 ml-2.5">
{total_clicks}
</span>
</Flex>
</Tooltip>
</Flex>
</div>
</Flex>
Expand Down
12 changes: 9 additions & 3 deletions apps/studio/src/components/dashboard/LinkDraggableList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { FC, useState, memo } from "react";
import LinkCard from "~/components/dashboard/LinkCard";
import Skeleton from "react-loading-skeleton";
import EmptyShell from "../EmptyShell";
import useLinks from "~/utils/hooks/queries/useLinks";
import useReorderLink from "~/utils/hooks/mutations/useReorderLink";
import useSafeLayoutEffect from "~/utils/hooks/useSafeLayoutEffect";
import { DragDropContext, Droppable, DropResult } from "react-beautiful-dnd";
import { LinkCard } from "~/components/dashboard";
import { FilePlus } from "@biolnk/ui";
import { useAppContext } from "~/data/context";
import { getLinksWithOrder, reorderList } from "~/utils/misc/orderLinks";
Expand Down Expand Up @@ -34,9 +35,14 @@ const LinkDraggableList: FC = () => {
}
}, [links]);

/** @TODO Implement <Skeleton /> component */
if (isLoading) {
return <span>Skeleton loading</span>;
return (
<Skeleton
count={3}
height={136}
containerClassName="mt-2 block space-y-4"
/>
);
}

if (!isLoading && links.length < 1) {
Expand Down
Loading