mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-20 04:16:21 +02:00
🚧 Add more info about giving feedback in the open beta environment (#508)
This commit is contained in:
parent
9586a072d4
commit
ce3e5540db
7 changed files with 122 additions and 69 deletions
|
@ -8,6 +8,7 @@ import {
|
|||
} from "@floating-ui/react-dom-interactions";
|
||||
import { Menu } from "@headlessui/react";
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import * as React from "react";
|
||||
|
||||
import { transformOriginByPlacement } from "@/utils/constants";
|
||||
|
@ -82,30 +83,25 @@ export const DropdownItem: React.VoidFunctionComponent<{
|
|||
href?: string;
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
}> = ({ icon: Icon, label, onClick, disabled, href }) => {
|
||||
const Element = href ? "a" : "button";
|
||||
const Element = href ? Link : "button";
|
||||
return (
|
||||
<Menu.Item disabled={disabled}>
|
||||
{({ active }) => (
|
||||
<Element
|
||||
href={href}
|
||||
// TODO (Luke Vella) [2023-02-10]: Find a better solution for having a mixture of links and buttons
|
||||
// in a dropdown
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
href={href as any}
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
"group flex w-full items-center rounded py-2 pl-2 pr-4",
|
||||
"relative flex w-full select-none items-center whitespace-nowrap rounded py-1.5 pl-2 pr-4 font-medium text-slate-600",
|
||||
{
|
||||
"bg-primary-500 text-white": active,
|
||||
"text-gray-700": !active,
|
||||
"bg-slate-100": active,
|
||||
"opacity-50": disabled,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{Icon && (
|
||||
<Icon
|
||||
className={clsx("mr-2 h-5 w-5", {
|
||||
"text-white": active,
|
||||
"text-primary-500": !active,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{Icon && <Icon className={clsx("mr-2 h-5 shrink-0")} />}
|
||||
{label}
|
||||
</Element>
|
||||
)}
|
||||
|
|
3
src/components/icons/beaker.svg
Normal file
3
src/components/icons/beaker.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" />
|
||||
</svg>
|
After Width: | Height: | Size: 458 B |
|
@ -1,11 +1,11 @@
|
|||
import clsx from "clsx";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
import Link from "next/link";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import React from "react";
|
||||
|
||||
import { LoginLink } from "@/components/auth/login-modal";
|
||||
import Adjustments from "@/components/icons/adjustments.svg";
|
||||
import Beaker from "@/components/icons/beaker.svg";
|
||||
import Home from "@/components/icons/home.svg";
|
||||
import Login from "@/components/icons/login.svg";
|
||||
import Menu from "@/components/icons/menu.svg";
|
||||
|
@ -16,7 +16,10 @@ import { Popover, PopoverContent, PopoverTrigger } from "@/components/popover";
|
|||
import Preferences from "@/components/preferences";
|
||||
import { useUser } from "@/components/user-provider";
|
||||
|
||||
import Dropdown, { DropdownItem } from "../../dropdown";
|
||||
import { Logo } from "../../logo";
|
||||
import { useModalContext } from "../../modal/modal-provider";
|
||||
import OpenBeta from "../../open-beta-modal";
|
||||
import { UserDropdown } from "./user-dropdown";
|
||||
|
||||
export const MobileNavigation = (props: { className?: string }) => {
|
||||
|
@ -24,6 +27,7 @@ export const MobileNavigation = (props: { className?: string }) => {
|
|||
const { t } = useTranslation(["common", "app"]);
|
||||
|
||||
const [isPinned, setIsPinned] = React.useState(false);
|
||||
const modalContext = useModalContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const scrollHandler = () => {
|
||||
|
@ -51,8 +55,9 @@ export const MobileNavigation = (props: { className?: string }) => {
|
|||
)}
|
||||
>
|
||||
<div>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild={true}>
|
||||
<Dropdown
|
||||
placement="bottom-start"
|
||||
trigger={
|
||||
<button
|
||||
role="button"
|
||||
type="button"
|
||||
|
@ -61,11 +66,33 @@ export const MobileNavigation = (props: { className?: string }) => {
|
|||
<Menu className="mr-2 w-5 group-hover:text-primary-500" />
|
||||
<Logo />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="start">
|
||||
<AppMenu />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
}
|
||||
>
|
||||
<DropdownItem href="/" label={t("home")} icon={Home} />
|
||||
<DropdownItem href="/new" label={t("app:createNew")} icon={Pencil} />
|
||||
<DropdownItem
|
||||
href="https://support.rallly.co"
|
||||
label={t("support")}
|
||||
icon={Support}
|
||||
/>
|
||||
{process.env.NEXT_PUBLIC_BETA === "1" ? (
|
||||
<>
|
||||
<DropdownItem
|
||||
onClick={() => {
|
||||
// open modal
|
||||
modalContext.render({
|
||||
content: <OpenBeta />,
|
||||
footer: null,
|
||||
showClose: true,
|
||||
overlayClosable: true,
|
||||
});
|
||||
}}
|
||||
label="Feedback"
|
||||
icon={Beaker}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
</Dropdown>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
{user ? null : (
|
||||
|
@ -121,36 +148,3 @@ export const MobileNavigation = (props: { className?: string }) => {
|
|||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const AppMenu: React.VoidFunctionComponent<{ className?: string }> = ({
|
||||
className,
|
||||
}) => {
|
||||
const { t } = useTranslation(["common", "app"]);
|
||||
return (
|
||||
<div className={clsx("space-y-1", className)}>
|
||||
<Link
|
||||
href="/"
|
||||
className="flex cursor-pointer items-center space-x-2 whitespace-nowrap rounded px-2 py-1 pr-4 font-medium text-slate-600 transition-colors hover:bg-slate-50 hover:text-slate-600 hover:no-underline active:bg-gray-300"
|
||||
>
|
||||
<Home className="h-5 opacity-75 " />
|
||||
<span className="inline-block">{t("app:home")}</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="/new"
|
||||
className="flex cursor-pointer items-center space-x-2 whitespace-nowrap rounded px-2 py-1 pr-4 font-medium text-slate-600 transition-colors hover:bg-slate-50 hover:text-slate-600 hover:no-underline active:bg-gray-300"
|
||||
>
|
||||
<Pencil className="h-5 opacity-75 " />
|
||||
<span className="inline-block">{t("app:createNew")}</span>
|
||||
</Link>
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://support.rallly.co"
|
||||
className="flex cursor-pointer items-center space-x-2 whitespace-nowrap rounded px-2 py-1 pr-4 font-medium text-slate-600 transition-colors hover:bg-slate-50 hover:text-slate-600 hover:no-underline active:bg-gray-300"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Support className="h-5 opacity-75" />
|
||||
<span className="inline-block">{t("common:support")}</span>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import clsx from "clsx";
|
|||
export const Logo = (props: { className?: string; color?: boolean }) => {
|
||||
const { color = true } = props;
|
||||
return (
|
||||
<span className="inline-flex items-center">
|
||||
<span className="inline-flex select-none items-center">
|
||||
<span
|
||||
className={clsx(
|
||||
"font-semibold uppercase tracking-widest",
|
||||
|
@ -16,7 +16,7 @@ export const Logo = (props: { className?: string; color?: boolean }) => {
|
|||
Rallly
|
||||
</span>
|
||||
{process.env.NEXT_PUBLIC_BETA === "1" ? (
|
||||
<span className="ml-2 inline-block animate-pulse rounded bg-rose-500 px-1 text-xs lowercase tracking-tight text-white">
|
||||
<span className="ml-2 inline-block rounded bg-rose-500 px-1 text-xs lowercase tracking-tight text-slate-50">
|
||||
beta
|
||||
</span>
|
||||
) : null}
|
||||
|
|
|
@ -64,7 +64,7 @@ const Modal: React.VoidFunctionComponent<ModalProps> = ({
|
|||
initial={{ opacity: 0, scale: 0.9 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.9 }}
|
||||
className="relative z-50 my-8 inline-block max-w-full transform text-left align-middle"
|
||||
className="relative z-50 m-3 inline-block max-w-full transform text-left align-middle sm:m-8"
|
||||
>
|
||||
<div className="max-w-full overflow-hidden rounded-md bg-white shadow-huge">
|
||||
{showClose ? (
|
||||
|
|
71
src/components/open-beta-modal.tsx
Normal file
71
src/components/open-beta-modal.tsx
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { Logo } from "./logo";
|
||||
|
||||
const OpenBeta = () => {
|
||||
return (
|
||||
<div>
|
||||
<div className="bg-pattern border-b px-4 py-8 text-center text-2xl">
|
||||
<Logo />
|
||||
</div>
|
||||
<div className="max-w-3xl p-3 sm:p-6">
|
||||
<div>
|
||||
<p>
|
||||
The open beta allows you to test out new features before they are
|
||||
officially released to the general public. By participating you,
|
||||
will have the opportunity to provide feedback and help shape the
|
||||
future of Rallly!
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Feedback</h2>
|
||||
<p></p>
|
||||
<ul className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<a
|
||||
href="https://github.com/lukevella/rallly/issues/new?assignees=&labels=bug&template=---bug-report.md&title="
|
||||
className="rounded border p-3 hover:text-primary-500"
|
||||
>
|
||||
🐞 Submit a bug report
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/lukevella/rallly/discussions/new/choose"
|
||||
className="rounded border p-3 hover:text-primary-500"
|
||||
>
|
||||
📢 Open a discussion with the community
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.gg/uzg4ZcHbuM"
|
||||
className="rounded border p-3 hover:text-primary-500"
|
||||
>
|
||||
💬 Chat on Discord
|
||||
</a>
|
||||
<a
|
||||
href="mailto:feedback@rallly.co"
|
||||
className="rounded border p-3 hover:text-primary-500"
|
||||
>
|
||||
✉️ Send an email
|
||||
</a>
|
||||
</ul>
|
||||
<div className="bg-patte mt-4 rounded border bg-slate-50 p-4">
|
||||
<h2 className="text-slate-800">Important</h2>
|
||||
<p>
|
||||
<strong>
|
||||
You should not rely on the beta for any important data or
|
||||
information.
|
||||
</strong>
|
||||
</p>
|
||||
<p>
|
||||
The beta should be used exclusively for testing purposes.
|
||||
Features, polls, accounts, or data may be removed at any time
|
||||
without prior notice.
|
||||
</p>
|
||||
<p className="m-0">
|
||||
Any data or information saved on the beta website cannot be
|
||||
accessed on the production website and vice versa.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OpenBeta;
|
|
@ -4,7 +4,6 @@ import "~/style.css";
|
|||
|
||||
import { Inter, Noto_Sans_Mono } from "@next/font/google";
|
||||
import { inject } from "@vercel/analytics";
|
||||
import { domAnimation, LazyMotion, m } from "framer-motion";
|
||||
import { NextPage } from "next";
|
||||
import { AppProps } from "next/app";
|
||||
import Head from "next/head";
|
||||
|
@ -89,17 +88,7 @@ const MyApp: NextPage<AppPropsWithLayout> = ({ Component, pageProps }) => {
|
|||
--font-noto: ${noto.style.fontFamily};
|
||||
}
|
||||
`}</style>
|
||||
<LazyMotion features={domAnimation}>
|
||||
{getLayout(
|
||||
<m.div
|
||||
initial={{ opacity: 0, y: -50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: 50 }}
|
||||
>
|
||||
<Component {...pageProps} />
|
||||
</m.div>,
|
||||
)}
|
||||
</LazyMotion>
|
||||
{getLayout(<Component {...pageProps} />)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue