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

feat: implement the asyncapi financial summary page #2038

Merged
merged 95 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from 89 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
cd47497
created new file and added basic content
vishvamsinh28 Aug 6, 2023
cbb9d71
completed till other forms of support
vishvamsinh28 Aug 6, 2023
997f6b7
improved table design
vishvamsinh28 Aug 6, 2023
ddc4ff9
made design more responsive
vishvamsinh28 Aug 7, 2023
3f1b1ee
added Expense breakdown component
vishvamsinh28 Aug 7, 2023
e2352e1
added succes stories component
vishvamsinh28 Aug 7, 2023
31a019c
added Contact Us component
vishvamsinh28 Aug 7, 2023
fe9a006
graph added
vishvamsinh28 Aug 8, 2023
c5473cb
graph added and removed some bugs
vishvamsinh28 Aug 8, 2023
9a6634c
made separate files for components
vishvamsinh28 Aug 8, 2023
8a7d5b7
improved design
vishvamsinh28 Aug 8, 2023
a5e018e
expense object updated
vishvamsinh28 Aug 8, 2023
6710e46
added icons and enhanced design
vishvamsinh28 Aug 8, 2023
fea4e1f
added id's to headings
vishvamsinh28 Aug 8, 2023
9132a0c
added link to get more details of budget
vishvamsinh28 Aug 8, 2023
a8c7197
design updated
vishvamsinh28 Aug 9, 2023
05a3b0b
Merge branch 'master' into FinanceSummary#1723
Mayaleeeee Aug 9, 2023
f512471
design improvements
vishvamsinh28 Aug 9, 2023
7830729
design improvement
vishvamsinh28 Aug 9, 2023
4eb000b
bar chart improments
vishvamsinh28 Aug 9, 2023
fce3d68
added table for smaller devices
vishvamsinh28 Aug 9, 2023
f66dfbc
wide screen issue fixed
vishvamsinh28 Aug 10, 2023
935d250
table title clickable
vishvamsinh28 Aug 10, 2023
c7a255e
table header link
vishvamsinh28 Aug 10, 2023
2766fbb
added yaml files for expenses
vishvamsinh28 Aug 13, 2023
ad78052
created function for converting yaml data to json
vishvamsinh28 Aug 14, 2023
394eb13
modifies graph component for new data structure
vishvamsinh28 Aug 14, 2023
4b2ba9b
images extension changes
vishvamsinh28 Aug 27, 2023
ac5f32b
images extension changes
vishvamsinh28 Aug 27, 2023
5ef718f
design updates
vishvamsinh28 Sep 3, 2023
b7e90da
sponsorship tier reposiveness issue fixed
vishvamsinh28 Sep 4, 2023
e877ff2
made requested changes
vishvamsinh28 Sep 4, 2023
2fcfea9
design changes
vishvamsinh28 Sep 4, 2023
73a2bed
Merge branch 'master' of https://github.com/vishvamsinh28/website int…
vishvamsinh28 Sep 4, 2023
97faac2
mobile links click fix
vishvamsinh28 Sep 4, 2023
0646a89
commit conflict fix
vishvamsinh28 Sep 4, 2023
7a4b2c8
json data issue fix
vishvamsinh28 Sep 4, 2023
aa81682
json data issue fix
vishvamsinh28 Sep 4, 2023
51a36d4
design changes
vishvamsinh28 Sep 7, 2023
93924d2
requested changes made
vishvamsinh28 Oct 7, 2023
e74374c
Merge branch 'master' into FinanceSummary#1723
vishvamsinh28 Oct 11, 2023
48f50f9
requested changes made
vishvamsinh28 Oct 11, 2023
2ecfe5c
Merge branch 'FinanceSummary#1723' of https://github.com/vishvamsinh2…
vishvamsinh28 Oct 11, 2023
e1acedb
bug fix
vishvamsinh28 Oct 11, 2023
0ee8aff
Merge branch 'master' into FinanceSummary#1723
akshatnema Oct 12, 2023
485cedb
text alignment
vishvamsinh28 Oct 26, 2023
2e9fe8b
design updates
vishvamsinh28 Oct 27, 2023
1b6658f
Merge branch 'FinanceSummary#1723' of https://github.com/vishvamsinh2…
vishvamsinh28 Oct 27, 2023
26a8951
removed json files
vishvamsinh28 Oct 27, 2023
3221463
json files
vishvamsinh28 Oct 27, 2023
c27b7bf
json files
vishvamsinh28 Oct 27, 2023
306a303
added json files
vishvamsinh28 Oct 27, 2023
9f286f5
code updates
vishvamsinh28 Oct 27, 2023
ddfecc5
design updates
vishvamsinh28 Oct 28, 2023
2764a1d
fix
vishvamsinh28 Oct 28, 2023
80c38bc
category code updates
vishvamsinh28 Nov 1, 2023
cbb46a5
expense design updates
vishvamsinh28 Nov 7, 2023
82de3eb
bar chart design updates
vishvamsinh28 Nov 7, 2023
79d3d16
design improvements
vishvamsinh28 Nov 17, 2023
56da3a9
code updated
vishvamsinh28 Nov 21, 2023
529ca9d
testing
vishvamsinh28 Nov 21, 2023
8b4e67d
testing
vishvamsinh28 Nov 21, 2023
b16042a
file name change
vishvamsinh28 Nov 21, 2023
2630a6d
file name change
vishvamsinh28 Nov 21, 2023
908cfa2
file name change
vishvamsinh28 Nov 21, 2023
ff03b60
file name change
vishvamsinh28 Nov 21, 2023
8353b7e
json files added
vishvamsinh28 Nov 21, 2023
15290c3
json files removed from pr
vishvamsinh28 Nov 23, 2023
ae5ac3f
json files removed from pr
vishvamsinh28 Nov 23, 2023
ee13a35
json files issue
vishvamsinh28 Nov 23, 2023
4e2bb16
json file testing
vishvamsinh28 Nov 23, 2023
97db4a9
testing2
vishvamsinh28 Nov 23, 2023
5af477c
testing2
vishvamsinh28 Nov 23, 2023
4d46e5b
testing2
vishvamsinh28 Nov 23, 2023
7a86a0a
json files issue fixed
vishvamsinh28 Nov 23, 2023
4d9cdfd
conflict resolve
vishvamsinh28 Nov 24, 2023
e3080da
Merge branch 'master' into FinanceSummary#1723
vishvamsinh28 Nov 24, 2023
dbe683c
json files update
vishvamsinh28 Nov 24, 2023
1c2536a
Merge branch 'FinanceSummary#1723' of https://github.com/vishvamsinh2…
vishvamsinh28 Nov 24, 2023
08b20ce
conflict resolved
vishvamsinh28 Nov 24, 2023
eef441d
timeout issue fixed
vishvamsinh28 Nov 24, 2023
ad1a31a
timeout issue
vishvamsinh28 Nov 24, 2023
edc0871
Merge branch 'master' of https://github.com/vishvamsinh28/website int…
vishvamsinh28 Nov 28, 2023
0321317
merged with latest commit on master branch
vishvamsinh28 Nov 28, 2023
45db5c7
testing
vishvamsinh28 Dec 4, 2023
af93aab
testing2
vishvamsinh28 Dec 4, 2023
910e9ca
Merge branch 'master' into FinanceSummary#1723
akshatnema Dec 5, 2023
31ea8ca
enhancements
vishvamsinh28 Dec 6, 2023
c614a8e
Merge branch 'FinanceSummary#1723' of https://github.com/vishvamsinh2…
vishvamsinh28 Dec 6, 2023
8abffcc
Merge branch 'master' into FinanceSummary#1723
Mayaleeeee Dec 11, 2023
e03cc99
text center
vishvamsinh28 Dec 11, 2023
2668487
Merge branch 'FinanceSummary#1723' of https://github.com/vishvamsinh2…
vishvamsinh28 Dec 11, 2023
3de80ba
Merge branch 'master' into FinanceSummary#1723
akshatnema Dec 19, 2023
cbef230
design updates
vishvamsinh28 Dec 20, 2023
91e6425
Merge branch 'master' into FinanceSummary#1723
akshatnema Dec 20, 2023
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ meetings.json
.netlify
.env
cypress/screenshots
cypress/videos
cypress/videos
/config/finance/json-data/*
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ npm run build

Generated files of the website go to the `.next` folder.

## Updating information about project finance

AsyncAPI Financial Summary page aims to provide transparency and clarity regarding the organization's financial activities. It serves as a platform to showcase how donations are accepted, different sponsorship options, and how the generated funds are utilized.

### How to update information

- YAML files must be stored in the `config/finance` directory.

- Create separate folders for each year under `config/finance`, such as `config/finance/2023`. Inside each year's folder, include two YAML files: `Expenses.yml` and `ExpensesLink.yml`.

- In `Expenses.yml`, record expenses for each month, specifying the `Category` and `Amount`.

- In `ExpensesLink.yml`, provide discussion links related to expense categories.

- When a new year begins, create a corresponding folder for that year under `config/finance` and place the YAML files inside the folder for that specific year. For example, create a folder named `config/finance/2024` for the year 2024 and `config/finance/2025` for the year 2025. Place the YAML file for each respective year inside its designated folder.

- Modify the years within the `scripts/finance/index.js` , `lib/getUniqueCategories.js` and `components/FinancialSummary/BarChartComponent.js` to handle data for different years effectively.

## Case studies

### Overview
Expand Down
54 changes: 54 additions & 0 deletions components/FinancialSummary/AsyncAPISummary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Button from '../buttons/Button'
import Heading from '../typography/Heading'
import Paragraph from '../typography/Paragraph'

export default function AsyncAPISummary() {
return (
<div className="px-4 sm:px-6 lg:px-8">
<div className="grid lg:grid-cols-9 lg:gap-8 lg:text-center my-8 mx-4">
<div className="col-start-3 col-span-5">
<Heading level="h2" className="text-5xl my-3 mx-3">
AsyncAPI Financial Summary
</Heading>
<Paragraph typeStyle="body-md" className="my-1 max-w-4xl text-darkGunMetal">
To help improve the current state of Event-Driven Architectures and their tooling, you can show your support for
the AsyncAPI Initiative by making a financial contribution. We offer three donation options: <strong>Open Collective, GitHub
Sponsors, and Linux Foundation Crowdfunding</strong>. Our expenses are managed through Open Collective and GitHub Sponsors,
while Linux Foundation Crowdfunding operates separately.
</Paragraph>
</div>
</div>
<div className="flex justify-center mb-20">
<Button
text="Become a Sponsor"
href="https://opencollective.com/asyncapi#category-CONTRIBUTE"
target='_blank'
/>
</div>
<div className="text-center text-sm mt-4">
<Heading level="h1" typeStyle="heading-md" className="4xl">
Ways to Support Us?
</Heading>
</div>
<div className="text-center my-4 text-base max-width text-darkGunMetal">
<Paragraph typeStyle="body-sm" className="my-4">
The easiest way to support AsyncAPI is by becoming a financial sponsor. While <br class="hidden lg:inline-block"></br>there are alternative options,
they may involve greater effort. Contribute <br class="hidden lg:inline-block"></br>monetarily using the following channels.
</Paragraph>
</div>

<div className="text-center">
<a href="https://opencollective.com/asyncapi" target='_blank'>
<img className="mx-4 inline w-10 h-10 transform transition-transform hover:scale-110 active:scale-90" src="/img/logos/OpenCollective.svg" alt="Open Collective" />
</a>
<a href="https://crowdfunding.lfx.linuxfoundation.org/projects/445898e9-42a2-4965-9e0a-c2a714f381bc" target='_blank'>
<img className="mx-4 inline w-10 h-10 transform transition-transform hover:scale-110 active:scale-90" src="/img/logos/LFX.svg" alt="Linux Foundation" />
</a>
<a href="https://github.com/sponsors/asyncapi" target='_blank'>
<img className="mx-4 inline w-10 h-10 transform transition-transform hover:scale-110 active:scale-90" src="/img/logos/github-black.svg" alt="Github" />
</a>
</div>

</div>
);
}
221 changes: 221 additions & 0 deletions components/FinancialSummary/BarChartComponent.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add jsdocs to the functions you defined in this component. Also, can we write these functions in lib folder instead of defining them in UI component file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vishvamsinh28 Kindly address this comment.

Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import React, { useState, useEffect, useRef } from 'react';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts';
import ExpensesLink from '../../config/finance/json-data/2023/ExpensesLink.json';
import Expenses from '../../config/finance/json-data/2023/Expenses.json';
import { getUniqueCategories } from '../../lib/getUniqueCategories';
/**
* CustomTooltip component for the bar chart. Displays additional information on hover.
*
* @param {Object} props - The component's props.
* @param {boolean} props.active - Indicates if the tooltip is active.
* @param {Object[]} props.payload - An array of data points.
* @returns {JSX.Element} The rendered CustomTooltip component.
*/
const CustomTooltip = ({ active, payload }) => {
if (active && payload && payload.length) {
const data = payload[0].payload;
return (
<div className="bg-opacity-90 bg-white border border-gray-300 p-2 shadow-md rounded-md">
<p className="text-14 font-bold mb-1">{data.Category}</p>
<p className="text-12 text-gray-900">${data.Amount.toFixed(2)}</p>
<p>Click the bar to learn more</p>
</div>
);
}
return null;
};

/**
* Retrieves unique expense categories from the Expenses data.
*
* @returns {string[]} An array of unique expense categories.
*/

const months = Object.keys(Expenses);
const categories = getUniqueCategories();

/**
* Card component displays monthly expense data.
*
* @param {Object} props - The component's props.
* @param {string} props.month - The month for which expenses are displayed.
* @param {Object[]} props.data - The expense data for the month.
* @param {Object[]} props.links - Links to additional information for each category.
* @returns {JSX.Element} The rendered Card component.
*/
const Card = ({ month, data, links }) => {
return (
<div className="bg-slate-100 shadow-lg rounded-lg p-4 flex flex-col justify-between h-56 overflow-hidden">
<div className="text-lg font-semibold mb-4">{month}</div>
<div className="flex flex-col justify-center overflow-x-auto">
{data.map((item, index) => (
<div key={index} className="flex justify-between">
<div className="text-sm m-2" onClick={(links) => {
const category = item.Category;
const matchedLinkObject = ExpensesLink.find(obj => obj.category === category);
if (matchedLinkObject) {
window.open(matchedLinkObject.link, '_blank');
}
}}>{item.Category}</div>
<div className="text-sm m-2">${item.Amount}</div>
</div>
))}
</div>
</div>
);
};

/**
* ExpensesCard component displays a grid of expense cards for each month.
*
* @returns {JSX.Element} The rendered ExpensesCard component.
*/
const ExpensesCard = () => {
return (
<div className="overflow-x-auto">
<div className="grid grid-flow-col auto-cols-max gap-4 p-4">
{Object.keys(Expenses).map((month, index) => (
<Card key={index} month={month} data={Expenses[month]} />
))}
</div>
</div>
);
};

/**
* BarChartComponent displays a budget analysis bar chart with filtering options.
*
* @returns {JSX.Element} The rendered BarChartComponent component.
*/
const BarChartComponent = () => {
// State for selected filters
const [selectedCategory, setSelectedCategory] = useState("All Categories");
const [selectedMonth, setSelectedMonth] = useState("All Months");
const [windowWidth, setWindowWidth] = useState(null);

// Get unique categories and months from the Expenses data
const categories = getUniqueCategories();
const months = Object.keys(Expenses);

// Filter the expenses data based on selectedCategory and selectedMonth
const filteredData = Object.entries(Expenses).flatMap(([month, entries]) =>
(selectedMonth === "All Months" || selectedMonth === month) ?
entries.filter(entry =>
selectedCategory === "All Categories" || entry.Category === selectedCategory
)
: []
);

// Calculate total amount for the filtered data
const totalAmount = filteredData.reduce((total, entry) => total + parseFloat(entry.Amount), 0);

const categoryAmounts = {};
filteredData.forEach(entry => {
if (categoryAmounts[entry.Category]) {
categoryAmounts[entry.Category] += parseFloat(entry.Amount);
} else {
categoryAmounts[entry.Category] = parseFloat(entry.Amount);
}
});

// Prepare chartData from the aggregated categoryAmounts
const chartData = Object.keys(categoryAmounts).map(category => ({
Category: category,
Amount: categoryAmounts[category],
}));

// Create a ref for the handleResize function
const handleResizeRef = useRef(null);

// Define the handleResize function
handleResizeRef.current = () => {
setWindowWidth(window.innerWidth);
};

// Update the window width when the component mounts and when the window is resized
useEffect(() => {
// Initial width
handleResizeRef.current();

// Listen for window resize events
window.addEventListener("resize", handleResizeRef.current);

// Clean up the event listener when the component unmounts
return () => {
window.removeEventListener("resize", handleResizeRef.current);
};
}, []);

const barWidth = windowWidth < 900 ? null : 800;
const barHeight = windowWidth < 900 ? null : 400;

return (
<div className="flex justify-center items-center sm:px-6 lg:px-8 mt-8">
<div className="w-full lg:w-2/3 px-4 text-center">
<div className='mb-5'>
<h1 id="budget-analysis" className="text-3xl font-semibold mb-4 my-2">Budget Analysis</h1>
<p>Gain insights into the allocation of funds across different categories through our Budget Analysis</p>
<div className="flex flex-col md:flex-row justify-between my-4 md:items-center md:justify-between md:m-8">
<div className="my-2">
<p className="text-center sm:text-left">Expenses</p>
<p className="text-center sm:text-left mt-1 text-xl font-semibold">${totalAmount.toFixed(2)}</p>
</div>
<div className="md:flex space-x-4">

<div className="mx-auto">
{/* Select for category filter */}
<select
className="p-2 m-1 border text-gray-600 font-semibold border-gray-600 rounded-md bg-white text-violet text-xs w-full sm:w-auto md:w-48"
value={selectedCategory}
onChange={(e) => setSelectedCategory(e.target.value)}
>
<option value="All Categories">All Categories</option>
{categories.map(category => (
<option key={category} value={category}>{category}</option>
))}
</select>

{/* Select for month filter */}
<select
className="p-2 m-1 pr-8 border border-gray-600 rounded-md bg-violet text-white font-semibold text-xs w-full sm:w-auto md:w-48"
value={selectedMonth}
onChange={(e) => setSelectedMonth(e.target.value)}
>
<option value="All Months">All Months</option>
{months.map(month => (
<option key={month} value={month}>{month}</option>
))}
</select>
</div>
</div>
</div>

</div>
{/* Recharts BarChart */}
<BarChart width={barWidth} height={barHeight} data={chartData}>
<CartesianGrid strokeDasharray="3 3" />
<YAxis tickFormatter={(value) => `$${value}`} />
<Tooltip content={<CustomTooltip />} />
<Legend />
<Bar
dataKey="Amount"
fill="#7B5DD3FF"
onClick={(data) => {
// Get the category from the clicked bar's payload
const category = data.payload.Category;
// Replace the URL with the external website URL you want to open
const matchedLinkObject = ExpensesLink.find(obj => obj.category === category);
if (matchedLinkObject) {
// Extract the link from the matched object and open it in a new tab/window
window.open(matchedLinkObject.link, '_blank');
}
}}
/>
</BarChart>
{windowWidth < 900 ? <ExpensesCard data={Expenses} /> : null}
</div>
</div>
);
};

export default BarChartComponent;
28 changes: 28 additions & 0 deletions components/FinancialSummary/ContactUs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Button from '../buttons/Button'
import Heading from '../typography/Heading'
import Paragraph from '../typography/Paragraph'

export default function ContactUs() {
return (
<div className="px-4 sm:px-6 lg:px-8">
<div className="grid lg:grid-cols-9 lg:gap-8 lg:text-center my-4">
<div className="col-start-3 col-span-5">
<div className="mx-2">
<Heading level="h1" typeStyle="heading-lg"><h1 id="contact-us">Interested in getting in touch?</h1></Heading>
<Paragraph typeStyle="body-md" className="my-2 max-w-4xl">
Feel free to contact us if you need more explanation. We are happy to hop on a call and help with
onboarding to the project as a sponsor. Write email to <span><a className="text-violet text-base font-semibold" href="mailto:[email protected]" target='_blank'>[email protected]</a></span>
</Paragraph>
</div>
</div>
</div>
<div className="flex justify-center">
<Button
text="Contact Us"
href="mailto:[email protected]"
target='_blank'
/>
</div>
</div>
)
}
Loading
Loading