Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

536 add funding endpoint #540

Merged
merged 8 commits into from
May 21, 2024
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
26 changes: 26 additions & 0 deletions packages/api/src/fetchForumQuestionFunding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { GetFundingResponse } from './types';

async function fetchForumQuestionFunding(questionId: string): Promise<GetFundingResponse | null> {
try {
const response = await fetch(
`${import.meta.env.VITE_SERVER_URL}/api/forum-questions/${questionId}/funding`,
{
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
},
);
if (!response.ok) {
throw new Error(`HTTP Error! Status: ${response.status}`);
}

const stats = (await response.json()) as { data: GetFundingResponse };
return stats.data;
} catch (error) {
console.error('Error fetching forum question funding:', error);
return null;
}
}

export default fetchForumQuestionFunding;
1 change: 1 addition & 0 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { default as fetchEvent } from './fetchEvent';
export { default as fetchEventCycles } from './fetchEventCycles';
export { default as fetchEvents } from './fetchEvents';
export { default as fetchForumQuestionStatistics } from './fetchForumQuestionStatistics';
export { default as fetchForumQuestionFunding } from './fetchForumQuestionFunding';
export { default as fetchGroupCategories } from './fetchGroupCategories';
export { default as fetchGroupMembers } from './fetchGroupMembers';
export { default as fetchGroupRegistrations } from './fetchGroupRegistrations';
Expand Down
6 changes: 6 additions & 0 deletions packages/api/src/types/FundingType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type GetFundingResponse = {
allocated_funding: {
[key: string]: number;
};
remaining_funding: number;
};
1 change: 1 addition & 0 deletions packages/api/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './CommentType';
export * from './CycleType';
export * from './EventType';
export * from './ForumQuestionType';
export * from './FundingType';
export * from './GroupCategoryType';
export * from './GroupMembersType';
export * from './GroupRegistrationsType';
Expand Down
47 changes: 34 additions & 13 deletions packages/berlin/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ async function redirectOnLandingLoader(queryClient: QueryClient) {
}

if (events?.length === 1) {
const registrations = await queryClient.fetchQuery({
queryKey: ['event', events?.[0].id, 'registrations'],
queryFn: () => fetchRegistrations(events?.[0].id || ''),
});

if (registrations && registrations.some((registration) => registration.status === 'APPROVED')) {
return redirect(`/events/${events?.[0].id}/register`);
}

return redirect(`/events/${events?.[0].id}/cycles`);
}

Expand All @@ -114,7 +123,6 @@ async function redirectToOnlyOneEventLoader(queryClient: QueryClient) {

/**
* Redirects the user to the register page if they are not registered
* Redirects the user to register page if they any approved registrations
* Redirects the user to the holding page if they don't have any approved registrations
*/
async function redirectToEventHoldingOrRegister(queryClient: QueryClient, eventId?: string) {
Expand All @@ -123,15 +131,15 @@ async function redirectToEventHoldingOrRegister(queryClient: QueryClient, eventI
queryFn: () => fetchRegistrations(eventId || ''),
});

if (
!registrations ||
!registrations.length ||
registrations.some((registration) => registration.status === 'APPROVED')
) {
if (!registrations || !registrations.length) {
return redirect(`/events/${eventId}/register`);
}

return redirect(`/events/${eventId}/holding`);
if (!registrations.some((registration) => registration.status === 'APPROVED')) {
return redirect(`/events/${eventId}/holding`);
}

return null;
}

/**
Expand Down Expand Up @@ -172,16 +180,29 @@ async function redirectToCycleIfOpen(queryClient: QueryClient, eventId?: string,

const router = (queryClient: QueryClient) =>
createBrowserRouter([
{ path: '/popup', element: <PassportPopupRedirect /> },
{
path: '/popup',
element: <PassportPopupRedirect />,
},
{
element: <BerlinLayout />,
children: [
{ path: '/', loader: () => redirectOnLandingLoader(queryClient), element: <Landing /> },
{
path: '/',
loader: () => redirectOnLandingLoader(queryClient),
element: <Landing />,
},
{
loader: () => redirectToLandingLoader(queryClient),
children: [
{ path: '/onboarding', Component: Onboarding },
{ path: '/data-policy', Component: DataPolicy },
{
path: '/onboarding',
Component: Onboarding,
},
{
path: '/data-policy',
Component: DataPolicy,
},
{
path: '/account',
Component: Account,
Expand Down Expand Up @@ -212,9 +233,9 @@ const router = (queryClient: QueryClient) =>
Component: Holding,
},
{
path: ':eventId/cycles',
loader: ({ params }) =>
redirectToEventHoldingOrRegister(queryClient, params.eventId),
path: ':eventId/cycles',
children: [
{
path: '',
Expand All @@ -227,9 +248,9 @@ const router = (queryClient: QueryClient) =>
Component: Cycle,
},
{
path: ':cycleId/results',
loader: ({ params }) =>
redirectToCycleIfOpen(queryClient, params.eventId, params.cycleId),
path: ':cycleId/results',
Component: Results,
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import styled from 'styled-components';
import { Grid } from '../../containers/Grid.styled';

export const Card = styled(Grid)`
export const Card = styled(Grid)<{ $showFunding: boolean }>`
border-bottom: 2px solid var(--color-black);
grid-template-columns: ${(props) =>
props.$showFunding ? 'auto repeat(3, 48px) 100px' : 'auto repeat(3, 48px)'};
padding: 1.5rem;
grid-template-columns: auto repeat(3, 48px) 80px;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import IconButton from '../../icon-button';
import { Bold } from '../../typography/Bold.styled';
import { Card } from './ResultsColumns.styled';

function ResultsColumns() {
type ResultsColumnsType = {
$showFunding: boolean;
};

function ResultsColumns({ $showFunding }: ResultsColumnsType) {
const theme = useAppStore((state) => state.theme);
return (
<Card>
<Card $showFunding={$showFunding}>
<Bold>Title</Bold>
<IconButton
$padding={0}
Expand All @@ -23,11 +27,13 @@ function ResultsColumns() {
$color="secondary"
icon={{ src: `/icons/plurality-score.svg`, alt: 'Plurality score' }}
/>
<IconButton
$padding={0}
$color="secondary"
icon={{ src: `/logos/arbitrum-${theme}.svg`, alt: 'Arbitrum' }}
/>
{$showFunding && (
<IconButton
$padding={0}
$color="secondary"
icon={{ src: `/logos/arbitrum-${theme}.svg`, alt: 'Arbitrum' }}
/>
)}
</Card>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import styled from 'styled-components';
import { Grid } from '../../containers/Grid.styled';

export const Card = styled(Grid)<{ $expanded: boolean }>`
cursor: pointer;
export const Card = styled(Grid)<{ $expanded: boolean; $showFunding: boolean }>`
border-bottom: 1px solid var(--color-black);
grid-template-columns: auto repeat(3, 48px) 80px;
cursor: pointer;
grid-template-columns: ${(props) =>
props.$showFunding ? 'auto repeat(3, 48px) 100px' : 'auto repeat(3, 48px)'};
overflow: hidden;
padding: 1.5rem;
position: relative;
Expand All @@ -13,6 +14,6 @@ export const Card = styled(Grid)<{ $expanded: boolean }>`

.description {
display: ${(props) => (props.$expanded ? 'flex' : 'none')};
grid-column: 1/6;
grid-column: ${(props) => (props.$showFunding ? '1/6' : '1/5')};
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type ResultsTableProps = {
distinctGroups: number;
listOfGroupNames: string[];
quadraticScore: string;
allocatedFunding: number | null;
id: string;
};
onClick: () => void;
Expand All @@ -44,7 +45,12 @@ function ResultsTable({ $expanded, option, onClick }: ResultsTableProps) {
}, [option.pluralityScore]);

return (
<Card $expanded={$expanded} onClick={onClick} $rowgap="2rem">
<Card
$expanded={$expanded}
$showFunding={!!option.allocatedFunding}
onClick={onClick}
$rowgap="2rem"
>
<FlexRow>
<IconButton
$padding={0}
Expand All @@ -57,7 +63,7 @@ function ResultsTable({ $expanded, option, onClick }: ResultsTableProps) {
<Body>{option.allocatedHearts}</Body>
<Body>{formattedQuadraticScore}</Body>
<Body>{formattedPluralityScore}</Body>
<Body>$ 10.000</Body>
{option.allocatedFunding !== null && <Body>{option.allocatedFunding} ARB</Body>}
<FlexColumn className="description">
<Body>{option.optionSubTitle}</Body>
<Body>
Expand Down
12 changes: 10 additions & 2 deletions packages/berlin/src/pages/Results.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { fetchCycle, fetchForumQuestionStatistics } from 'api';
import { fetchCycle, fetchForumQuestionFunding, fetchForumQuestionStatistics } from 'api';
import { FlexColumn } from '../components/containers/FlexColumn.styled';
import { Subtitle } from '../components/typography/Subtitle.styled';
import { useParams } from 'react-router-dom';
Expand All @@ -9,6 +9,7 @@ import ResultsColumns from '../components/columns/results-columns';
import ResultsTable from '../components/tables/results-table';
import StatsTable from '../components/tables/stats-table';
import StatsColumns from '../components/columns/stats-columns';
import { FINAL_QUESTION_TITLE } from '../utils/constants';

function Results() {
const [expandedIndex, setExpandedIndex] = useState<number | null>(null);
Expand All @@ -29,6 +30,12 @@ function Results() {
retry: false,
});

const { data: funding } = useQuery({
queryKey: ['funding', cycle?.forumQuestions[0].id],
queryFn: () => fetchForumQuestionFunding(cycle?.forumQuestions[0].id || ''),
enabled: !!cycle?.id && cycle?.forumQuestions?.[0].questionTitle === FINAL_QUESTION_TITLE,
});

const overallStatistics = [
{
id: 0,
Expand Down Expand Up @@ -56,6 +63,7 @@ function Results() {
.map(([id, stats]) => ({
id,
...stats,
allocatedFunding: funding?.allocated_funding[id] || null,
}))
.sort((a, b) => parseFloat(b.pluralityScore) - parseFloat(a.pluralityScore));

Expand All @@ -64,7 +72,7 @@ function Results() {
<BackButton />
<Subtitle>Results for: {cycle?.forumQuestions?.[0].questionTitle}</Subtitle>
<FlexColumn $gap="0">
<ResultsColumns />
<ResultsColumns $showFunding={!!funding} />
{optionStatsArray.map((option, index) => (
<ResultsTable
key={option.id}
Expand Down
1 change: 1 addition & 0 deletions packages/berlin/src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const INITIAL_HEARTS = 80;
export const FIVE_MINUTES_IN_SECONDS = 300;
export const FINAL_QUESTION_TITLE = 'Which research should receive a share of 100,000 ARB?';
Loading