added bottom nav, replaced png with svg integration icons, added subtitle to shell component

This commit is contained in:
Peer Richelsen 2021-08-02 16:10:24 +02:00
parent c16dd21a94
commit 64961cada1
37 changed files with 462 additions and 352 deletions

7
components/Logo.tsx Normal file
View File

@ -0,0 +1,7 @@
export default function Logo({small} : {small?: boolean}){
return <h1 className="brand-logo inline">
<strong>
<img className={small ? "h-4 w-auto" : "h-5 w-auto"} alt="Calendso" title="Calendso" src="/calendso-logo-white-word.svg" />
</strong>
</h1>;
}

View File

@ -1,4 +1,4 @@
import { Fragment, useState } from 'react'
import { Fragment } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { CheckIcon } from '@heroicons/react/outline'

View File

@ -18,7 +18,7 @@ export default function SettingsShell(props) {
];
return (
<div className="max-w-6xl mx-auto">
<div className="max-w-6xl">
<div>
<div className="sm:hidden">
<label htmlFor="tabs" className="sr-only">

View File

@ -1,22 +1,22 @@
import Link from "next/link";
import React, { Fragment, useEffect, useState } from "react";
import React, { Fragment, useEffect } from "react";
import { useRouter } from "next/router";
import { signOut, useSession } from "next-auth/client";
import { Dialog, Menu, Transition } from "@headlessui/react";
import { Menu, Transition } from "@headlessui/react";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../lib/telemetry";
import { MenuIcon, SelectorIcon, XIcon } from "@heroicons/react/outline";
import { SelectorIcon} from "@heroicons/react/outline";
import {
CalendarIcon,
ClockIcon,
CogIcon,
PuzzleIcon,
SupportIcon,
CogIcon,
ChatAltIcon,
LogoutIcon,
ExternalLinkIcon,
LinkIcon,
} from "@heroicons/react/solid";
import Logo from "./Logo";
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
@ -52,11 +52,14 @@ export default function Shell(props) {
icon: PuzzleIcon,
current: router.pathname.startsWith("/integrations"),
},
{ name: "Settings", href: "/settings", icon: CogIcon, current: router.pathname.startsWith("/settings") },
{
name: "Settings",
href: "/settings/profile",
icon: CogIcon,
current: router.pathname.startsWith("/settings"),
},
];
const [sidebarOpen, setSidebarOpen] = useState(false);
useEffect(() => {
telemetry.withJitsu((jitsu) => {
return jitsu.track(telemetryEventTypes.pageView, collectPageParameters(router.pathname));
@ -73,119 +76,14 @@ export default function Shell(props) {
return session ? (
<div className="h-screen flex overflow-hidden bg-gray-100">
<Transition.Root show={sidebarOpen} as={Fragment}>
<Dialog
as="div"
static
className="fixed inset-0 flex z-40 md:hidden"
open={sidebarOpen}
onClose={setSidebarOpen}>
<Transition.Child
as={Fragment}
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0">
<Dialog.Overlay className="fixed inset-0 bg-gray-600 bg-opacity-75" />
</Transition.Child>
<Transition.Child
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full">
<div className="relative flex-1 flex flex-col max-w-xs w-full bg-white">
<Transition.Child
as={Fragment}
enter="ease-in-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in-out duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0">
<div className="absolute top-0 right-0 -mr-12 pt-2">
<button
className="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
onClick={() => setSidebarOpen(false)}>
<span className="sr-only">Close sidebar</span>
<XIcon className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
</Transition.Child>
<div className="flex-1 h-0 pt-5 pb-4 overflow-y-auto">
<div className="flex-shrink-0 flex items-center px-4">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-logo-indigo-600-mark-gray-800-text.svg"
alt="Workflow"
/>
</div>
<nav className="mt-5 px-2 space-y-1">
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={classNames(
item.current
? "bg-gray-100 text-gray-900"
: "text-gray-600 hover:bg-gray-50 hover:text-gray-900",
"group flex items-center px-2 py-2 text-base font-medium rounded-md"
)}>
<item.icon
className={classNames(
item.current ? "text-gray-500" : "text-gray-400 group-hover:text-gray-500",
"mr-4 flex-shrink-0 h-6 w-6"
)}
aria-hidden="true"
/>
{item.name}
</a>
))}
</nav>
</div>
<div className="flex-shrink-0 flex border-t border-gray-200 p-4">
<a href="#" className="flex-shrink-0 group block">
<div className="flex items-center">
<div>
<img
className="inline-block h-10 w-10 rounded-full"
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
alt=""
/>
</div>
<div className="ml-3">
<p className="text-base font-medium text-gray-700 group-hover:text-gray-900">
Tom Cook
</p>
<p className="text-sm font-medium text-gray-500 group-hover:text-gray-700">
View profile
</p>
</div>
</div>
</a>
</div>
</div>
</Transition.Child>
<div className="flex-shrink-0 w-14">{/* Force sidebar to shrink to fit close icon */}</div>
</Dialog>
</Transition.Root>
{/* Static sidebar for desktop */}
<div className="hidden md:flex md:flex-shrink-0">
<div className="flex flex-col w-64">
{/* Sidebar component, swap this element with another sidebar if you like */}
<div className="flex flex-col h-0 flex-1 border-r border-gray-200 bg-white">
<div className="flex-1 flex flex-col pt-5 pb-4 overflow-y-auto">
<div className="flex items-center font-kollektif flex-shrink-0 px-4">
<h1 className="brand-logo font-kollektif inline">
<strong>
<img className="h-4 w-auto" alt="Calendso" title="Calendso" src="/calendso-logo-white-word.svg" />
</strong>
</h1>
<div className="flex items-center flex-shrink-0 px-4">
<Logo small />
</div>
<nav className="mt-5 flex-1 px-2 bg-white space-y-1">
{navigation.map((item) => (
@ -211,150 +109,214 @@ export default function Shell(props) {
</nav>
</div>
<div className="flex-shrink-0 flex border-t border-gray-200 p-4">
{/* User account dropdown */}
<Menu as="div" className="w-full relative inline-block text-left">
{({ open }) => (
<>
<div>
<Menu.Button className="group w-full rounded-md text-sm text-left font-medium text-gray-700 focus:outline-none">
<span className="flex w-full justify-between items-center">
<span className="flex min-w-0 items-center justify-between space-x-3">
<img
className="w-10 h-10 bg-gray-300 rounded-full flex-shrink-0"
src={
session.user.image
? session.user.image
: "https://eu.ui-avatars.com/api/?background=fff&color=039be5&name=" +
encodeURIComponent(session.user.name || "")
}
alt=""
/>
<span className="flex-1 flex flex-col min-w-0">
<span className="text-gray-900 text-sm font-medium truncate">
{session.user.name}
</span>
<span className="text-neutral-500 font-normal text-sm truncate">
{session.user.username}
</span>
</span>
</span>
<SelectorIcon
className="flex-shrink-0 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</span>
</Menu.Button>
</div>
<Transition
show={open}
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95">
<Menu.Items
static
className="w-64 z-10 origin-top absolute bottom-14 left-0 mt-1 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-200 focus:outline-none">
<div className="py-1">
<a
href={"/" + session.user.username}
className="flex px-4 py-2 text-sm text-neutral-500 pb-6">
View public page <ExternalLinkIcon className="ml-1 w-4 h-4 text-neutral-400" />
<span className="absolute top-8 text-neutral-900 font-medium">
{window.location.hostname}/bailey
</span>
</a>
</div>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-neutral-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<SupportIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Help
</a>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-neutral-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<ChatAltIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Feedback
</a>
)}
</Menu.Item>
</div>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<LogoutIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Sign out
</a>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</>
)}
</Menu>
<UserDropdown session={session} />
</div>
</div>
</div>
</div>
<div className="flex flex-col w-0 flex-1 overflow-hidden">
<div className="md:hidden pl-1 pt-1 sm:pl-3 sm:pt-3">
<button
className="-ml-0.5 -mt-0.5 h-12 w-12 inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
onClick={() => setSidebarOpen(true)}>
<span className="sr-only">Open sidebar</span>
<MenuIcon className="h-6 w-6" aria-hidden="true" />
</button>
</div>
{/* show top navigation for md and smaller (tablet and phones) */}
<nav className="md:hidden bg-white shadow p-4 flex justify-between items-center">
<Link href="/">
<a>
<Logo />
</a>
</Link>
<div className="flex gap-3 items-center self-center">
<button className="bg-white p-2 rounded-full text-gray-400 hover:text-gray-500 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<span className="sr-only">View notifications</span>
<Link href="/settings/profile">
<a>
<CogIcon className="h-6 w-6" aria-hidden="true" />
</a>
</Link>
</button>
<div className="mt-1">
<UserDropdown small bottom session={session} />
</div>
</div>
</nav>
<main className="flex-1 relative z-0 overflow-y-auto focus:outline-none">
<div className="py-6">
<div className="px-4 sm:px-6 md:px-8">
<h1 className="text-2xl font-kollektif font-semibold text-gray-900">{props.heading}</h1>
<div className="block sm:flex justify-between px-4 sm:px-6 md:px-8">
<div className="mb-6">
<h1 className="text-2xl font-semibold text-gray-900">{props.heading}</h1>
<p className="text-sm text-neutral-500 mr-4">{props.subtitle}</p>
</div>
<div className="mb-4 flex-shrink-0">{props.CTA}</div>
</div>
<div className="px-4 sm:px-6 md:px-8">{props.children}</div>
{/* add padding to content for mobile navigation*/}
<div className="block md:hidden pt-12" />
</div>
</main>
{/* show bottom navigation for md and smaller (tablet and phones) */}
<nav className="md:hidden flex fixed bottom-0 bg-white w-full rounded-lg shadow">
{/* note(PeerRich): using flatMap instead of map to remove settings from bottom nav */}
{navigation.flatMap((item, itemIdx) =>
item.name === "Settings" ? (
[]
) : (
<Link key={item.name} href={item.href}>
<a
className={classNames(
item.current ? "text-gray-900" : "text-neutral-400 hover:text-gray-700",
itemIdx === 0 ? "rounded-l-lg" : "",
itemIdx === navigation.length - 1 ? "rounded-r-lg" : "",
"group relative min-w-0 flex-1 overflow-hidden bg-white py-2 px-2 text-xs sm:text-sm font-medium text-center hover:bg-gray-50 focus:z-10"
)}
aria-current={item.current ? "page" : undefined}>
<item.icon
className={classNames(
item.current ? "text-gray-900" : "text-gray-400 group-hover:text-gray-500",
"block mx-auto flex-shrink-0 h-5 w-5 mb-1 text-center"
)}
aria-hidden="true"
/>
<span>{item.name}</span>
</a>
</Link>
)
)}
</nav>
</div>
</div>
) : null;
}
function UserDropdown({session, small, bottom} : {session: any, small?: boolean, bottom?: boolean}){
return (
<Menu as="div" className="w-full relative inline-block text-left">
{({ open }) => (
<>
<div>
<Menu.Button className="group w-full rounded-md text-sm text-left font-medium text-gray-700 focus:outline-none">
<span className="flex w-full justify-between items-center">
<span className="flex min-w-0 items-center justify-between space-x-3">
<img
className={classNames(
small ? "w-8 h-8" : "w-10 h-10",
"bg-gray-300 rounded-full flex-shrink-0"
)}
src={
session.user.image
? session.user.image
: "https://eu.ui-avatars.com/api/?background=fff&color=039be5&name=" +
encodeURIComponent(session.user.name || "")
}
alt=""
/>
{!small && (
<span className="flex-1 flex flex-col min-w-0">
<span className="text-gray-900 text-sm font-medium truncate">{session.user.name}</span>
<span className="text-neutral-500 font-normal text-sm truncate">
{session.user.username}
</span>
</span>
)}
</span>
{!small && (
<SelectorIcon
className="flex-shrink-0 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
)}
</span>
</Menu.Button>
</div>
<Transition
show={open}
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95">
<Menu.Items
static
className={classNames(
bottom ? "origin-top top-1 right-0" : "origin-bottom bottom-14 left-0",
"w-64 z-10 absolute mt-1 rounded-md shadow-lg bg-white ring-1 ring-black ring-opacity-5 divide-y divide-gray-200 focus:outline-none"
)}>
<div className="py-1">
<a
href={"/" + session.user.username}
className="flex px-4 py-2 text-sm text-neutral-500 pb-6">
View public page <ExternalLinkIcon className="ml-1 w-4 h-4 text-neutral-400" />
<span className="absolute top-8 text-neutral-900 font-medium">
{window.location.hostname}/bailey
</span>
</a>
</div>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-neutral-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<SupportIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Help
</a>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-neutral-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<ChatAltIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Feedback
</a>
)}
</Menu.Item>
</div>
<div className="py-1">
<Menu.Item>
{({ active }) => (
<a
href="#"
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-gray-700",
"flex px-4 py-2 text-sm font-medium"
)}>
<LogoutIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Sign out
</a>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</>
)}
</Menu>
);
}

View File

@ -1060,7 +1060,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, query
enabled: credentials.find((integration) => integration.type === "google_calendar") != null,
type: "google_calendar",
title: "Google Calendar",
imageSrc: "integrations/google-calendar.png",
imageSrc: "integrations/google-calendar.svg",
description: "For personal and business accounts",
},
{
@ -1068,7 +1068,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, query
type: "office365_calendar",
enabled: credentials.find((integration) => integration.type === "office365_calendar") != null,
title: "Office 365 / Outlook.com Calendar",
imageSrc: "integrations/office-365.png",
imageSrc: "integrations/outlook.svg",
description: "For personal and business accounts",
},
];

View File

@ -28,7 +28,7 @@ export default function Availability(props) {
const bufferMinsRef = useRef<HTMLInputElement>();
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
function toggleAddModal() {
@ -117,11 +117,11 @@ export default function Availability(props) {
<title>Availability | Calendso</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Shell heading="Availability">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">Configure times when you are available for bookings.</p>
</div>
<Shell
heading="Availability"
subtitle="Configure times when you are available for bookings.
">
<div className="flex">
<div className="w-1/2 mr-2 bg-white shadow rounded-sm">
<div className="px-4 py-5 sm:p-6">

View File

@ -14,7 +14,7 @@ export default function Troubleshoot({ user }) {
const [selectedDate, setSelectedDate] = useState(dayjs());
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
function convertMinsToHrsMins(mins) {
@ -56,25 +56,35 @@ export default function Troubleshoot({ user }) {
Understand why certain times are available and others are blocked.
</p>
</div>
<div className="bg-white overflow-hidden shadow rounded-sm">
<div className="bg-white max-w-md overflow-hidden shadow rounded-sm">
<div className="px-4 py-5 sm:p-6">
Here is an overview of your day on {selectedDate.format("D MMMM YYYY")}:
<small className="block text-neutral-400">Tip: Hover over the bold times for a full timestamp</small>
<small className="block text-neutral-400">
Tip: Hover over the bold times for a full timestamp
</small>
<div className="mt-4 space-y-4">
<div className="bg-neutral-600 overflow-hidden rounded-sm">
<div className="bg-black overflow-hidden rounded-sm">
<div className="px-4 sm:px-6 py-2 text-white">
Your day starts at {convertMinsToHrsMins(user.startTime)}
</div>
</div>
{availability.map((slot) => (
<div key={slot.start} className="bg-neutral-100 overflow-hidden rounded-sm">
<div className="px-4 py-5 sm:p-6 text-neutral-600">
Your calendar shows you as busy between <span className="font-medium text-neutral-800" title={slot.start}>{dayjs(slot.start).format("HH:mm")}</span> and <span className="font-medium text-neutral-800" title={slot.end}>{dayjs(slot.end).format("HH:mm")}</span> on {dayjs(slot.start).format("D MMMM YYYY")}
<div className="px-4 py-5 sm:p-6 text-black">
Your calendar shows you as busy between{" "}
<span className="font-medium text-neutral-800" title={slot.start}>
{dayjs(slot.start).format("HH:mm")}
</span>{" "}
and{" "}
<span className="font-medium text-neutral-800" title={slot.end}>
{dayjs(slot.end).format("HH:mm")}
</span>{" "}
on {dayjs(slot.start).format("D MMMM YYYY")}
</div>
</div>
))}
{availability.length === 0 && <div className="loader"></div>}
<div className="bg-neutral-600 overflow-hidden rounded-sm">
{availability.length === 0 && <div className="loader"><span className="loader-inner"></span></div>}
<div className="bg-black overflow-hidden rounded-sm">
<div className="px-4 sm:px-6 py-2 text-white">
Your day ends at {convertMinsToHrsMins(user.endTime)}
</div>

View File

@ -31,12 +31,7 @@ export default function Bookings({ bookings }) {
<title>Bookings | Calendso</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Shell heading="Bookings">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">
See upcoming and past events booked through your event type links.
</p>
</div>
<Shell heading="Bookings" subtitle="See upcoming and past events booked through your event type links.">
<div className="flex flex-col">
<div className="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
@ -67,7 +62,9 @@ export default function Bookings({ bookings }) {
"px-6 py-4 max-w-20 w-full" + (booking.rejected ? " line-through" : "")
}>
<div className="text-sm text-neutral-900 font-medium">{booking.title}</div>
<div className="text-sm text-neutral-500">You and {booking.attendees[0].name}</div>
<div className="text-sm text-neutral-500">
You and {booking.attendees[0].name}
</div>
</td>
{/* <td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-500">

View File

@ -1135,7 +1135,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, query
enabled: credentials.find((integration) => integration.type === "google_calendar") != null,
type: "google_calendar",
title: "Google Calendar",
imageSrc: "integrations/google-calendar.png",
imageSrc: "integrations/google-calendar.svg",
description: "For personal and business accounts",
},
{
@ -1143,7 +1143,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async ({ req, query
type: "office365_calendar",
enabled: credentials.find((integration) => integration.type === "office365_calendar") != null,
title: "Office 365 / Outlook.com Calendar",
imageSrc: "integrations/office-365.png",
imageSrc: "integrations/outlook.svg",
description: "For personal and business accounts",
},
];

View File

@ -65,7 +65,7 @@ export default function Availability({ user, types }) {
}
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
return (
@ -74,18 +74,17 @@ export default function Availability({ user, types }) {
<title>Event Types | Calendso</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<Shell heading="Event Types">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">
Create events to share for people to book on your calendar.
</p>
</div>
<button
onClick={toggleAddModal}
className="absolute top-8 right-8 flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
<PlusIcon className="w-5 h-5 mr-1" />
New event type
</button>
<Shell
heading="Event Types"
subtitle="Create events to share for people to book on your calendar."
CTA={
<button
onClick={toggleAddModal}
className="flex justify-center py-2 px-4 border border-transparent rounded-sm shadow-sm text-sm font-medium text-white bg-neutral-900 hover:bg-neutral-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-neutral-900">
<PlusIcon className="w-5 h-5 mr-1" />
New event type
</button>
}>
<div className="bg-white shadow overflow-hidden sm:rounded-sm">
<ul className="divide-y divide-neutral-200">
{types.map((type) => (

View File

@ -13,7 +13,7 @@ function classNames(...classes) {
export default function Home(props) {
const [session, loading] = useSession();
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
function convertMinsToHrsMins(mins) {
@ -227,19 +227,19 @@ export default function Home(props) {
{integration.type == "google_calendar" && (
<img
className="h-10 w-10 mr-2"
src="integrations/google-calendar.png"
src="integrations/google-calendar.svg"
alt="Google Calendar"
/>
)}
{integration.type == "office365_calendar" && (
<img
className="h-10 w-10 mr-2"
src="integrations/office-365.png"
src="integrations/outlook.svg"
alt="Office 365 / Outlook.com Calendar"
/>
)}
{integration.type == "zoom_video" && (
<img className="h-10 w-10 mr-2" src="integrations/zoom.png" alt="Zoom" />
<img className="h-10 w-10 mr-2" src="integrations/zoom.svg" alt="Zoom" />
)}
<div className="ml-3">
{integration.type == "office365_calendar" && (

View File

@ -12,7 +12,7 @@ export default function integration(props) {
const [showAPIKey, setShowAPIKey] = useState(false);
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
function toggleShowAPIKey() {

View File

@ -71,9 +71,9 @@ export default function Home({ integrations }) {
function getCalendarIntegrationImage(integrationType: string) {
switch (integrationType) {
case "google_calendar":
return "integrations/google-calendar.png";
return "integrations/google-calendar.svg";
case "office365_calendar":
return "integrations/office-365.png";
return "integrations/outlook.svg";
default:
return "";
}
@ -86,7 +86,7 @@ export default function Home({ integrations }) {
useEffect(loadCalendars, [integrations]);
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
return (
@ -96,10 +96,10 @@ export default function Home({ integrations }) {
<link rel="icon" href="/favicon.ico" />
</Head>
<Shell heading="Integrations" noPaddingBottom>
<div className="flex">
<p className="text-sm text-neutral-500">Connect your favourite apps.</p>
</div>
<Shell
heading="Integrations"
subtitle="Connect your favourite apps."
noPaddingBottom>
<div className="text-right py-2">
<button
onClick={toggleAddModal}
@ -434,7 +434,7 @@ export async function getServerSideProps(context) {
credential: credentials.find((integration) => integration.type === "google_calendar") || null,
type: "google_calendar",
title: "Google Calendar",
imageSrc: "integrations/google-calendar.png",
imageSrc: "integrations/google-calendar.svg",
description: "For personal and business calendars",
},
{
@ -442,7 +442,7 @@ export async function getServerSideProps(context) {
type: "office365_calendar",
credential: credentials.find((integration) => integration.type === "office365_calendar") || null,
title: "Office 365 / Outlook.com Calendar",
imageSrc: "integrations/office-365.png",
imageSrc: "integrations/outlook.svg",
description: "For personal and business calendars",
},
{
@ -450,7 +450,7 @@ export async function getServerSideProps(context) {
type: "zoom_video",
credential: credentials.find((integration) => integration.type === "zoom_video") || null,
title: "Zoom",
imageSrc: "integrations/zoom.png",
imageSrc: "integrations/zoom.svg",
description: "Video Conferencing",
},
];

View File

@ -8,33 +8,24 @@ export default function Billing(props) {
const [ session, loading ] = useSession();
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
return (
<Shell heading="Billing">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">
Manage your billing information and cancel your subscription.
</p>
</div>
<Shell heading="Billing" subtitle="Manage your billing information and cancel your subscription.">
<Head>
<title>Billing | Calendso</title>
</Head>
<SettingsShell>
<div className="py-6 lg:pb-8 lg:col-span-9">
<div className="mb-6">
<h2 className="text-lg leading-6 font-medium text-gray-900">
Change your Subscription
</h2>
<p className="mt-1 text-sm text-gray-500">
Cancel, update credit card or change plan
</p>
<h2 className="text-lg leading-6 font-medium text-gray-900">Change your Subscription</h2>
<p className="mt-1 text-sm text-gray-500">Cancel, update credit card or change plan</p>
</div>
<div className="my-6">
<iframe
src="https://calendso.com/subscription-embed"
style={{minHeight: 800, width: "100%", border: 0 }}
style={{ minHeight: 800, width: "100%", border: 0 }}
/>
</div>
</div>

View File

@ -3,26 +3,20 @@ import Link from "next/link";
import { useState } from "react";
import { useRouter } from "next/router";
import prisma from "../../lib/prisma";
import Modal from "../../components/Modal";
import Shell from "../../components/Shell";
import SettingsShell from "../../components/Settings";
import Avatar from "../../components/Avatar";
import { signIn, useSession, getSession } from "next-auth/client";
import TimezoneSelect from "react-timezone-select";
import { useSession, getSession } from "next-auth/client";
export default function Embed(props) {
const [session, loading] = useSession();
const router = useRouter();
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
return (
<Shell heading="Embed">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">Integrate with your website using our embed options.</p>
</div>
<Shell heading="Embed" subtitle="Integrate with your website using our embed options.">
<Head>
<title>Embed | Calendso</title>
<link rel="icon" href="/favicon.ico" />
@ -30,7 +24,7 @@ export default function Embed(props) {
<SettingsShell>
<div className="py-6 lg:pb-8 lg:col-span-9">
<div className="mb-6">
<h2 className="text-lg leading-6 font-medium text-gray-900">Iframe Embed</h2>
<h2 className="text-lg leading-6 font-medium text-gray-900">iframe Embed</h2>
<p className="mt-1 text-sm text-gray-500">The easiest way to embed Calendso on your website.</p>
</div>
<div className="grid grid-cols-2 space-x-4">

View File

@ -14,7 +14,7 @@ export default function Settings(props) {
const newPasswordRef = useRef<HTMLInputElement>();
if (loading) {
return <div className="loader"></div>;
return <div className="loader"><span className="loader-inner"></span></div>;
}
const closeSuccessModal = () => {
@ -41,10 +41,7 @@ export default function Settings(props) {
}
return (
<Shell heading="Password">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">Change the password that you use to sign in.</p>
</div>
<Shell heading="Password" subtitle="Change the password that you use to sign in.">
<Head>
<title>Change Password | Calendso</title>
<link rel="icon" href="/favicon.ico" />

View File

@ -90,12 +90,7 @@ export default function Settings(props) {
}
return (
<Shell heading="Profile">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">
Edit your profile information, which shows on your scheduling link.
</p>
</div>
<Shell heading="Profile" subtitle="Edit your profile information, which shows on your scheduling link.">
<Head>
<title>Profile | Calendso</title>
<link rel="icon" href="/favicon.ico" />

View File

@ -57,12 +57,7 @@ export default function Teams() {
};
return (
<Shell heading="Teams">
<div className="flex mb-8">
<p className="text-sm text-neutral-500">
Create and manage teams to use collaborative features.
</p>
</div>
<Shell heading="Teams" subtitle="Create and manage teams to use collaborative features.">
<Head>
<title>Teams | Calendso</title>
<link rel="icon" href="/favicon.ico" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 29.2 33" style="enable-background:new 0 0 29.2 33;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F68D2E;}
</style>
<path class="st0" d="M27.2,18.5c-1.5-0.9-3.3-0.8-4.7,0.2c-0.3,0.2-0.6,0.2-0.9,0l-4.2-2.4c-0.1,0-0.1-0.1,0-0.1c0,0,0,0,0,0
l4.2-2.4c0.3-0.2,0.7-0.1,0.9,0.1c1.4,1,3.2,1.1,4.7,0.2c1.9-1.2,2.6-3.7,1.5-5.7c-1.1-2.1-3.7-2.8-5.8-1.7
c-1.5,0.8-2.4,2.4-2.2,4.1c0,0.3-0.1,0.7-0.4,0.8L16,13.9c-0.1,0-0.1,0-0.1,0c0,0,0,0,0-0.1V8.9c0-0.3,0.2-0.6,0.5-0.8
c2.1-1,3.1-3.5,2.1-5.7S15-0.6,12.8,0.4S9.7,3.9,10.7,6c0.4,0.9,1.2,1.7,2.1,2.1c0.3,0.1,0.5,0.4,0.5,0.8v4.9c0,0.1,0,0.1-0.1,0.1
c0,0,0,0-0.1,0l-4.2-2.4c-0.3-0.2-0.5-0.5-0.4-0.8C8.7,8.3,7,6.2,4.6,6S0.2,7.6,0,9.9s1.5,4.4,3.9,4.6c1,0.1,2-0.2,2.9-0.8
c0.3-0.2,0.6-0.2,0.9-0.1l4.2,2.4c0.1,0,0.1,0.1,0,0.1c0,0,0,0,0,0l-4.2,2.4c-0.3,0.2-0.7,0.1-0.9,0c-1.4-1-3.2-1-4.7-0.2
c-1.9,1.2-2.6,3.7-1.5,5.7c1.1,2.1,3.7,2.8,5.8,1.7c1.5-0.8,2.4-2.4,2.2-4.1c0-0.3,0.1-0.7,0.4-0.8l4.2-2.4c0.1,0,0.1,0,0.1,0
c0,0,0,0,0,0.1v4.9c0,0.3-0.2,0.6-0.5,0.8c-2.1,1-3.1,3.5-2.1,5.7s3.5,3.1,5.7,2.1c2.1-1,3.1-3.5,2.1-5.7c-0.4-0.9-1.2-1.7-2.1-2.1
c-0.3-0.1-0.5-0.4-0.5-0.8v-4.9c0-0.1,0-0.1,0.1-0.1c0,0,0,0,0.1,0l4.2,2.4c0.3,0.2,0.5,0.5,0.4,0.8c-0.2,2.3,1.5,4.4,3.9,4.6
c1.7,0.2,3.3-0.7,4.1-2.2C29.8,22.2,29.1,19.7,27.2,18.5L27.2,18.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="186 38 76 76"><path fill="#fff" d="M244 56h-40v40h40V56z"/><path fill="#EA4335" d="M244 114l18-18h-18v18z"/><path fill="#FBBC04" d="M262 56h-18v40h18V56z"/><path fill="#34A853" d="M244 96h-40v18h40V96z"/><path fill="#188038" d="M186 96v12c0 3.315 2.685 6 6 6h12V96h-18z"/><path fill="#1967D2" d="M262 56V44c0-3.315-2.685-6-6-6h-12v18h18z"/><path fill="#4285F4" d="M244 38h-52c-3.315 0 -6 2.685-6 6v52h18V56h40V38z"/><path fill="#4285F4" d="M212.205 87.03c-1.495-1.01-2.53-2.485-3.095-4.435l3.47-1.43c.315 1.2.865 2.13 1.65 2.79.78.66 1.73.985 2.84.985 1.135 0 2.11-.345 2.925-1.035s1.225-1.57 1.225-2.635c0-1.09-.43-1.98-1.29-2.67-.86-.69-1.94-1.035-3.23-1.035h-2.005V74.13h1.8c1.11 0 2.045-.3 2.805-.9.76-.6 1.14-1.42 1.14-2.465 0 -.93-.34-1.67-1.02-2.225-.68-.555-1.54-.835-2.585-.835-1.02 0 -1.83.27-2.43.815a4.784 4.784 0 0 0 -1.31 2.005l-3.435-1.43c.455-1.29 1.29-2.43 2.515-3.415 1.225-.985 2.79-1.48 4.69-1.48 1.405 0 2.67.27 3.79.815 1.12.545 2 1.3 2.635 2.26.635.965.95 2.045.95 3.245 0 1.225-.295 2.26-.885 3.11-.59.85-1.315 1.5-2.175 1.955v.205a6.605 6.605 0 0 1 2.79 2.175c.725.975 1.09 2.14 1.09 3.5 0 1.36-.345 2.575-1.035 3.64s-1.645 1.905-2.855 2.515c-1.215.61-2.58.92-4.095.92-1.755.005-3.375-.5-4.87-1.51zM233.52 69.81l-3.81 2.755-1.905-2.89 6.835-4.93h2.62V88h-3.74V69.81z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" id="Livello_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2228.833 2073.333"
enable-background="new 0 0 2228.833 2073.333" xml:space="preserve">
<metadata>
<sfw xmlns="&ns_sfw;">
<slices></slices>
<sliceSourceBounds bottomLeftOrigin="true" height="2073.333" width="2228.833" x="-1116.333" y="-1012.667">
</sliceSourceBounds>
</sfw>
</metadata>
<path fill="#5059C9" d="M1554.637,777.5h575.713c54.391,0,98.483,44.092,98.483,98.483c0,0,0,0,0,0v524.398
c0,199.901-162.051,361.952-361.952,361.952h0h-1.711c-199.901,0.028-361.975-162-362.004-361.901c0-0.017,0-0.034,0-0.052V828.971
C1503.167,800.544,1526.211,777.5,1554.637,777.5L1554.637,777.5z"/>
<circle fill="#5059C9" cx="1943.75" cy="440.583" r="233.25"/>
<circle fill="#7B83EB" cx="1218.083" cy="336.917" r="336.917"/>
<path fill="#7B83EB" d="M1667.323,777.5H717.01c-53.743,1.33-96.257,45.931-95.01,99.676v598.105
c-7.505,322.519,247.657,590.16,570.167,598.053c322.51-7.893,577.671-275.534,570.167-598.053V877.176
C1763.579,823.431,1721.066,778.83,1667.323,777.5z"/>
<path opacity="0.1" enable-background="new " d="M1244,777.5v838.145c-0.258,38.435-23.549,72.964-59.09,87.598
c-11.316,4.787-23.478,7.254-35.765,7.257H667.613c-6.738-17.105-12.958-34.21-18.142-51.833
c-18.144-59.477-27.402-121.307-27.472-183.49V877.02c-1.246-53.659,41.198-98.19,94.855-99.52H1244z"/>
<path opacity="0.2" enable-background="new " d="M1192.167,777.5v889.978c-0.002,12.287-2.47,24.449-7.257,35.765
c-14.634,35.541-49.163,58.833-87.598,59.09H691.975c-8.812-17.105-17.105-34.21-24.362-51.833
c-7.257-17.623-12.958-34.21-18.142-51.833c-18.144-59.476-27.402-121.307-27.472-183.49V877.02
c-1.246-53.659,41.198-98.19,94.855-99.52H1192.167z"/>
<path opacity="0.2" enable-background="new " d="M1192.167,777.5v786.312c-0.395,52.223-42.632,94.46-94.855,94.855h-447.84
c-18.144-59.476-27.402-121.307-27.472-183.49V877.02c-1.246-53.659,41.198-98.19,94.855-99.52H1192.167z"/>
<path opacity="0.2" enable-background="new " d="M1140.333,777.5v786.312c-0.395,52.223-42.632,94.46-94.855,94.855H649.472
c-18.144-59.476-27.402-121.307-27.472-183.49V877.02c-1.246-53.659,41.198-98.19,94.855-99.52H1140.333z"/>
<path opacity="0.1" enable-background="new " d="M1244,509.522v163.275c-8.812,0.518-17.105,1.037-25.917,1.037
c-8.812,0-17.105-0.518-25.917-1.037c-17.496-1.161-34.848-3.937-51.833-8.293c-104.963-24.857-191.679-98.469-233.25-198.003
c-7.153-16.715-12.706-34.071-16.587-51.833h258.648C1201.449,414.866,1243.801,457.217,1244,509.522z"/>
<path opacity="0.2" enable-background="new " d="M1192.167,561.355v111.442c-17.496-1.161-34.848-3.937-51.833-8.293
c-104.963-24.857-191.679-98.469-233.25-198.003h190.228C1149.616,466.699,1191.968,509.051,1192.167,561.355z"/>
<path opacity="0.2" enable-background="new " d="M1192.167,561.355v111.442c-17.496-1.161-34.848-3.937-51.833-8.293
c-104.963-24.857-191.679-98.469-233.25-198.003h190.228C1149.616,466.699,1191.968,509.051,1192.167,561.355z"/>
<path opacity="0.2" enable-background="new " d="M1140.333,561.355v103.148c-104.963-24.857-191.679-98.469-233.25-198.003
h138.395C1097.783,466.699,1140.134,509.051,1140.333,561.355z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="198.099" y1="1683.0726" x2="942.2344" y2="394.2607" gradientTransform="matrix(1 0 0 -1 0 2075.3333)">
<stop offset="0" style="stop-color:#5A62C3"/>
<stop offset="0.5" style="stop-color:#4D55BD"/>
<stop offset="1" style="stop-color:#3940AB"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M95.01,466.5h950.312c52.473,0,95.01,42.538,95.01,95.01v950.312c0,52.473-42.538,95.01-95.01,95.01
H95.01c-52.473,0-95.01-42.538-95.01-95.01V561.51C0,509.038,42.538,466.5,95.01,466.5z"/>
<path fill="#FFFFFF" d="M820.211,828.193H630.241v517.297H509.211V828.193H320.123V727.844h500.088V828.193z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,36 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="17 34 127 113">
<defs>
<linearGradient id="a" x1="28.286" y1="53.757" x2="70.714" y2="127.243" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#1784d9"/>
<stop offset="0.5" stop-color="#107ad5"/>
<stop offset="1" stop-color="#0a63c9"/>
</linearGradient>
</defs>
<path d="M143.984,93.02a1.813,1.813,0,0,1-.07.52,1.055,1.055,0,0,1-.06.24c.01.01,0,.02-.01.03a.9.9,0,0,1-.079.21,2.1,2.1,0,0,1-.15.3,2.5,2.5,0,0,1-1.059,1.05l-4.636,2.62-.4.23L132.584,101l-1.139.64-21.5,12.16-.419.24-8.193,4.63-1.019.57-1.009.57-.51.29c-.17.09-.349.19-.529.29-.02.01-.03.02-.05.03a4.689,4.689,0,0,1-1.169.43h-.01a5.834,5.834,0,0,1-1.509.19,5.973,5.973,0,0,1-2.7-.62c-.14-.08-.28-.16-.42-.23-.05-.03-.1-.06-.16-.09l-6.414-3.63-.869-.49-.62-.35-.13-.07-.469-.27-.07-.04-.21-.12-.15-.09-.16-.09-.2-.11-.239-.13-.12-.07-.03-.02-.32-.18-.28-.16-.08-.04-.359-.2L63.416,103.8,59.6,101.64,58.46,101l-4.936-2.78L53,97.92l-4.506-2.55a2.546,2.546,0,0,1-1.059-1.05,2.233,2.233,0,0,1-.15-.31l-.21-.99a2.645,2.645,0,0,1,1.329-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13l.529-.3L74.845,75.78,76.224,75l5.306-2.99.359-.21.08-.04.28-.16.32-.18.03-.02.12-.07.239-.13.2-.11.16-.09.15-.08.21-.12.07-.04.469-.27.13-.07.62-.35.869-.5,6.414-3.62c.2-.11.39-.22.58-.32a6.069,6.069,0,0,1,5.385,0c.2.1.389.21.579.32l10.731,6.06,6.674,3.77L137.52,87.83l.4.23,4.636,2.61c.03,0,.05.02.07.02l.02.03A2.633,2.633,0,0,1,143.984,93.02Z" fill="#123b6d"/>
<polygon points="110 49 82 49 82 75 110 101 138 101 138 75 110 49" fill="#28a8ea"/>
<path d="M110,101v26H82l-.5-.42-.07-.06v-.01l-.09-.08-.18-.15-.34-.29-.03-.02-.44-.38-.01-.01-.11-.09-.05-.04-.05-.05-.59-.5h-.01l-.12-.11-.08-.07-.05-.04-.12-.1-.3-.25-.6-.49L54,103.99l-1-.82V75H82l.6.56.15.14.44.41.31.28.28.26.47.44.13.12.62.58Z" fill="#0364b8"/>
<rect x="54" y="101" width="28" height="26" fill="#14447d"/>
<rect x="110" y="101" width="28" height="26" fill="#0078d4"/>
<rect x="110" y="49" width="28" height="26" fill="#50d9ff"/>
<rect x="53" y="49" width="29" height="26" fill="#0078d4"/>
<rect x="82" y="75" width="28" height="26" fill="#0078d4"/>
<path d="M58.38,34h74.24A5.38,5.38,0,0,1,138,39.38V49a0,0,0,0,1,0,0H53a0,0,0,0,1,0,0V39.38A5.38,5.38,0,0,1,58.38,34Z" fill="#0358a7"/>
<path d="M138,93.829,96.942,116.108l-.192.111a1.94,1.94,0,0,1-.2.107c-.074.035-.151.066-.227.093l-1.34-.751-.167-.089c-.08-.04-.161-.082-.237-.13l-.1-.062-8.132-4.52-.664-.375-.545-.3-1.2-.675L53,92.318v32.259h85Z" fill="#0a2767" opacity="0.1"/>
<path d="M138,94.829,96.942,117.108l-.192.111a1.94,1.94,0,0,1-.2.107c-.074.035-.151.066-.227.093l-1.34-.751-.167-.089c-.08-.04-.161-.082-.237-.13l-.1-.062-8.132-4.52-.664-.375-.545-.3-1.2-.675L53,93.318v32.259h85Z" fill="#0a2767" opacity="0.1"/>
<path d="M138,95.829,96.942,118.108l-.192.111a1.94,1.94,0,0,1-.2.107c-.074.035-.151.066-.227.093l-1.34-.751-.167-.089c-.08-.04-.161-.082-.237-.13l-.1-.062-8.132-4.52-.664-.375-.545-.3-1.2-.675L53,94.318v32.259h85Z" fill="#0a2767" opacity="0.1"/>
<path d="M138,96.829,96.942,119.108l-.192.111a1.94,1.94,0,0,1-.2.107c-.074.035-.151.066-.227.093l-1.34-.751-.167-.089c-.08-.04-.161-.082-.237-.13l-.1-.062-8.132-4.52-.664-.375-.545-.3-1.2-.675L53,95.318v32.259h85Z" fill="#0a2767" opacity="0.1"/>
<path d="M142.641,95.242v0l-.054.029-.013.008-43.8,23.765a6.019,6.019,0,0,1-.587.319h0a6.331,6.331,0,0,1-5.389,0h0a6.138,6.138,0,0,1-.587-.319l2.061,14.818,43.658,13.047a6.235,6.235,0,0,0,3.564-1.1,5.686,5.686,0,0,0,2.5-4.671V93.022A2.542,2.542,0,0,1,142.641,95.242Z" fill="#1490df"/>
<path d="M100.479,118.163l-1.629.883a6.261,6.261,0,0,1-.587.319h0a6.329,6.329,0,0,1-5.388,0h0a6.261,6.261,0,0,1-.587-.319l2.061,14.818,43.658,13.047a6.241,6.241,0,0,0,3.565-1.1,5.773,5.773,0,0,0,2.339-3.356Z" opacity="0.05"/>
<path d="M143.578,143.412,99.439,118.727l-.589.319a6.261,6.261,0,0,1-.587.319h0a6.329,6.329,0,0,1-5.388,0h0a6.261,6.261,0,0,1-.587-.319l2.061,14.818,43.658,13.047a6.241,6.241,0,0,0,3.565-1.1A5.851,5.851,0,0,0,143.578,143.412Z" opacity="0.05"/>
<path d="M143.088,144.284,98.406,119.3l-.143.07h0a6.329,6.329,0,0,1-5.388,0h0a6.261,6.261,0,0,1-.587-.319l2.061,14.818,43.658,13.047a6.241,6.241,0,0,0,3.565-1.1A5.943,5.943,0,0,0,143.088,144.284Z" opacity="0.05"/>
<path d="M142.444,145.069,97.578,119.977l-.223-.119-.176-.1a6.334,6.334,0,0,1-4.305-.394h0a6.261,6.261,0,0,1-.587-.319l2.061,14.818,43.658,13.047a6.241,6.241,0,0,0,3.565-1.1A6.015,6.015,0,0,0,142.444,145.069Z" opacity="0.05"/>
<path d="M141.63,145.76c-.13.09-.26.18-.39.26s-.27.15-.41.22c-.16.08-.32.15-.48.22-.01,0-.02.01-.03.01q-.27.1-.54.18a3.3,3.3,0,0,1-.62.15.7.7,0,0,1-.14.03c-.11.02-.22.03-.34.04a4.632,4.632,0,0,1-.65.04H53.15a6.01,6.01,0,0,1-6.08-5.94V93.02l1.38.77.02.01c.01.01.01.01.02.01L53,96.32,61.42,101,82,112.44l.6.34.15.08.44.25.31.17.28.15.47.27.13.07.62.34,7.44,4.14c.19.12.39.23.59.33l2.48,1.39,1.57.88h.01l6.67,3.73,1.79,1,1.79,1,.75.42,1.04.58Z" fill="#28a8ea"/>
<path d="M85,63v59.62a5.337,5.337,0,0,1-.37,1.96,5.272,5.272,0,0,1-.52,1,4.839,4.839,0,0,1-.86,1,5.173,5.173,0,0,1-.51.42,5.462,5.462,0,0,1-1.03.58,5.378,5.378,0,0,1-2.09.42H47v-4h.07V93.02a2.644,2.644,0,0,1,1.33-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13V57H79.62a4.547,4.547,0,0,1,2.38.69A6.374,6.374,0,0,1,85,63Z" opacity="0.05"/>
<path d="M84.25,63.1v58.52a5.432,5.432,0,0,1-.86,2.96,4.746,4.746,0,0,1-.84,1,3.379,3.379,0,0,1-.55.45,3.747,3.747,0,0,1-.66.4c-.1.06-.2.1-.3.15a5.292,5.292,0,0,1-2.08.42H47v-3h.07V93.02a2.644,2.644,0,0,1,1.33-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13V57.25H78.87A4.942,4.942,0,0,1,82,58.42,6.149,6.149,0,0,1,84.25,63.1Z" opacity="0.075"/>
<path d="M83.5,63.19v57.43a5.45,5.45,0,0,1-1.5,3.82,1.92,1.92,0,0,1-.15.14,4.911,4.911,0,0,1-1.47,1c-.01,0-.02.01-.03.01a5.268,5.268,0,0,1-2.04.41H47v-2h.07V93.02a2.644,2.644,0,0,1,1.33-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13V57.5H78.12A5.21,5.21,0,0,1,82,59.32,5.846,5.846,0,0,1,83.5,63.19Z" opacity="0.1"/>
<path d="M82.75,63.28v56.34a5.735,5.735,0,0,1-.75,2.87,4.989,4.989,0,0,1-2.29,2.09c-.12.05-.25.1-.38.14a5.088,5.088,0,0,1-1.67.28H47v-1h.07V93.02a2.644,2.644,0,0,1,1.33-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13V57.75H77.37A5.373,5.373,0,0,1,82,60.51,5.5,5.5,0,0,1,82.75,63.28Z" opacity="0.125"/>
<path d="M82,63.38v55.24a5.158,5.158,0,0,1-3.74,5.22A4.731,4.731,0,0,1,77,124H47.07V93.02a2.644,2.644,0,0,1,1.33-2.3l.03-.03c.02,0,.04-.02.06-.02L53,88.13V58H76.62A5.382,5.382,0,0,1,82,63.38Z" opacity="0.2"/>
<rect x="17" y="58" width="65" height="65" rx="5.38" fill="url(#a)"/>
<path d="M35.041,81.643A14.637,14.637,0,0,1,40.785,75.3a17.366,17.366,0,0,1,9.128-2.287,16.154,16.154,0,0,1,8.444,2.169,14.489,14.489,0,0,1,5.59,6.062,19.581,19.581,0,0,1,1.958,8.916,20.653,20.653,0,0,1-2.017,9.329,14.837,14.837,0,0,1-5.755,6.274,16.788,16.788,0,0,1-8.763,2.228,16.542,16.542,0,0,1-8.632-2.193,14.705,14.705,0,0,1-5.661-6.074A19.091,19.091,0,0,1,33.1,90.913,21.187,21.187,0,0,1,35.041,81.643Zm6.121,14.895a9.5,9.5,0,0,0,3.231,4.175,8.44,8.44,0,0,0,5.048,1.521,8.862,8.862,0,0,0,5.39-1.568,9.107,9.107,0,0,0,3.137-4.187,16.181,16.181,0,0,0,1-5.826,17.723,17.723,0,0,0-.943-5.9A9.345,9.345,0,0,0,55,80.417a8.35,8.35,0,0,0-5.343-1.651A8.718,8.718,0,0,0,44.488,80.3a9.576,9.576,0,0,0-3.3,4.21,16.71,16.71,0,0,0-.024,12.029Z" fill="#fff"/>
<rect width="180" height="180" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M63.207 26.418H44.432l13.193-13.193c-1.015-1.522-2.03-2.537-3.045-4.06a29.025 29.025 0 0 1-4.059-3.552L37.33 18.807V.54a17.252 17.252 0 0 0-5.074-.507A15.629 15.629 0 0 0 27.18.54v18.775l-13.7-13.7A13.7 13.7 0 0 0 9.42 9.166c-1.015 1.522-2.537 2.537-3.552 4.06L19.06 26.418H.794l-.507 5.074a15.629 15.629 0 0 0 .507 5.074H19.57l-13.7 13.7a27.198 27.198 0 0 0 7.611 7.611l13.193-13.193V63.46a17.252 17.252 0 0 0 5.074.507 15.629 15.629 0 0 0 5.074-.507V44.686L50.014 57.88a13.7 13.7 0 0 0 4.059-3.552 29.025 29.025 0 0 0 3.552-4.059L44.432 37.074h18.775A17.252 17.252 0 0 0 63.715 32a19.028 19.028 0 0 0-.507-5.582zm-23.342 5.074a25.726 25.726 0 0 1-1.015 6.597 15.223 15.223 0 0 1-6.597 1.015 25.726 25.726 0 0 1-6.597-1.015 15.223 15.223 0 0 1-1.015-6.597 25.726 25.726 0 0 1 1.015-6.597 15.223 15.223 0 0 1 6.597-1.015 25.726 25.726 0 0 1 6.597 1.015 29.684 29.684 0 0 1 1.015 6.597z" fill="#ff4a00"/></svg>

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1 @@
<svg height="64" viewBox="0 0 32 32" width="64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m-200-175h1000v562h-1000z"/></clipPath><clipPath id="b"><circle cx="107" cy="106" r="102"/></clipPath><clipPath id="c"><circle cx="107" cy="106" r="100"/></clipPath><clipPath id="d"><circle cx="107" cy="106" r="92"/></clipPath><clipPath id="e"><path clip-rule="evenodd" d="m135 94.06 26-19c2.27-1.85 4-1.42 4 2v57.94c0 3.84-2.16 3.4-4 2l-26-19zm-88-16.86v43.2a17.69 17.69 0 0 0 17.77 17.6h63a3.22 3.22 0 0 0 3.23-3.2v-43.2a17.69 17.69 0 0 0 -17.77-17.6h-63a3.22 3.22 0 0 0 -3.23 3.2z"/></clipPath><g clip-path="url(#a)" transform="translate(0 -178)"><path d="m232 61h366v90h-366z" fill="#4a8cff"/></g><g clip-path="url(#a)" transform="matrix(.156863 0 0 .156863 -.784314 -.627496)"><g clip-path="url(#b)"><path d="m0-1h214v214h-214z" fill="#e5e5e4"/></g><g clip-path="url(#c)"><path d="m2 1h210v210h-210z" fill="#fff"/></g><g clip-path="url(#d)"><path d="m10 9h194v194h-194z" fill="#4a8cff"/></g><g clip-path="url(#e)"><path d="m42 69h128v74h-128z" fill="#fff"/></g></g><g clip-path="url(#a)" transform="translate(0 -178)"><path d="m232 19.25h180v38.17h-180z" fill="#90908f"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -82,18 +82,65 @@
}
.loader {
margin: 80px auto;
border: 8px solid #f3f3f3; /* Light grey */
border-top: 8px solid #039be5; /* neutral */
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 2s linear infinite;
display: block;
width: 30px;
height: 30px;
margin: 60px auto;
position: relative;
border: 4px solid #000;
animation: loader 2s infinite ease;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
.loader-inner {
vertical-align: top;
display: inline-block;
width: 100%;
background-color: #000;
animation: loader-inner 2s infinite ease-in;
}
@keyframes loader {
0% {
transform: rotate(0deg);
}
25% {
transform: rotate(180deg);
}
50% {
transform: rotate(180deg);
}
75% {
transform: rotate(360deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes loader-inner {
0% {
height: 0%;
}
25% {
height: 0%;
}
50% {
height: 100%;
}
75% {
height: 100%;
}
100% {
height: 0%;
}
}
nav#nav--settings > a {