Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Dingyj3178/stripe-billing-simulator
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.0
Choose a base ref
...
head repository: Dingyj3178/stripe-billing-simulator
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.1.1
Choose a head ref
  • 14 commits
  • 9 files changed
  • 2 contributors

Commits on Aug 13, 2022

  1. 1
    Copy the full SHA
    89f7811 View commit details

Commits on Aug 18, 2022

  1. Copy the full SHA
    e632789 View commit details
  2. Copy the full SHA
    f737a27 View commit details
  3. Copy the full SHA
    e196bc2 View commit details
  4. Merge pull request #2 from ding-st/feature/add-timeline-date

    Feature/add timeline date
    ding-stripe authored Aug 18, 2022
    1

    Verified

    This commit was created on github.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    737ac31 View commit details

Commits on Aug 19, 2022

  1. 1
    Copy the full SHA
    1d79ebf View commit details

Commits on Aug 20, 2022

  1. change the display order */}

    Fixes #3
    Dingyj3178 committed Aug 20, 2022
    Copy the full SHA
    fe5dc03 View commit details

Commits on Aug 21, 2022

  1. Copy the full SHA
    6c7c878 View commit details
  2. Merge pull request #5 from ding-st/Dingyj3178/issue3

    change the display order */}
    ding-stripe authored Aug 21, 2022
    1

    Verified

    This commit was created on github.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    d16011c View commit details
  3. Verified

    This commit was created on github.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    2de8734 View commit details
  4. Merge pull request #6 from Dingyj3178/scenario-simulator

    change postman script to button
    Dingyj3178 authored Aug 21, 2022

    Verified

    This commit was created on github.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b2be060 View commit details
  5. fix typo

    Dingyj3178 committed Aug 21, 2022
    Copy the full SHA
    a9f9870 View commit details
  6. fix typo

    Dingyj3178 committed Aug 21, 2022
    Copy the full SHA
    9ead386 View commit details
  7. delete comment

    Dingyj3178 committed Aug 21, 2022
    1
    Copy the full SHA
    137e809 View commit details
113 changes: 111 additions & 2 deletions billing-simulator/components/Eventpoint.tsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,11 @@ import React, { useState, useEffect, useRef } from "react";
import dynamic from "next/dynamic";
import { useXarrow } from "react-xarrows";

import { eventPointCalculator, widthCalculator } from "../utils/timelineHelper";
import {
eventPointCalculator,
widthCalculator,
calculateUpdate,
} from "../utils/timelineHelper";
import { Parameters } from "../typings";

const Xarrow = dynamic(() => import("react-xarrows"), { ssr: false });
@@ -20,17 +24,35 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
updateXarrow();
}, [parameter]);

const updateDate = calculateUpdate(
parameter.billing_cycle_anchor as Date,
parameter.trial_end as Date,
parameter.create_date as Date,
parameter.interval,
parameter.interval_count
);

const secondUpdateDate = calculateUpdate(
null,
null,
updateDate,
parameter.interval,
parameter.interval_count
);

const result = eventPointCalculator(parameter);
const widthResult = widthCalculator(result, timelineWidth);
const timeline = result.timeline;
const startPoint = result.startPoint;
const updatePoint = result.updatePoint;
const secondUpdatePoint = result.secondUpdatePoint;
const trialEndPoint = result.trialEndPoint;
const billingPoint = result.billingPoint;
const width1 = widthResult.width1;
const width2 = widthResult.width2;
const width3 = widthResult.width3;
const width4 = widthResult.width4;
const width5 = widthResult.width5;

function classNames(...classes: any) {
return classes.filter(Boolean).join(" ");
@@ -99,7 +121,19 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
id="d-update-point"
className=" inline-block px-3 py-0.5 rounded-full text-sm font-medium text-gray-50 bg-violet-500 mb-20 break-words w-24 text-center "
>
Charge for Update
Charge
</span>
<div
className="static inline-block"
style={{
width: width5 + "px",
}}
/>
<span
id="d-second-update-point"
className=" inline-block px-3 py-0.5 rounded-full text-sm font-medium text-gray-50 bg-violet-500 mb-20 break-words w-24 text-center "
>
Charge
</span>
</div>

@@ -112,6 +146,17 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
)}
style={{ left: (timelineWidth - 6) * (startPoint / timeline) + "px" }}
/>
<div
className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center text-sm"
style={{
left: (timelineWidth - 6) * (startPoint / timeline) - 4 + "px",
}}
>
{parameter.create_date!.getMonth() +
1 +
"/" +
parameter.create_date!.getDate()}
</div>
<Xarrow
startAnchor={"bottom"}
endAnchor={"top"}
@@ -133,6 +178,18 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
left: (timelineWidth - 6) * (trialEndPoint / timeline) + "px",
}}
/>
<div
className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center text-sm"
style={{
left:
(timelineWidth - 6) * (trialEndPoint / timeline) - 4 + "px",
}}
>
{parameter.trial_end!.getMonth() +
1 +
"/" +
parameter.trial_end!.getDate()}
</div>
<Xarrow
startAnchor={"bottom"}
endAnchor={"top"}
@@ -155,6 +212,18 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
left: (timelineWidth - 6) * (billingPoint / timeline) + "px",
}}
/>
<div
className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center text-sm"
style={{
left:
(timelineWidth - 6) * (billingPoint / timeline) - 4 + "px",
}}
>
{parameter.billing_cycle_anchor!.getMonth() +
1 +
"/" +
parameter.billing_cycle_anchor!.getDate()}
</div>
<Xarrow
startAnchor={"bottom"}
endAnchor={"top"}
@@ -176,6 +245,14 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
left: (timelineWidth - 6) * (updatePoint / timeline) + "px",
}}
/>
<div
className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center text-sm"
style={{
left: (timelineWidth - 6) * (updatePoint / timeline) - 4 + "px",
}}
>
{updateDate!.getMonth() + 1 + "/" + updateDate!.getDate()}
</div>
<Xarrow
startAnchor={"bottom"}
endAnchor={"top"}
@@ -186,6 +263,38 @@ function Eventpoint({ parameter }: { parameter: Parameters }) {
strokeWidth={2}
/>
</div>
<div>
<div
id="p-second-update-point"
className={classNames(
"w-3 h-3 bg-[#80E9FF] border-[#7A73FF] border-2 rounded-full absolute -bottom-2 "
)}
style={{
left: (timelineWidth - 6) * (secondUpdatePoint / timeline) + "px",
}}
/>
<div
className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center text-sm"
style={{
left:
(timelineWidth - 6) * (secondUpdatePoint / timeline) - 4 + "px",
}}
>
{secondUpdateDate!.getMonth() +
1 +
"/" +
secondUpdateDate!.getDate()}
</div>
<Xarrow
startAnchor={"bottom"}
endAnchor={"top"}
color="#0A2540"
headSize={4}
start="d-second-update-point" //can be react ref
end="p-second-update-point" //or an id
strokeWidth={2}
/>
</div>
</div>
</div>
);
41 changes: 23 additions & 18 deletions billing-simulator/components/MeteredChart.tsx
Original file line number Diff line number Diff line change
@@ -48,20 +48,25 @@ function calculatePrice(
let price: number = 0;
for (let index = 0; index < parameter.pricingTiers.length; index++) {
const element = parameter.pricingTiers[index];
if (
index === parameter.pricingTiers.length - 1 ||
usage === element.up_to
) {
price = element.unit_amount * i + element.flat_amount;
break;
} else if (
usage > element.up_to &&
usage <= parameter.pricingTiers[index + 1].up_to
) {
price =
parameter.pricingTiers[index + 1].unit_amount * i +
parameter.pricingTiers[index + 1].flat_amount;
break;
if (i > 0) {
if (
index === parameter.pricingTiers.length - 1 ||
usage === element.up_to
) {
price = element.unit_amount * i + element.flat_amount;
break;
} else if (
usage > element.up_to &&
usage <= parameter.pricingTiers[index + 1].up_to
) {
price =
parameter.pricingTiers[index + 1].unit_amount * i +
parameter.pricingTiers[index + 1].flat_amount;
break;
} else if (usage <= element.up_to) {
price = element.unit_amount * i + element.flat_amount;
break;
}
}
}
return price;
@@ -178,7 +183,7 @@ function MeteredChart({ parameter }: { parameter: Parameters }) {
? addYears(
new Date((greatestUpdateDate as number) * 1000),
parameter.interval_count *
(Math.abs(differenceFromUsageDate) / 86400) >
(Math.abs(differenceFromUsageDate) / 86400) >=
differenceInCalendarDays(
new Date((usageDate as number) * 1000),
new Date((greatestUpdateDate as number) * 1000)
@@ -202,7 +207,7 @@ function MeteredChart({ parameter }: { parameter: Parameters }) {
? addMonths(
new Date((greatestUpdateDate as number) * 1000),
parameter.interval_count *
(Math.abs(differenceFromUsageDate) / 86400) >
(Math.abs(differenceFromUsageDate) / 86400) >=
differenceInCalendarDays(
new Date((usageDate as number) * 1000),
new Date((greatestUpdateDate as number) * 1000)
@@ -221,7 +226,7 @@ function MeteredChart({ parameter }: { parameter: Parameters }) {
? addWeeks(
new Date((greatestUpdateDate as number) * 1000),
parameter.interval_count *
(Math.abs(differenceFromUsageDate) / 86400) >
(Math.abs(differenceFromUsageDate) / 86400) >=
differenceInCalendarDays(
new Date((usageDate as number) * 1000),
new Date((greatestUpdateDate as number) * 1000)
@@ -235,7 +240,7 @@ function MeteredChart({ parameter }: { parameter: Parameters }) {
: addDays(
new Date((greatestUpdateDate as number) * 1000),
parameter.interval_count *
(Math.abs(differenceFromUsageDate) / 86400) >
(Math.abs(differenceFromUsageDate) / 86400) >=
differenceInCalendarDays(
new Date((usageDate as number) * 1000),
new Date((greatestUpdateDate as number) * 1000)
32 changes: 32 additions & 0 deletions billing-simulator/components/Period.tsx
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ function Period({ parameter }: { parameter: Parameters }) {
const timeline = result.timeline;
const startPoint = result.startPoint;
const updatePoint = result.updatePoint;
const secondUpdatePoint = result.secondUpdatePoint;
const trialEndPoint = result.trialEndPoint;
const billingPoint = result.billingPoint;

@@ -165,6 +166,37 @@ function Period({ parameter }: { parameter: Parameters }) {
headShape="arrow1"
/>
</div>
<div>
<div
className={classNames(
"w-3 h-3 rounded-full absolute place-items-center grid"
)}
style={{
left: (width - 6) * (secondUpdatePoint / timeline) + "px",
}}
>
<div
id="line-second-update-point"
className=" w-1 h-12 bg-[#0A2540]"
/>
</div>
<Xarrow
startAnchor={"right"}
endAnchor={"left"}
// path="straight"
color="#0A2540"
headSize={4}
tailSize={4}
start="line-update-point"
end="line-second-update-point"
strokeWidth={2}
dashness
showTail
labels={<div className=" mt-20">Biling Cycle</div>}
tailShape="arrow1"
headShape="arrow1"
/>
</div>
</div>
</div>
);
42 changes: 28 additions & 14 deletions billing-simulator/components/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import React from "react";
import React, { useRef, useEffect, useState } from "react";
import eachMonthOfInterval from "date-fns/eachMonthOfInterval";
import eachYearOfInterval from "date-fns/eachYearOfInterval";
import eachWeekOfInterval from "date-fns/eachWeekOfInterval";
import eachDayOfInterval from "date-fns/eachDayOfInterval";
import { Parameters } from "../typings";

function Timeline({ parameter }: { parameter: Parameters }) {
const ref = useRef<HTMLDivElement>(null);
const [timelineWidth, setTimelineWidth] = useState(0);
// const timelineWidth = 854;
useEffect(() => {
setTimelineWidth(ref.current!.clientWidth);
});
let timelineArray: Date[] = [];
const timelineStart = new Date(
parameter.create_date!.getFullYear(),
@@ -26,7 +32,7 @@ function Timeline({ parameter }: { parameter: Parameters }) {
start: timelineStart,
end: new Date(
endDate!.getFullYear(),
endDate!.getMonth() + parameter.interval_count * 1 + 2,
endDate!.getMonth() + parameter.interval_count * 2 + 2,
1
),
});
@@ -35,7 +41,7 @@ function Timeline({ parameter }: { parameter: Parameters }) {
timelineArray = eachYearOfInterval({
start: timelineStart,
end: new Date(
endDate!.getFullYear() + parameter.interval_count * 1 + 1,
endDate!.getFullYear() + parameter.interval_count * 2 + 1,
endDate!.getMonth(),
1
),
@@ -45,37 +51,45 @@ function Timeline({ parameter }: { parameter: Parameters }) {
timelineArray = eachWeekOfInterval({
start: parameter.create_date!,
end: new Date(endDate!).setDate(
endDate!.getDate() + parameter.interval_count * 7 + 14
endDate!.getDate() + parameter.interval_count * 14 + 14
),
});
break;
case "day":
timelineArray = eachDayOfInterval({
start: parameter.create_date!,
end: new Date(endDate!).setDate(
endDate!.getDate() + parameter.interval_count * 1 + 1
endDate!.getDate() + parameter.interval_count * 2 + 1
),
});
break;
default:
12;
}
const displayDensity = Math.ceil((timelineArray.length * 80) / timelineWidth);
let displayIndex: number[] = [];
for (let index = 0; index < timelineArray.length; index += displayDensity) {
displayIndex.push(index);
}

return (
<div className="flex justify-between -mt-2 mb-10 mx-12 ">
{timelineArray.map((id) => {
<div ref={ref} className="flex justify-between -mt-2 mb-10 mx-12 ">
{/* <div className="flex justify-between -mt-2 mb-10 mx-12 "> */}
{timelineArray.map((id, index) => {
return (
<div
key={id.toString()}
className=" w-3 h-3 bg-yellow-500 rounded-full relative"
>
<div className=" absolute -translate-x-1/3 left-1/3 top-7 w-20 text-center z-10">
{id.getFullYear() +
"/" +
(id.getMonth() + 1) +
"/" +
id.getDate()}
</div>
{displayIndex.includes(index) ? (
<div className=" absolute -translate-x-1/3 left-1/3 top-8 w-20 text-center z-10">
{id.getFullYear() +
"/" +
(id.getMonth() + 1) +
"/" +
id.getDate()}
</div>
) : null}
</div>
);
})}
Loading