Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions apps/app/src/components/decisions/EmptyProposalsState.tsx

This file was deleted.

7 changes: 4 additions & 3 deletions apps/app/src/components/decisions/MyBallot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import { useUser } from '@/utils/UserProvider';
import { trpc } from '@op/api/client';
import { Checkbox } from '@op/ui/Checkbox';
import { EmptyState } from '@op/ui/EmptyState';
import { Header3 } from '@op/ui/Header';
import { LuLeaf } from 'react-icons/lu';

import { useTranslations } from '@/lib/i18n';

import { EmptyProposalsState } from './EmptyProposalsState';
import {
ProposalCardContent,
ProposalCardDescription,
Expand All @@ -20,11 +21,11 @@ import { VotingProposalCard } from './VotingProposalCard';
export const NoVoteFound = () => {
const t = useTranslations();
return (
<EmptyProposalsState>
<EmptyState icon={<LuLeaf className="size-6" />}>
<Header3 className="font-serif !text-title-base font-light text-neutral-black">
{t('You did not vote in this process.')}
</Header3>
</EmptyProposalsState>
</EmptyState>
);
};

Expand Down
8 changes: 4 additions & 4 deletions apps/app/src/components/decisions/ProposalsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ import { match } from '@op/core';
import { Button, ButtonLink } from '@op/ui/Button';
import { Checkbox } from '@op/ui/Checkbox';
import { Dialog, DialogTrigger } from '@op/ui/Dialog';
import { EmptyState } from '@op/ui/EmptyState';
import { Header3 } from '@op/ui/Header';
import { Modal } from '@op/ui/Modal';
import { Select, SelectItem } from '@op/ui/Select';
import { Skeleton } from '@op/ui/Skeleton';
import { Surface } from '@op/ui/Surface';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';
import { LuArrowDownToLine } from 'react-icons/lu';
import { LuArrowDownToLine, LuLeaf } from 'react-icons/lu';
import type { z } from 'zod';

import { useTranslations } from '@/lib/i18n';

import { Bullet } from '../Bullet';
import { EmptyProposalsState } from './EmptyProposalsState';
import {
ProposalCard,
ProposalCardActions,
Expand Down Expand Up @@ -113,14 +113,14 @@ export const ProposalListSkeleton = () => {
const NoProposalsFound = () => {
const t = useTranslations();
return (
<EmptyProposalsState>
<EmptyState icon={<LuLeaf className="size-6" />}>
<Header3 className="font-serif !text-title-base font-light text-neutral-black">
{t('No proposals found matching the current filters.')}
</Header3>
<p className="text-base text-neutral-charcoal">
{t('Try adjusting your filter selection above.')}
</p>
</EmptyProposalsState>
</EmptyState>
);
};

Expand Down
7 changes: 4 additions & 3 deletions apps/app/src/components/decisions/ResultsList.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'use client';

import { trpc } from '@op/api/client';
import { EmptyState } from '@op/ui/EmptyState';
import { Header3 } from '@op/ui/Header';
import { LuLeaf } from 'react-icons/lu';

import { useTranslations } from '@/lib/i18n';

import { EmptyProposalsState } from './EmptyProposalsState';
import {
ProposalCard,
ProposalCardContent,
Expand All @@ -18,14 +19,14 @@ import {
const NoProposalsFound = () => {
const t = useTranslations();
return (
<EmptyProposalsState>
<EmptyState icon={<LuLeaf className="size-6" />}>
<Header3 className="font-serif !text-title-base font-light text-neutral-black">
{t('No results yet for this decision.')}
</Header3>
<p className="text-base text-neutral-charcoal">
{t('Results are still being worked on.')}
</p>
</EmptyProposalsState>
</EmptyState>
);
};

Expand Down
7 changes: 4 additions & 3 deletions apps/app/src/components/decisions/pages/ResultsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import { APIErrorBoundary } from '@/utils/APIErrorBoundary';
import { trpc } from '@op/api/client';
import { match } from '@op/core';
import { EmptyState } from '@op/ui/EmptyState';
import { Header3 } from '@op/ui/Header';
import { Skeleton } from '@op/ui/Skeleton';
import { Suspense } from 'react';
import { LuLeaf } from 'react-icons/lu';

import { useTranslations } from '@/lib/i18n/routing';

Expand All @@ -15,7 +17,6 @@ import {
DecisionResultsTabPanel,
DecisionResultsTabs,
} from '../DecisionResultsTabs';
import { EmptyProposalsState } from '../EmptyProposalsState';
import { MyBallot, NoVoteFound } from '../MyBallot';
import { ProposalListSkeleton } from '../ProposalsList';
import { ResultsList } from '../ResultsList';
Expand Down Expand Up @@ -146,14 +147,14 @@ function ResultsPageContent({
<APIErrorBoundary
fallbacks={{
404: (
<EmptyProposalsState>
<EmptyState icon={<LuLeaf className="size-6" />}>
<Header3 className="font-serif !text-title-base font-light text-neutral-black">
{t('Results are still being processed.')}
</Header3>
<p className="text-base text-neutral-charcoal">
{t('Check back again shortly for the results.')}
</p>
</EmptyProposalsState>
</EmptyState>
),
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import { getUniqueSubmitters } from '@/utils/proposalUtils';
import { trpc } from '@op/api/client';
import { match } from '@op/core';
import { EmptyState } from '@op/ui/EmptyState';
import { Header3 } from '@op/ui/Header';
import { Suspense } from 'react';
import { LuLeaf } from 'react-icons/lu';

import { useTranslations } from '@/lib/i18n/routing';

import { DecisionActionBar } from '../DecisionActionBar';
import { DecisionHero } from '../DecisionHero';
import { EmptyProposalsState } from '../EmptyProposalsState';
import { MemberParticipationFacePile } from '../MemberParticipationFacePile';
import { ProposalListSkeleton, ProposalsList } from '../ProposalsList';

Expand Down Expand Up @@ -135,14 +136,14 @@ export function StandardDecisionPage({
<div className="w-full gap-8 p-4 sm:max-w-6xl sm:p-8">
<div className="lg:col-span-3">
{proposals.length === 0 ? (
<EmptyProposalsState>
<EmptyState icon={<LuLeaf className="size-6" />}>
<Header3 className="font-serif !text-title-base font-light text-neutral-black">
{t('No proposals yet')}
</Header3>
<p className="text-base text-neutral-charcoal">
{t('You could be the first one to submit a proposal')}
</p>
</EmptyProposalsState>
</EmptyState>
) : (
<Suspense fallback={<ProposalListSkeleton />}>
<ProposalsList
Expand Down
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"./DatePicker": "./src/components/DatePicker.tsx",
"./Dialog": "./src/components/Dialog.tsx",
"./DropDownButton": "./src/components/DropDownButton.tsx",
"./EmptyState": "./src/components/EmptyState.tsx",
"./Field": "./src/components/Field.tsx",
"./Form": "./src/components/Form.tsx",
"./Header": "./src/components/Header.tsx",
Expand Down
21 changes: 21 additions & 0 deletions packages/ui/src/components/EmptyState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { ReactNode } from 'react';
import { LuCircleAlert } from 'react-icons/lu';

export const EmptyState = ({
icon,
children,
}: {
icon?: ReactNode;
children: ReactNode;
}) => {
return (
<div className="flex min-h-40 w-full flex-col items-center justify-center py-6">
<div className="flex flex-col items-center justify-center gap-4 text-neutral-gray4">
<div className="flex size-10 items-center justify-center gap-4 rounded-full bg-neutral-gray1">
{icon ?? <LuCircleAlert />}
</div>
{children}
</div>
</div>
);
};
5 changes: 2 additions & 3 deletions packages/ui/src/components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ import {
import { LuArrowDown } from 'react-icons/lu';
import { twJoin, twMerge } from 'tailwind-merge';

import { cx } from '@/lib/primitive';

import { Checkbox } from '@/components/Checkbox';
import { cx } from '../../lib/primitive';
import { Checkbox } from '../Checkbox';

interface TableProps extends Omit<TablePrimitiveProps, 'className'> {
allowResize?: boolean;
Expand Down
73 changes: 73 additions & 0 deletions packages/ui/stories/EmptyState.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { LuFileText, LuInbox, LuSearch, LuUsers } from 'react-icons/lu';

import { Button } from '../src/components/Button';
import { EmptyState } from '../src/components/EmptyState';

export default {
title: 'EmptyState',
component: EmptyState,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
};

export const Default = () => (
<EmptyState>
<p>No items found</p>
</EmptyState>
);

export const WithCustomIcon = () => (
<EmptyState icon={<LuInbox />}>
<p>Your inbox is empty</p>
</EmptyState>
);

export const WithDescription = () => (
<EmptyState icon={<LuSearch />}>
<p className="font-medium">No results found</p>
<p className="text-sm">Try adjusting your search or filters</p>
</EmptyState>
);

export const WithAction = () => (
<EmptyState icon={<LuUsers />}>
<p className="font-medium">No team members</p>
<p className="mb-3 text-sm">
Get started by inviting your first team member
</p>
<Button size="small">Invite Member</Button>
</EmptyState>
);

export const Examples = () => (
<div className="grid w-full max-w-3xl grid-cols-2 gap-8">
<div className="rounded-lg border border-neutral-gray2 p-4">
<EmptyState>
<p>No items found</p>
</EmptyState>
</div>

<div className="rounded-lg border border-neutral-gray2 p-4">
<EmptyState icon={<LuInbox />}>
<p>Your inbox is empty</p>
</EmptyState>
</div>

<div className="rounded-lg border border-neutral-gray2 p-4">
<EmptyState icon={<LuSearch />}>
<p className="font-medium">No results found</p>
<p className="text-sm">Try adjusting your search</p>
</EmptyState>
</div>

<div className="rounded-lg border border-neutral-gray2 p-4">
<EmptyState icon={<LuFileText />}>
<p className="font-medium">No documents</p>
<p className="mb-3 text-sm">Upload your first document</p>
<Button size="small">Upload</Button>
</EmptyState>
</div>
</div>
);