Skip to content

Commit

Permalink
πŸš€ Add dark and light support (#133)
Browse files Browse the repository at this point in the history
* Add dark and light support

* Add theme selector on account page

* Add theme selector

* πŸ› Fix bug with floating numbers on exact split calculator (#135)

Fix bug with floating numbers on exact split calculator

* Update default theme

* Fix the theme color on light mode

* πŸš€ Order by expense created date in the groups list (#139)

Order by expense created date in the groups list

* πŸš€ Redirect to groupexpense or expense in activity list based on groupId (#140)

Redirect to groupexpense or expense in activity list based on groupId

* πŸš€ Add group created date and first expense date (#141)

* Add group created date and first expense date

* Fixup

* fix date format error

* fix deleted expense included in total stats

---------

Co-authored-by: KMKoushik <koushikmohan1996@gmail.com>
  • Loading branch information
alexanderwassbjer and KMKoushik authored Nov 8, 2024
1 parent 464cc4f commit 4071ba5
Show file tree
Hide file tree
Showing 19 changed files with 7,399 additions and 5,567 deletions.
12,731 changes: 7,225 additions & 5,506 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/components/Account/SubmitFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { Form, FormControl, FormField, FormItem, FormMessage } from '../ui/form';
import { toast } from 'sonner';
import { Button } from '../ui/button';

const feedbackSchema = z.object({
feedback: z
Expand Down Expand Up @@ -37,13 +38,16 @@ export const SubmitFeedback: React.FC = () => {
return (
<AppDrawer
trigger={
<div className="flex w-full justify-between px-0 py-2 text-[16px] font-medium text-gray-300 hover:text-foreground/80">
<Button
variant="ghost"
className="text-md w-full justify-between px-0 hover:text-foreground/80"
>
<div className="flex items-center gap-4 text-[16px]">
<MessageSquare className="h-5 w-5 text-green-500" />
Submit feedback
</div>
<ChevronRight className="h-6x w-6 text-gray-500" />
</div>
</Button>
}
open={feedbackOpen}
onOpenChange={setFeedbackOpen}
Expand Down
70 changes: 70 additions & 0 deletions src/components/Account/ThemeSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { Command, CommandGroup, CommandItem } from '../ui/command';
import { AppDrawer } from '../ui/drawer';
import { Check, ChevronRight, Moon } from 'lucide-react';
import { cn } from '~/lib/utils';
import { Button } from '../ui/button';
import { useTheme } from 'next-themes';

const supportedThemes = {
dark: 'Dark',
light: 'Light',
system: 'System prefer',
};

export const ThemeSelect = () => {
const [open, setOpen] = React.useState(false);
const { theme, setTheme } = useTheme();

const onSelect = async (currentValue: string) => {
setTheme(currentValue);

setOpen(false);
};

return (
<AppDrawer
trigger={
<Button
variant="ghost"
className="text-md w-full justify-between px-0 hover:text-foreground/80"
>
<div className="flex items-center gap-4">
<Moon className="h-5 w-5 text-violet-500" />
<p>Theme</p>
</div>
<ChevronRight className="h-6 w-6 text-gray-500" />
</Button>
}
onTriggerClick={() => setOpen(true)}
title={'Select theme'}
className="h-[70vh]"
shouldCloseOnAction
open={open}
onOpenChange={(openVal) => {
if (openVal !== open) setOpen(openVal);
}}
>
<div className="">
<Command className="h-[50vh]">
<CommandGroup className="h-full overflow-auto">
{Object.keys(supportedThemes).map((framework, index) => (
<CommandItem
key={framework}
value={framework}
onSelect={(currentValue) => onSelect(currentValue)}
>
<Check
className={cn('mr-2 h-4 w-4', framework === theme ? 'opacity-100' : 'opacity-0')}
/>
<div className="flex gap-2">
<p>{Object.values(supportedThemes)[index]}</p>
</div>
</CommandItem>
))}
</CommandGroup>
</Command>
</div>
</AppDrawer>
);
};
35 changes: 14 additions & 21 deletions src/components/AddExpense/SplitTypeSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const SplitTypeSection: React.FC = () => {
const { setPaidBy } = useAddExpenseStore((s) => s.actions);

return (
<div className="mt-4 flex items-center justify-center text-[16px] text-gray-400">
<div className="mt-4 flex items-center justify-center text-[16px] text-gray-800 dark:text-gray-400">
<p className="text-[16px]">Paid by </p>
<AppDrawer
trigger={
Expand Down Expand Up @@ -137,27 +137,20 @@ const SplitEqualSection: React.FC = () => {
const allSelected = participants.every((p) => p.splitShare !== 0);

return (
<div className="mt-4 flex flex-col gap-6 px-2 relative">
<div className="relative mt-4 flex flex-col gap-6 px-2">
<div className="flex items-center">
<div className="mb-2 flex-grow flex justify-center">
<div
className={`${canSplitScreenClosed ? 'text-gray-300' : 'text-red-500'
}`}
>
<div className="mb-2 flex flex-grow justify-center">
<div className={`${canSplitScreenClosed ? 'text-gray-300' : 'text-red-500'}`}>
{currency} {(amount / totalParticipants).toFixed(2)} per person
</div>
</div>
</div>
<div className="absolute top-0 right-0">
<div className="absolute right-0 top-0">
<button
className="flex items-center gap-1 border rounded-md py-0.5 px-2 whitespace-nowrap"
className="flex items-center gap-1 whitespace-nowrap rounded-md border px-2 py-0.5"
onClick={selectAll}
>
{allSelected ? (
<X className="h-4 w-4" />
) : (
<Check className="h-4 w-4" />
)}
{allSelected ? <X className="h-4 w-4" /> : <Check className="h-4 w-4" />}
<span className="text-sm">All</span>
</button>
</div>
Expand Down Expand Up @@ -243,7 +236,7 @@ const SplitByAmountSection: React.FC = () => {
const [splitShareValue, setSplitShareValue] = useState(
participants.reduce(
(acc, p) => {
acc[p.id] = p.splitShare?.toString();
acc[p.id] = p.splitShare?.toString() ?? '';
return acc;
},
{} as Record<string, string | undefined>,
Expand All @@ -256,19 +249,20 @@ const SplitByAmountSection: React.FC = () => {
addOrUpdateParticipant({ ...p, splitShare: 0 });
return;
}
addOrUpdateParticipant({ ...p, splitShare: parseFloat(value) });
const formattedValue = parseFloat(parseFloat(value).toFixed(2));
addOrUpdateParticipant({ ...p, splitShare: formattedValue });
};

const remainingPercentage =
amount - participants.reduce((acc, p) => acc + (p.splitShare ?? 0), 0);
const totalSplitShare = participants.reduce((acc, p) => acc + (p.splitShare ?? 0), 0);

const remainingAmount = parseFloat((amount - totalSplitShare).toFixed(2));

return (
<div className="mt-4 flex flex-col gap-6 px-2">
<div
className={`mb-2 text-center ${canSplitScreenClosed ? 'text-gray-300' : 'text-red-500'} t`}
>
{' '}
Remaining {currency} {remainingPercentage}
Remaining {currency} {remainingAmount}
</div>
{participants.map((p) => (
<div key={p.id} className="flex justify-between">
Expand All @@ -278,7 +272,6 @@ const SplitByAmountSection: React.FC = () => {
</div>
<div className="flex items-center gap-1">
<p className="text-xs">{currency}</p>

<Input
type="number"
value={splitShareValue[p.id]}
Expand Down
4 changes: 2 additions & 2 deletions src/components/AddExpense/UserInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const UserInput: React.FC = () => {
return (
<div className="mt-4 flex flex-wrap gap-2 border-b pb-4">
{group ? (
<div className="flex items-center gap-2 rounded-full bg-slate-800 p-0.5 pr-4">
<div className="flex items-center gap-2 rounded-full bg-slate-100 p-0.5 pr-4 dark:bg-slate-800">
<GroupAvatar name={group.name} size={30} />
<p className="text-xs">{group.name}</p>
</div>
Expand All @@ -73,7 +73,7 @@ export const UserInput: React.FC = () => {
p.id !== currentUser?.id ? (
<div
key={p.id}
className="flex items-center gap-2 rounded-full bg-slate-800 p-0.5 pr-4"
className="flex items-center gap-2 rounded-full bg-slate-100 p-0.5 pr-4 dark:bg-slate-800"
>
<UserAvatar user={p} size={30} />
<p className="text-xs">{p.name ?? p.email}</p>
Expand Down
2 changes: 1 addition & 1 deletion src/components/InstallApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const InstallApp: React.FC = () => {
<AppDrawer
trigger={
<Button className="w-[250px]">
<Download className="mr-2 h-5 w-5 text-black" />
<Download className="mr-2 h-5 w-5 text-white dark:text-black" />
Download App
</Button>
}
Expand Down
7 changes: 5 additions & 2 deletions src/components/Layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ const MainLayout: React.FC<MainLayoutProps> = ({ children, actions, hideAppBar,
currentPath={currentPath}
/>
</nav>
<div className="w-full overflow-auto lg:border-x lg:border-gray-900 lg:px-6">
<div
className="w-full overflow-auto lg:border-x lg:border-gray-200 lg:px-6 dark:lg:border-gray-900"
id="mainlayout"
>
{title ? (
<div className="mb-2 flex items-center justify-between px-4 py-4">
<div className="text-3xl font-bold text-gray-200">{title}</div>
<div className="text-3xl font-bold text-black dark:text-gray-200">{title}</div>
{actions}
</div>
) : null}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export const AppDrawer: React.FC<AppDrawerProps> = (props) => {
) : (
<DialogClose
onClick={actionOnClick}
className="w-[100px] rounded-md bg-primary py-2 text-sm text-black disabled:opacity-50"
className="w-[100px] rounded-md bg-primary py-2 text-sm text-white disabled:opacity-50 dark:text-black"
disabled={actionDisabled}
>
{actionTitle}
Expand Down
10 changes: 4 additions & 6 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,19 @@ const MyApp: AppType<{ session: Session | null }> = ({
<meta name="msapplication-config" content="/icons/browserconfig.xml" />
<meta name="msapplication-TileColor" content="#2B5797" />
<meta name="msapplication-tap-highlight" content="no" />

<meta name="theme-color" content="#030711" />
<meta name="color-scheme" content="light dark" />
<meta name="theme-color" content="#030711" media="(prefers-color-scheme: dark)" />
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />

<link rel="apple-touch-icon" href="/icons/ios/144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/icons/ios/152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/icons/ios/180.png" />
<link rel="apple-touch-icon" sizes="167x167" href="/icons/ios/167.png" />

<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" />
<link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#5bbad5" />
<link rel="shortcut icon" href="/favicon.ico" />

<meta name="twitter:card" content="summary" />
<meta name="twitter:url" content="https://splitpro.app" />
<meta name="twitter:title" content="SplitPro" />
Expand All @@ -64,7 +62,7 @@ const MyApp: AppType<{ session: Session | null }> = ({
<meta property="og:image" content="https://splitpro.app/og_banner.png" />
</Head>
<SessionProvider session={session}>
<ThemeProvider attribute="class" defaultTheme="dark">
<ThemeProvider attribute="class" enableColorScheme enableSystem defaultTheme="dark">
<Toaster toastOptions={{ duration: 1500 }} />
{(Component as NextPageWithUser).auth ? (
<Auth pageProps={pageProps} Page={Component as NextPageWithUser}></Auth>
Expand Down
13 changes: 9 additions & 4 deletions src/pages/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { env } from '~/env';
import { SubscribeNotification } from '~/components/Account/SubscribeNotification';
import { useState } from 'react';
import { LoadingSpinner } from '~/components/ui/spinner';
import { ThemeSelect } from '~/components/Account/ThemeSelect';

const AccountPage: NextPageWithUser = ({ user }) => {
const userQuery = api.user.me.useQuery();
Expand Down Expand Up @@ -67,6 +68,7 @@ const AccountPage: NextPageWithUser = ({ user }) => {
</div>
</div>
<div className="mt-8 flex flex-col gap-4">
<ThemeSelect />
<Link href="https://twitter.com/KM_Koushik_" target="_blank">
<Button
variant="ghost"
Expand All @@ -82,7 +84,7 @@ const AccountPage: NextPageWithUser = ({ user }) => {
<g clip-path="url(#clip0_1_2)">
<path
d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z"
fill="white"
fill="gray"
/>
</g>
<defs>
Expand All @@ -102,7 +104,7 @@ const AccountPage: NextPageWithUser = ({ user }) => {
className="text-md w-full justify-between px-0 hover:text-foreground/80"
>
<div className="flex items-center gap-4">
<Github className="h-5 w-5 text-gray-200" />
<Github className="h-5 w-5 text-gray-800 dark:text-gray-200" />
Star us on Github
</div>
<ChevronRight className="h-6 w-6 text-gray-500" />
Expand Down Expand Up @@ -136,13 +138,16 @@ const AccountPage: NextPageWithUser = ({ user }) => {
</Link>
<AppDrawer
trigger={
<div className="flex w-full justify-between px-0 py-2 text-[16px] font-medium text-gray-300 hover:text-foreground/80">
<Button
variant="ghost"
className="text-md w-full justify-between px-0 hover:text-foreground/80"
>
<div className="flex items-center gap-4">
<Download className="h-5 w-5 text-blue-500" />
Download App
</div>
<ChevronRight className="h-6x w-6 text-gray-500" />
</div>
</Button>
}
leftAction="Close"
title="Download App"
Expand Down
14 changes: 10 additions & 4 deletions src/pages/activity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ const ActivityPage: NextPageWithUser = ({ user }) => {
<div className="mt-[30vh] text-center text-gray-400">No activities yet</div>
) : null}
{expensesQuery.data?.map((e) => (
<Link href={`/expenses/${e.expenseId}`} key={e.expenseId} className="flex gap-2">
<Link
href={`${e.expense.groupId ? `/groups/${e.expense.groupId}/` : '/'}expenses/${e.expenseId}`}
key={e.expenseId}
className="flex gap-2"
>
<div className="mt-1">
<UserAvatar user={e.expense.paidByUser} size={30} />
</div>
Expand All @@ -82,14 +86,16 @@ const ActivityPage: NextPageWithUser = ({ user }) => {
<span className=" font-semibold ">{e.expense.name}</span>
</p>
) : (
<p className="text-gray-300">
<span className=" font-semibold text-gray-300">
<p className="text-gray-800 dark:text-gray-300">
<span className=" font-semibold text-gray-800 dark:text-gray-300">
{e.expense.paidBy === user.id
? 'You'
: e.expense.paidByUser.name ?? e.expense.paidByUser.email}
</span>
{' paid for '}
<span className=" font-semibold text-gray-300">{e.expense.name}</span>
<span className=" font-semibold text-gray-800 dark:text-gray-300">
{e.expense.name}
</span>
</p>
)}

Expand Down
4 changes: 2 additions & 2 deletions src/pages/auth/signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const Home: NextPage<{ feedbackEmail: string; providers: ClientSafeProvider[] }>
)}
/>

<Button className="mt-6 w-[300px] bg-white hover:bg-gray-100 focus:bg-gray-100">
<Button className="mt-6 w-[300px] bg-black hover:bg-gray-800 focus:bg-gray-100 dark:bg-white dark:hover:bg-gray-100">
Submit
</Button>
</form>
Expand Down Expand Up @@ -186,7 +186,7 @@ const Home: NextPage<{ feedbackEmail: string; providers: ClientSafeProvider[] }>
)}
/>
<Button
className="mt-6 w-[300px] bg-white hover:bg-gray-100 focus:bg-gray-100"
className="mt-6 w-[300px] bg-black hover:bg-gray-800 focus:bg-gray-100 dark:bg-white dark:hover:bg-gray-100"
type="submit"
disabled={emailStatus === 'sending'}
>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/balances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ const BalancePage: NextPageWithUser = () => {

<Link href="/add">
<Button className="w-[250px]">
<PlusIcon className="mr-2 h-5 w-5 text-black" />
<PlusIcon className="mr-2 h-5 w-5 text-white dark:text-black" />
Add Expense
</Button>
</Link>
Expand Down
Loading

0 comments on commit 4071ba5

Please sign in to comment.