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

Update landing page stats #444

Merged
merged 6 commits into from
Nov 8, 2022
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
11 changes: 11 additions & 0 deletions backend/app/controllers/stats_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ def index
contribution_amount_from_secondary_donors = SecondaryDonation.sum(:amount)
@total_contribution_amount = contribution_amount_from_primary_donor + contribution_amount_from_secondary_donors

@total_redemption_count = redemptions.count
@total_charities_supported = CampaignCharity.distinct.count(:charity_id)
end

def steps
redemptions = Redemption.includes(:coupon).all

contribution_amount_from_primary_donor = redemptions.map { |r| r.coupon.denomination }.sum
contribution_amount_from_secondary_donors = SecondaryDonation.sum(:amount)
@total_contribution_amount = contribution_amount_from_primary_donor + contribution_amount_from_secondary_donors

@total_redemption_count = redemptions.count
end
end
1 change: 1 addition & 0 deletions backend/app/views/stats/index.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

json.totalContributionAmount @total_contribution_amount
json.totalRedemptionCount @total_redemption_count
json.totalCharitiesSupported @total_charities_supported
4 changes: 4 additions & 0 deletions backend/app/views/stats/steps.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.totalContributionAmount @total_contribution_amount
json.totalRedemptionCount @total_redemption_count
6 changes: 5 additions & 1 deletion backend/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
token_validations: 'auth/token_validations'
}

get 'stats', to: 'stats#index'
resources :stats, only: %i[index] do
collection do
get 'steps'
end
end

resources :campaigns do
collection do
Expand Down
8 changes: 6 additions & 2 deletions frontend/frontendApis/stats.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ApiPromise } from '../types/api';
import { SummaryData } from '../types/summary';
import { LandingPageStatsData, StepsStatsData } from '../types/summary';
import BaseAPI from './base';

class StatsAPI extends BaseAPI {
static STATS_URL = 'stats';

public getSummaryStats(): ApiPromise<SummaryData> {
public getLandingPageStats(): ApiPromise<LandingPageStatsData> {
return this.get(StatsAPI.STATS_URL);
}

public getStepsStats(): ApiPromise<StepsStatsData> {
return this.get(`${StatsAPI.STATS_URL}/steps`);
}
}

export default StatsAPI;
47 changes: 34 additions & 13 deletions frontend/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import GitHubIcon from '@mui/icons-material/GitHub';
import InstagramIcon from '@mui/icons-material/Instagram';
import LocalActivityIcon from '@mui/icons-material/LocalActivity';
import VolunteerActivismIcon from '@mui/icons-material/VolunteerActivism';
import { Avatar, Grid, Tooltip, Typography, useMediaQuery } from '@mui/material';
import { Avatar, Grid, Skeleton, Tooltip, Typography, useMediaQuery } from '@mui/material';
import { Box, Stack, useTheme } from '@mui/system';
import type { NextPage } from 'next';
import Head from 'next/head';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { ReactNode } from 'react';
import Typed from 'react-typed';
import useSWR from 'swr';
import Button from '../components/generic/Button';
import api from '../frontendApis';
import StatsAPI from '../frontendApis/stats';
import {
callToActionIconAvatarSx,
callToActionIconSx,
Expand Down Expand Up @@ -69,12 +72,14 @@ import {
statisticsMainTextSx,
statisticsSectionSx,
} from '../styles/indexStyles';
import { LandingPageStatsData } from '../types/summary';
import { Nullable } from '../types/utils';
import { log } from '../utils/analytics';
import { theme } from '../utils/theme';
import { combineSxProps } from '../utils/types';

interface StatisticItemProps {
statistic: string;
statistic?: Nullable<string | number>;
icon: ReactNode;
description: string;
}
Expand All @@ -85,7 +90,11 @@ const StatisticItem = ({ statistic, icon, description }: StatisticItemProps) =>
<Stack sx={statisticsItemCardSx} component="div" spacing={1}>
<Avatar sx={statisticsIconAvatarSx}>{icon}</Avatar>

<Typography sx={statisticsMainTextSx}>{statistic}</Typography>
{statistic ? (
<Typography sx={statisticsMainTextSx}>{statistic}</Typography>
) : (
<Skeleton width="50%" height="60px" />
)}

<Typography color={theme.palette.grey[800]}>{description}</Typography>
</Stack>
Expand Down Expand Up @@ -155,17 +164,11 @@ const SectionHeader = ({ title, subtitle = [] }: SectionHeaderProps) => (
</Stack>
);

const statistics: StatisticItemProps[] = [
{
statistic: '$1600',
icon: <VolunteerActivismIcon sx={statisticsIconSx} />,
description: 'Raised for charities',
},
{ statistic: '160', icon: <LocalActivityIcon sx={statisticsIconSx} />, description: 'Coupons distributed' },
{ statistic: '8', icon: <Diversity1Icon sx={statisticsIconSx} />, description: 'Charities supported' },
];

const Home: NextPage = () => {
const { data: stats } = useSWR<Nullable<LandingPageStatsData>>(StatsAPI.STATS_URL, () =>
api.stats.getLandingPageStats().then((r) => r.payload),
);

const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));
const router = useRouter();
Expand Down Expand Up @@ -207,6 +210,24 @@ const Home: NextPage = () => {
},
];

const statistics: StatisticItemProps[] = [
{
statistic: stats && `$${stats.totalContributionAmount}`,
icon: <VolunteerActivismIcon sx={statisticsIconSx} />,
description: 'Raised for charities',
},
{
statistic: stats?.totalRedemptionCount,
icon: <LocalActivityIcon sx={statisticsIconSx} />,
description: 'Coupons redeemed',
},
{
statistic: stats?.totalCharitiesSupported,
icon: <Diversity1Icon sx={statisticsIconSx} />,
description: 'Charities supported',
},
];

return (
<Box>
<Head>
Expand Down
18 changes: 9 additions & 9 deletions frontend/pages/stats.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Skeleton, Stack, Typography, Box } from '@mui/material';
import { Box, Skeleton, Stack, Typography } from '@mui/material';
import Head from 'next/head';
import useSWR from 'swr';
import AnimatedNumber from '../components/AnimatedNumber';
import GlassCard from '../components/GlassCard';
import api from '../frontendApis';
import StatsAPI from '../frontendApis/stats';
import { rootSx, numberSx, ctaSx, leftSectionSx } from '../styles/statsStyles';
import { SummaryData } from '../types/summary';
import { ctaSx, leftSectionSx, numberSx, rootSx } from '../styles/statsStyles';
import { StepsStatsData } from '../types/summary';
import { Nullable } from '../types/utils';
import { theme } from '../utils/theme';
import GlassCard from '../components/GlassCard';
import AnimatedNumber from '../components/AnimatedNumber';
import Head from 'next/head';

function Stats() {
const { data: stats } = useSWR<Nullable<SummaryData>>(
const { data: stats } = useSWR<Nullable<StepsStatsData>>(
StatsAPI.STATS_URL,
() => api.stats.getSummaryStats().then((r) => r.payload),
() => api.stats.getStepsStats().then((r) => r.payload),
{ refreshInterval: 5000, refreshWhenHidden: true },
);

Expand All @@ -23,7 +23,7 @@ function Stats() {
return (
<Stack direction="row" spacing={2} sx={rootSx}>
<Head>
<title>STePs Statistics</title>
<title>STePS Statistics</title>
</Head>

<Box sx={leftSectionSx}>
Expand Down
8 changes: 7 additions & 1 deletion frontend/types/summary.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export type SummaryData = {
export type LandingPageStatsData = {
totalContributionAmount: number;
totalRedemptionCount: number;
totalCharitiesSupported: number;
};

export type StepsStatsData = {
totalContributionAmount: number;
totalRedemptionCount: number;
};