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
2 changes: 1 addition & 1 deletion src/assets/data/revenueData.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"totalRevenue": 100000,
"totalRevenue": 1500000,
"comparedToLastMonth": "+ 4.12 %"
}
37 changes: 37 additions & 0 deletions src/assets/data/revenueDistribution.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"revenueDistribution": {
"totalRevenue": 1500000,
"sources": [
{
"source": "Subscriptions",
"amount": 750000,
"percentage": 50
},
{
"source": "Advertisements",
"amount": 300000,
"percentage": 20
},
{
"source": "YouTube",
"amount": 150000,
"percentage": 10
},
{
"source": "Facebook",
"amount": 50000,
"percentage": 3
},
{
"source": "Spotify Partnerships",
"amount": 200000,
"percentage": 13
},
{
"source": "Affiliate Marketing",
"amount": 50000,
"percentage": 4
}
]
}
}
45 changes: 45 additions & 0 deletions src/features/revenue/components/revenueDistribution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Stack } from "@mui/material";
import { SubSection } from "../../../pages/app/components/subSection";
import { SubSectionCard } from "../../../pages/app/components/SubSectionCard";
import { SubSectionListCard } from "../../../pages/app/components/SubSectionListCard";
import useRevenueData from "../../../states/revenueData/hooks/useRevenueData";
import { RevenueSource } from "../../../states/revenueData/models/revenueSource";

/**
* Component to display the revenue data distribution.
*/
export default function RevenueDistribution() {
const {
isRevenueDistributionDataError,
revenueDistributionData
} = useRevenueData();

// Show error state
if (isRevenueDistributionDataError) {
return <div>Error loading revenue distribution data</div>;
}

return (
<SubSection
title="Revenue Distribution"
content={ (
<Stack spacing={ 1 }>
<SubSectionCard
title="Total Revenue"
content={ revenueDistributionData?.totalRevenue.toLocaleString() || "N/A" }
/>
<SubSectionListCard
key="distribution-list"
contentList={
revenueDistributionData?.sources.map((source: RevenueSource, index: number) => ({
number: `${index + 1}`,
subtitle: `${source.amount} - ${source.percentage}%`,
title: source.source
})) || []
}
/>
</Stack>
) }
/>
);
}
2 changes: 2 additions & 0 deletions src/features/revenue/layout/revenueLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Stack from "@mui/material/Stack";
import RevenueDataAnalysis from "../components/revenueDataAnalysis";
import RevenueDataAnalysisChart from "../components/revenueDataAnalysisChart";
import RevenueDistribution from "../components/revenueDistribution";

export default function RevenueLayout() {
return (
<Stack spacing={ 4 }>
<RevenueDataAnalysis />
<RevenueDataAnalysisChart />
<RevenueDistribution />
</Stack>
);
}
17 changes: 11 additions & 6 deletions src/pages/app/components/SubSectionListCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface SubSectionListCardItem {
/**
* image URL
*/
imageUrl: string;
imageUrl?: string;
}

interface SubSectionListCardProps {
Expand Down Expand Up @@ -63,11 +63,16 @@ export const SubSectionListCard: FunctionComponent<SubSectionListCardProps> = (
{ addLeadingZero(contentItem.number) }
</Typography>
</Grid>
<img
className={ styles.subSectionListCardImage }
src={ contentItem.imageUrl }
alt="random"
/>
{
contentItem.imageUrl
&& (
<img
className={ styles.subSectionListCardImage }
src={ contentItem.imageUrl }
alt="random"
/>
)
}
<Stack justifyContent="center">
<Typography variant="body1">
{ contentItem.title }
Expand Down
9 changes: 9 additions & 0 deletions src/states/revenueData/contexts/revenueDataContext.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context, createContext } from "react";
import { RevenueAnalyticsData } from "../models/revenueAnalyticsData";
import { RevenueData } from "../models/revenueData";
import { RevenueDistribution } from "../models/revenueSource";

/**
* Props interface for RevenueDataContext.
Expand All @@ -22,6 +23,14 @@ export interface RevenueDataContextProps {
* Flag indicating if an error occurred while loading the revenue analytics data.
*/
isRevenueAnalyticsDataError: boolean;
/**
* Revenue distribution data.
*/
revenueDistributionData: RevenueDistribution | null;
/**
* Flag indicating if an error occurred while loading the revenue distribution data.
*/
isRevenueDistributionDataError: boolean;
}

/**
Expand Down
34 changes: 34 additions & 0 deletions src/states/revenueData/models/revenueSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Represents a single revenue source with its amount and percentage share.
*/
export interface RevenueSource {
/**
* The name of the revenue source (e.g., Subscriptions, Advertisements, YouTube).
*/
source: string;

/**
* The amount of revenue generated from this source.
*/
amount: number;

/**
* The percentage contribution of this source to the total revenue.
*/
percentage: number;
}

/**
* Represents the overall revenue distribution of Streamify.
*/
export interface RevenueDistribution {
/**
* The total revenue generated from all sources.
*/
totalRevenue: number;

/**
* A list of different revenue sources contributing to the total revenue.
*/
sources: RevenueSource[];
}
23 changes: 21 additions & 2 deletions src/states/revenueData/providers/revenueDataProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { FunctionComponent, PropsWithChildren, ReactElement, useMemo, useState } from "react";
import revenueAnalyticsDataJson from "../../../assets/data/revenueAnalytics.json";
import revenueDataJson from "../../../assets/data/revenueData.json";
import revenueDistributionDataJson from "../../../assets/data/revenueDistribution.json";
import RevenueDataContext from "../contexts/revenueDataContext";
import { RevenueAnalyticsData } from "../models/revenueAnalyticsData";
import { RevenueData } from "../models/revenueData";
import { RevenueDistribution } from "../models/revenueSource";

/**
* Props interface for the [RevenueDataProvider]
Expand All @@ -22,9 +24,11 @@ const RevenueDataProvider: FunctionComponent<RevenueDataProviderProps> = (
const { children } = props;

const [ isRevenueDataError, setIsRevenueDataError ] = useState<boolean>(false);
const [ RevenueData, setRevenueData ] = useState<RevenueData | null>(null);
const [ revenueData, setRevenueData ] = useState<RevenueData | null>(null);
const [ isRevenueAnalyticsDataError, setIsRevenueAnalyticsDataError ] = useState<boolean>(false);
const [ revenueAnalyticsData, setRevenueAnalyticsData ] = useState<RevenueAnalyticsData | null>(null);
const [ isRevenueDistributionDataError, setIsRevenueDistributionDataError ] = useState<boolean>(false);
const [ revenueDistributionData, setRevenueDistributionData ] = useState<RevenueDistribution | null>(null);

// Load the revenue data
useMemo(() => {
Expand Down Expand Up @@ -52,13 +56,28 @@ const RevenueDataProvider: FunctionComponent<RevenueDataProviderProps> = (
}
}, [ revenueAnalyticsDataJson ]);

// Load the revenue distribution data
useMemo(() => {
try {
if (revenueDistributionDataJson) {
setRevenueDistributionData(revenueDistributionDataJson.revenueDistribution);
setIsRevenueDistributionDataError(false);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (error) {
setIsRevenueDistributionDataError(true);
}
}, [ revenueDistributionDataJson ]);

return (
<RevenueDataContext.Provider
value={ {
isRevenueAnalyticsDataError: isRevenueAnalyticsDataError,
isRevenueDataError: isRevenueDataError,
isRevenueDistributionDataError: isRevenueDistributionDataError,
revenueAnalyticsData: revenueAnalyticsData,
revenueData: RevenueData
revenueData: revenueData,
revenueDistributionData: revenueDistributionData
} }
>
{ children }
Expand Down