mirror of
https://github.com/lukevella/rallly.git
synced 2025-08-06 09:59:00 +02:00
✨ New Login Page (#1504)
This commit is contained in:
parent
655f38203a
commit
f5ab25ed1f
67 changed files with 1669 additions and 713 deletions
|
@ -0,0 +1,14 @@
|
|||
"use client";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { Trans } from "@/components/trans";
|
||||
|
||||
export function RelativeDate({ date }: { date: Date }) {
|
||||
return (
|
||||
<Trans
|
||||
i18nKey="createdTime"
|
||||
defaults="Created {relativeTime}"
|
||||
values={{ relativeTime: dayjs(date).fromNow() }}
|
||||
/>
|
||||
);
|
||||
}
|
2
apps/web/src/features/quick-create/constants.ts
Normal file
2
apps/web/src/features/quick-create/constants.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const isQuickCreateEnabled =
|
||||
process.env.NEXT_PUBLIC_SELF_HOSTED !== "true";
|
1
apps/web/src/features/quick-create/index.ts
Normal file
1
apps/web/src/features/quick-create/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { isQuickCreateEnabled } from "./constants";
|
31
apps/web/src/features/quick-create/lib/get-guest-polls.ts
Normal file
31
apps/web/src/features/quick-create/lib/get-guest-polls.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { prisma } from "@rallly/database";
|
||||
|
||||
import { getServerSession } from "@/auth";
|
||||
|
||||
export async function getGuestPolls() {
|
||||
const session = await getServerSession();
|
||||
const user = session?.user;
|
||||
const guestId = !user?.email ? user?.id : null;
|
||||
|
||||
if (!guestId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const recentlyCreatedPolls = await prisma.poll.findMany({
|
||||
where: {
|
||||
guestId,
|
||||
deleted: false,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
createdAt: true,
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: "desc",
|
||||
},
|
||||
take: 3,
|
||||
});
|
||||
|
||||
return recentlyCreatedPolls;
|
||||
}
|
21
apps/web/src/features/quick-create/quick-create-button.tsx
Normal file
21
apps/web/src/features/quick-create/quick-create-button.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Button } from "@rallly/ui/button";
|
||||
import { Icon } from "@rallly/ui/icon";
|
||||
import { ZapIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Trans } from "react-i18next/TransWithoutContext";
|
||||
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export async function QuickStartButton() {
|
||||
const { t } = await getTranslation();
|
||||
return (
|
||||
<Button className="rounded-full" asChild>
|
||||
<Link href="/quick-create">
|
||||
<Icon>
|
||||
<ZapIcon className="size-4" />
|
||||
</Icon>
|
||||
<Trans t={t} ns="app" i18nKey="quickCreate" defaults="Quick Create" />
|
||||
</Link>
|
||||
</Button>
|
||||
);
|
||||
}
|
137
apps/web/src/features/quick-create/quick-create-widget.tsx
Normal file
137
apps/web/src/features/quick-create/quick-create-widget.tsx
Normal file
|
@ -0,0 +1,137 @@
|
|||
import { Button } from "@rallly/ui/button";
|
||||
import { Icon } from "@rallly/ui/icon";
|
||||
import { CheckIcon, PlusIcon, ZapIcon } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { Trans } from "react-i18next/TransWithoutContext";
|
||||
|
||||
import { GroupPollIcon } from "@/app/[locale]/(admin)/app-card";
|
||||
import { getGuestPolls } from "@/features/quick-create/lib/get-guest-polls";
|
||||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
import { RelativeDate } from "./components/relative-date";
|
||||
|
||||
export async function QuickStartWidget() {
|
||||
const polls = await getGuestPolls();
|
||||
const { t } = await getTranslation();
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-6">
|
||||
<div className="text-primary inline-flex items-center justify-center gap-2 rounded-md font-medium">
|
||||
<ZapIcon className="size-5" />
|
||||
<h2>
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickActionCreate"
|
||||
defaults="Quick Create"
|
||||
/>
|
||||
</h2>
|
||||
</div>
|
||||
<p className="text-muted-foreground text-pretty">
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickActionsDescription"
|
||||
defaults="Create a group poll without signing in. Login later to link it to your account."
|
||||
/>
|
||||
</p>
|
||||
{polls.length > 0 ? (
|
||||
<div className="space-y-4">
|
||||
<h3 className="font-semibold">
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateRecentlyCreated"
|
||||
defaults="Recently Created"
|
||||
/>
|
||||
</h3>
|
||||
<ul className="space-y-2">
|
||||
{polls.map((poll) => (
|
||||
<li key={poll.id}>
|
||||
<Link
|
||||
href={`/poll/${poll.id}`}
|
||||
className="flex items-center gap-3 rounded-xl border bg-white p-3 hover:bg-gray-50 active:bg-gray-100"
|
||||
>
|
||||
<div>
|
||||
<GroupPollIcon size="lg" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="truncate font-medium">
|
||||
<Link href={`/poll/${poll.id}`}>{poll.title}</Link>
|
||||
</div>
|
||||
<div className="text-muted-foreground whitespace-nowrap text-sm">
|
||||
<RelativeDate date={poll.createdAt} />
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
<div>
|
||||
<Button asChild size="lg" className="w-full">
|
||||
<Link href="/new">
|
||||
<Icon size="lg">
|
||||
<PlusIcon />
|
||||
</Icon>
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateGroupPoll"
|
||||
defaults="Create Group Poll"
|
||||
/>
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="font-semibold">
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateWhyCreateAnAccount"
|
||||
defaults="Why create an account?"
|
||||
/>
|
||||
</h3>
|
||||
</div>
|
||||
<ul className="text-muted-foreground space-y-2">
|
||||
<li className="flex items-center gap-2">
|
||||
<Icon variant="success" size="lg">
|
||||
<CheckIcon />
|
||||
</Icon>
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateSecurePolls"
|
||||
defaults="Store polls securely in your account"
|
||||
/>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Icon variant="success" size="lg">
|
||||
<CheckIcon />
|
||||
</Icon>
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateGetNotifications"
|
||||
defaults="Get email notifications"
|
||||
/>
|
||||
</li>
|
||||
<li className="flex items-center gap-2">
|
||||
<Icon variant="success" size="lg">
|
||||
<CheckIcon />
|
||||
</Icon>
|
||||
<Trans
|
||||
t={t}
|
||||
ns="app"
|
||||
i18nKey="quickCreateManagePollsFromAnyDevice"
|
||||
defaults="Manage your polls from any device"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue