Skip to content

Commit 997a1ee

Browse files
authored
✨ New and Improved Screens (#1151)
1 parent 5461c57 commit 997a1ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1511
-737
lines changed

.env.development

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ SECRET_PASSWORD=abcdef1234567890abcdef1234567890
55
# Example: https://example.com
66
NEXT_PUBLIC_BASE_URL=http://localhost:3000
77

8+
# NEXTAUTH_URL should be the same as NEXT_PUBLIC_BASE_URL
9+
NEXTAUTH_URL=http://localhost:3000
10+
811
# A connection string to your Postgres database
9-
DATABASE_URL="postgres://postgres:postgres@rallly_db:5450/rallly"
12+
DATABASE_URL="postgres://postgres:postgres@localhost:5450/rallly"
1013

1114
# Required to be able to send emails
1215
SUPPORT_EMAIL=[email protected]

.gitignore

+1-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ yarn-error.log*
2626

2727
# local env files
2828
.env
29-
.env.local
30-
.env.development.local
31-
.env.test.local
32-
.env.production.local
29+
.env*.local
3330

3431
# ts
3532
tsconfig.tsbuildinfo

apps/web/next.config.js

-5
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ const nextConfig = {
4646
destination: "/settings/profile",
4747
permanent: true,
4848
},
49-
{
50-
source: "/",
51-
destination: "/polls",
52-
permanent: false,
53-
},
5449
];
5550
},
5651
};

apps/web/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"lint:tsc": "tsc --noEmit",
1313
"i18n:scan": "i18next-scanner --config i18next-scanner.config.js",
1414
"prettier": "prettier --write ./src",
15-
"test:integration": "playwright test",
15+
"test:integration": "NODE_ENV=test playwright test",
1616
"test:unit": "vitest run",
1717
"test": "yarn test:unit && yarn test:e2e",
1818
"test:codegen": "playwright codegen http://localhost:3000",

apps/web/playwright.config.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
import { loadEnvConfig } from "@next/env";
12
import { devices, PlaywrightTestConfig } from "@playwright/test";
2-
import dotenv from "dotenv";
3-
import path from "path";
43

54
const ci = process.env.CI === "true";
65

7-
dotenv.config({ path: path.resolve(__dirname, ".env.test") });
6+
loadEnvConfig(process.cwd());
87

9-
const port = process.env.PORT || 3000;
8+
const port = process.env.PORT || 3002;
109
// Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port
1110
const baseURL = `http://localhost:${port}`;
1211

apps/web/public/locales/en/app.json

+14-12
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"copied": "Copied",
1616
"createAnAccount": "Create an account",
1717
"createdBy": "by <b>{name}</b>",
18-
"createPoll": "Create poll",
1918
"delete": "Delete",
2019
"deleteDate": "Delete date",
2120
"deletedPoll": "Deleted poll",
@@ -209,9 +208,6 @@
209208
"continueAs": "Continue as",
210209
"pageMovedDescription": "Redirecting to <a>{newUrl}</a>",
211210
"notRegistered": "Don't have an account? <a>Register</a>",
212-
"comingSoon": "Coming Soon",
213-
"integrations": "Integrations",
214-
"contacts": "Contacts",
215211
"unlockFeatures": "Unlock all Pro features.",
216212
"pollStatusFinalized": "Finalized",
217213
"share": "Share",
@@ -222,7 +218,6 @@
222218
"aboutGuestDescription": "Profile settings are not available for guest users. <0>Sign in</0> to your existing account or <1>create a new account</1> to customize your profile.",
223219
"logoutDescription": "Sign out of your existing session",
224220
"events": "Events",
225-
"registrations": "Registrations",
226221
"inviteParticipantsDescription": "Copy and share the invite link to start gathering responses from your participants.",
227222
"inviteLink": "Invite Link",
228223
"inviteParticipantLinkInfo": "Anyone with this link will be able to vote on your poll.",
@@ -233,14 +228,8 @@
233228
"autoTimeZoneHelp": "Enable this setting to automatically adjust event times to each participant's local time zone.",
234229
"commentsDisabled": "Comments have been disabled",
235230
"allParticipants": "All Participants",
236-
"host": "Host",
237-
"created": "Created",
238-
"pollStatus": "Status",
239231
"pollsListAll": "All",
240-
"pollsListMine": "Mine",
241-
"pollsListOther": "Other",
242232
"noParticipantsDescription": "Click <b>Share</b> to invite participants",
243-
"back": "Back",
244233
"timeShownIn": "Times shown in {timeZone}",
245234
"pollStatusPausedDescription": "Votes cannot be submitted or edited at this time",
246235
"eventHostTitle": "Manage Access",
@@ -261,5 +250,18 @@
261250
"advancedSettingsDescription": "Hide participants, hide scores, require participant email address.",
262251
"keepPollsIndefinitely": "Keep Polls Indefinitely",
263252
"keepPollsIndefinitelyDescription": "Inactive polls will not be auto-deleted.",
264-
"verificationCodeSentTo": "We sent a verification code to <b>{{ email }}</b>"
253+
"verificationCodeSentTo": "We sent a verification code to <b>{{ email }}</b>",
254+
"home": "Home",
255+
"groupPoll": "Group Poll",
256+
"groupPollDescription": "Share your availability with a group of people and find the best time to meet.",
257+
"create": "Create",
258+
"upcoming": "Upcoming",
259+
"past": "Past",
260+
"copyLink": "Copy Link",
261+
"upcomingEventsEmptyStateTitle": "No Upcoming Events",
262+
"upcomingEventsEmptyStateDescription": "When you schedule events, they will appear here.",
263+
"pastEventsEmptyStateTitle": "No Past Events",
264+
"pastEventsEmptyStateDescription": "When you schedule events, they will appear here.",
265+
"activePollCount": "{{activePollCount}} Live",
266+
"createPoll": "Create poll"
265267
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { cn } from "@rallly/ui";
2+
import { BarChart2Icon } from "lucide-react";
3+
import React from "react";
4+
5+
import { Squircle } from "@/app/components/squircle";
6+
7+
export function AppCard({
8+
children,
9+
className,
10+
}: {
11+
children?: React.ReactNode;
12+
className?: string;
13+
}) {
14+
return (
15+
<div
16+
className={cn(
17+
"flex w-full flex-col justify-between rounded-lg border bg-white p-4 shadow-sm ring-1 ring-inset ring-white/50",
18+
className,
19+
)}
20+
>
21+
{children}
22+
</div>
23+
);
24+
}
25+
26+
export function AppCardContent({ children }: { children?: React.ReactNode }) {
27+
return <div className="">{children}</div>;
28+
}
29+
30+
export function GroupPollIcon({
31+
size = "md",
32+
}: {
33+
size?: "xs" | "sm" | "md" | "lg";
34+
}) {
35+
return (
36+
<Squircle
37+
aria-label="Group Poll"
38+
className={cn(
39+
"inline-flex items-center justify-center bg-gradient-to-br from-purple-500 to-violet-500 text-purple-100",
40+
{
41+
"size-6": size === "xs",
42+
"size-8": size === "sm",
43+
"size-9": size === "md",
44+
"size-10": size === "lg",
45+
},
46+
)}
47+
>
48+
<BarChart2Icon
49+
className={cn({
50+
"size-4": size === "sm" || size === "xs",
51+
"size-5": size === "md",
52+
"size-6": size === "lg",
53+
})}
54+
/>
55+
</Squircle>
56+
);
57+
}
58+
59+
export function AppCardIcon({
60+
children,
61+
className,
62+
}: {
63+
children?: React.ReactNode;
64+
className?: string;
65+
}) {
66+
return (
67+
<div
68+
className={cn(
69+
"relative mb-4 inline-flex size-12 items-center justify-center",
70+
className,
71+
)}
72+
>
73+
{children}
74+
</div>
75+
);
76+
}
77+
78+
export function AppCardName({
79+
children,
80+
className,
81+
}: {
82+
children?: React.ReactNode;
83+
className?: string;
84+
}) {
85+
return <h2 className={cn("font-semibold", className)}>{children}</h2>;
86+
}
87+
88+
export function AppCardDescription({
89+
children,
90+
className,
91+
}: {
92+
children?: React.ReactNode;
93+
className?: string;
94+
}) {
95+
return (
96+
<p
97+
className={cn(
98+
"text-muted-foreground mt-1 text-sm leading-relaxed",
99+
className,
100+
)}
101+
>
102+
{children}
103+
</p>
104+
);
105+
}
106+
107+
export function AppCardFooter({
108+
children,
109+
className,
110+
}: {
111+
children?: React.ReactNode;
112+
className?: string;
113+
}) {
114+
return <div className={cn("mt-6 border-t pt-3", className)}>{children}</div>;
115+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"use client";
2+
import { Button } from "@rallly/ui/button";
3+
import { Icon } from "@rallly/ui/icon";
4+
import { PlusIcon } from "lucide-react";
5+
import Link from "next/link";
6+
7+
import {
8+
AppCard,
9+
AppCardContent,
10+
AppCardDescription,
11+
AppCardFooter,
12+
AppCardIcon,
13+
AppCardName,
14+
GroupPollIcon,
15+
} from "@/app/[locale]/(admin)/app-card";
16+
import { Spinner } from "@/components/spinner";
17+
import { Trans } from "@/components/trans";
18+
import { trpc } from "@/utils/trpc/client";
19+
20+
export default function Dashboard() {
21+
const { data } = trpc.dashboard.info.useQuery();
22+
23+
if (!data) {
24+
return <Spinner />;
25+
}
26+
27+
return (
28+
<div className="space-y-4">
29+
<div className="grid gap-4 lg:grid-cols-3">
30+
<AppCard>
31+
<AppCardIcon>
32+
<GroupPollIcon size="lg" />
33+
</AppCardIcon>
34+
<AppCardContent>
35+
<div>
36+
<AppCardName>
37+
<Trans i18nKey="groupPoll" defaults="Group Poll" />
38+
</AppCardName>
39+
<AppCardDescription>
40+
<Trans
41+
i18nKey="groupPollDescription"
42+
defaults="Share your availability with a group of people and find the best time to meet."
43+
/>
44+
</AppCardDescription>
45+
</div>
46+
</AppCardContent>
47+
<AppCardFooter className="flex items-center justify-between gap-4">
48+
<div className="inline-flex items-center gap-1 text-sm">
49+
<Link
50+
className="text-primary font-medium hover:underline"
51+
href="/polls?status=live"
52+
>
53+
<Trans
54+
i18nKey="activePollCount"
55+
defaults="{{activePollCount}} Live"
56+
values={{
57+
activePollCount: data.activePollCount,
58+
}}
59+
/>
60+
</Link>
61+
</div>
62+
<Button asChild>
63+
<Link href="/new">
64+
<Icon>
65+
<PlusIcon />
66+
</Icon>
67+
<Trans i18nKey="create" defaults="Create" />
68+
</Link>
69+
</Button>
70+
</AppCardFooter>
71+
</AppCard>
72+
</div>
73+
</div>
74+
);
75+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"use client";
2+
3+
import { Card, CardContent } from "@rallly/ui/card";
4+
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
5+
import dayjs from "dayjs";
6+
7+
import { ScheduledEvent } from "@/app/[locale]/(admin)/events/types";
8+
import { Trans } from "@/components/trans";
9+
import { generateGradient } from "@/utils/color-hash";
10+
import { useDayjs } from "@/utils/dayjs";
11+
12+
export function EventList({ data }: { data: ScheduledEvent[] }) {
13+
const table = useReactTable({
14+
data,
15+
columns: [],
16+
getCoreRowModel: getCoreRowModel(),
17+
});
18+
19+
const { adjustTimeZone } = useDayjs();
20+
return (
21+
<Card>
22+
<ul className="divide-y divide-gray-100">
23+
{table.getRowModel().rows.map((row) => {
24+
const start = adjustTimeZone(
25+
row.original.start,
26+
!row.original.timeZone,
27+
);
28+
29+
const end = adjustTimeZone(
30+
dayjs(row.original.start).add(row.original.duration, "minutes"),
31+
!row.original.timeZone,
32+
);
33+
return (
34+
<li key={row.id}>
35+
<CardContent>
36+
<div className="flex flex-col gap-2 sm:flex-row sm:gap-8">
37+
<div className="flex shrink-0 justify-between gap-1 sm:w-24 sm:flex-col sm:text-right">
38+
<time
39+
dateTime={start.toISOString()}
40+
className="text-sm font-medium"
41+
>
42+
{start.format("ddd, D MMM")}
43+
</time>
44+
<time
45+
dateTime={start.toISOString()}
46+
className="text-muted-foreground text-sm"
47+
>
48+
{start.format("YYYY")}
49+
</time>
50+
</div>
51+
<div className="min-w-0">
52+
<div className="flex items-center gap-x-2">
53+
<span
54+
className="h-4 w-1 shrink-0 rounded-full"
55+
style={{
56+
background: generateGradient(row.original.id),
57+
}}
58+
></span>
59+
<h2 className="truncate text-base font-semibold">
60+
{row.original.title}
61+
</h2>
62+
</div>
63+
<p className="text-muted-foreground mt-1 text-sm">
64+
{row.original.duration === 0 ? (
65+
<Trans i18nKey="allDay" />
66+
) : (
67+
<span>{`${start.format("LT")} - ${end.format("LT")}`}</span>
68+
)}
69+
</p>
70+
</div>
71+
</div>
72+
</CardContent>
73+
</li>
74+
);
75+
})}
76+
</ul>
77+
</Card>
78+
);
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Layout({ children }: { children?: React.ReactNode }) {
2+
return <div>{children}</div>;
3+
}

0 commit comments

Comments
 (0)