Skip to content

Commit

Permalink
Update Collective profile prototype (#10678)
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavlrsn authored Dec 2, 2024
1 parent 98b3bf2 commit ea43064
Show file tree
Hide file tree
Showing 53 changed files with 2,615 additions and 1,004 deletions.
23 changes: 23 additions & 0 deletions components/crowdfunding-redesign/AccountsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';

import { AccountsSublist } from './AccountsSublist';

export default function AccountsList({ data, queryFilter, metric }) {
const currency = data?.account?.[metric.id]?.current?.currency;

const meta = {
queryFilter,
currency: currency,
isAmount: !!metric.amount,
metric,
};

return (
<div className="space-y-8">
<AccountsSublist label="Main account" type="COLLECTIVE" data={data} metric={metric} meta={meta} />
<AccountsSublist label="Projects" type="PROJECT" data={data} metric={metric} meta={meta} />

<AccountsSublist label="Events" type="EVENT" data={data} metric={metric} meta={meta} />
</div>
);
}
82 changes: 82 additions & 0 deletions components/crowdfunding-redesign/AccountsSublist.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import { isNil, omit } from 'lodash';
import { ArrowUp10, ChevronRight } from 'lucide-react';
import { useRouter } from 'next/router';

import type { AccountMetricsFragment } from '../../lib/graphql/types/v2/graphql';

import { getPercentageDifference } from '../dashboard/sections/overview/Metric';
import FormattedMoneyAmount from '../FormattedMoneyAmount';
import Link from '../Link';
import { Button } from '../ui/Button';

import { triggerPrototypeToast } from './helpers';

type AccountMetricsRow = AccountMetricsFragment & {
current: number;
comparison?: number;
percentageDifference?: number;
};

export function AccountsSublist({ label, type, data, metric, meta }) {
const router = useRouter();
const columnData: AccountMetricsRow[] = React.useMemo(() => {
const nodes = data
? [omit(data?.account, 'childrenAccounts'), ...(data?.account.childrenAccounts.nodes ?? [])]
: [];
const filteredNodes = nodes.filter(node => node.type === type);

return filteredNodes.map(node => {
const current = node[metric.id].current.valueInCents ?? node[metric.id].current;
const comparison = node[metric.id].comparison?.valueInCents ?? node[metric.id].comparison;
return {
...node,
current: Math.abs(current),
comparison: !isNil(comparison) ? Math.abs(comparison) : undefined,
percentageDifference: getPercentageDifference(current, comparison),
};
});
}, [metric.id, data, type]);

return (
<div className="">
<div className="mb-2 flex items-center justify-between gap-4 px-2">
<h2 className="text-lg font-semibold text-slate-800">{label}</h2>
<Button
variant="ghost"
size="sm"
className={'group/btn -m-2 gap-2 text-foreground'}
onClick={triggerPrototypeToast}
disabled={columnData.length === 1}
>
<span>{metric.id === 'balance' ? 'Balance' : metric.label}</span>
<ArrowUp10 className="h-4 w-4 text-muted-foreground transition-colors" />
</Button>
</div>
<div className="flex flex-col divide-y overflow-hidden rounded-xl border bg-background">
{columnData
.sort((a, b) => b.current - a.current)
.map(account => (
<Link
key={account.id}
className="flex items-center justify-between px-4 py-4 hover:bg-muted"
href={`/preview/${router.query.collectiveSlug}/finances/${account.slug}`}
>
<div>{account.name}</div>
<div className="flex items-center gap-2">
<div className="font-medium">
<FormattedMoneyAmount
amount={account.current}
currency={meta.currency}
precision={2}
showCurrencyCode={false}
/>
</div>
<ChevronRight size={20} className="text-muted-foreground" />
</div>
</Link>
))}
</div>
</div>
);
}
30 changes: 30 additions & 0 deletions components/crowdfunding-redesign/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { Slash } from 'lucide-react';

import Link from '../Link';

export function Breadcrumb({ breadcrumbs }) {
return (
<div className="flex items-center gap-2 text-sm font-medium text-muted-foreground">
<Slash size={20} strokeWidth={1} />

{breadcrumbs?.map(({ href, label }, i, a) => {
if (i === a.length - 1) {
return (
<span key={href} className="p-1 text-foreground">
{label}
</span>
);
}
return (
<React.Fragment key={href}>
<Link href={href} className="rounded p-1 hover:bg-muted hover:text-foreground">
<span className="text-muted-foreground">{label}</span>
</Link>
<Slash size={20} strokeWidth={1} />
</React.Fragment>
);
})}
</div>
);
}
56 changes: 56 additions & 0 deletions components/crowdfunding-redesign/ContentOverview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, { useEffect, useState } from 'react';
import { cva } from 'class-variance-authority';
// eslint-disable-next-line no-restricted-imports
import Link from 'next/link';
import sanitizeHtml from 'sanitize-html';

import { triggerPrototypeToast } from './helpers';

export const ContentOverview = ({ content }) => {
const [headings, setHeadings] = useState<string[]>([]);

useEffect(() => {
const parser = new DOMParser();
const doc = parser.parseFromString(content, 'text/html');
const headingElements = doc.querySelectorAll('h3');
const headingTexts = Array.from(headingElements).map(h3 => h3.textContent?.trim() || '');
setHeadings(headingTexts);
}, [content]);

const linkClasses = cva('block border-l-[3px] px-2 text-sm font-semibold hover:text-primary', {
variants: {
active: {
true: 'border-primary/80',
false: 'border-transparent',
},
},
defaultVariants: {
active: false,
},
});

return (
<div className="space-y-4">
<Link href="#" className={linkClasses({ active: true })} onClick={triggerPrototypeToast}>
About
</Link>
{headings.map(heading => {
const sanitizedKey = sanitizeHtml(heading, {
allowedTags: [], // No tags allowed
allowedAttributes: {}, // No attributes allowed
}).replace(/[^a-zA-Z0-9-_]/g, '_'); // Replace unsafe characters

return (
<Link
href="#"
key={sanitizedKey} // Use sanitized and unique key
className={linkClasses()}
onClick={triggerPrototypeToast}
>
{heading}
</Link>
);
})}
</div>
);
};
99 changes: 0 additions & 99 deletions components/crowdfunding-redesign/ContributionsList.tsx

This file was deleted.

49 changes: 0 additions & 49 deletions components/crowdfunding-redesign/CrowdfundingPrototypePage.tsx

This file was deleted.

Loading

0 comments on commit ea43064

Please sign in to comment.