diff --git a/src/Faction/formulas/donation.ts b/src/Faction/formulas/donation.ts new file mode 100644 index 000000000..cd9fd0d6c --- /dev/null +++ b/src/Faction/formulas/donation.ts @@ -0,0 +1,6 @@ +import { CONSTANTS } from "../../Constants"; +import { IPlayer } from "../../PersonObjects/IPlayer"; + +export function repFromDonation(amt: number, player: IPlayer): number { + return amt / CONSTANTS.DonateMoneyToRepDivisor * player.faction_rep_mult; +} \ No newline at end of file diff --git a/src/Faction/ui/DonateOption.tsx b/src/Faction/ui/DonateOption.tsx index be6575170..d1c68039a 100644 --- a/src/Faction/ui/DonateOption.tsx +++ b/src/Faction/ui/DonateOption.tsx @@ -1,11 +1,12 @@ /** * React component for a donate option on the Faction UI */ -import * as React from "react"; +import React, { useState } from "react"; import { CONSTANTS } from "../../Constants"; import { Faction } from "../../Faction/Faction"; import { IPlayer } from "../../PersonObjects/IPlayer"; +import { repFromDonation } from "../formulas/donation"; import { Money } from "../../ui/React/Money"; import { Reputation } from "../../ui/React/Reputation"; @@ -15,6 +16,7 @@ import { StdButton } from "../../ui/React/StdButton"; import { numeralWrapper } from "../../ui/numeralFormat"; import { dialogBoxCreate } from "../../../utils/DialogBox"; +import { MathComponent } from 'mathjax-react'; type IProps = { faction: Faction; @@ -24,93 +26,78 @@ type IProps = { rerender: () => void; } -type IState = { - donateAmt: number; - status: JSX.Element; -} const inputStyleMarkup = { margin: "5px", height: "26px", } -export class DonateOption extends React.Component { - // Style markup for block elements. Stored as property - blockStyle: any = { display: "block" }; +const blockStyle = { display: "block" }; - constructor(props: IProps) { - super(props); +export function DonateOption(props: IProps): React.ReactElement { + const [donateAmt, setDonateAmt] = useState(null); + const digits = (CONSTANTS.DonateMoneyToRepDivisor+'').length-1; + function canDonate(): boolean { + if(donateAmt === null) return false; + if (isNaN(donateAmt) || donateAmt <= 0) return false; + if(props.p.money.lt(donateAmt)) return false; + return true; + } - this.state = { - donateAmt: 0, - status: props.disabled ? <>Unlocked at {props.favorToDonate} favor with {props.faction.name} : <>, + function onChange(event: React.ChangeEvent): void { + const amt = numeralWrapper.parseMoney(event.target.value); + if(event.target.value === "" || isNaN(amt)) setDonateAmt(null); + else setDonateAmt(amt); + } + + function donate(): void { + const fac = props.faction; + const amt = donateAmt; + if(amt === null) return; + if(!canDonate()) return; + props.p.loseMoney(amt); + const repGain = repFromDonation(amt, props.p); + props.faction.playerReputation += repGain; + dialogBoxCreate(<> + You just donated {Money(amt)} to {fac.name} to gain {Reputation(repGain)} reputation. + ); + props.rerender(); + } + + function Status(): React.ReactElement { + if(donateAmt === null) return (<>); + if(!canDonate()) { + if(props.p.money.lt(donateAmt)) + return (

Insufficient funds

); + return (

Invalid donate amount entered!

); } - - this.calculateRepGain = this.calculateRepGain.bind(this); - this.donate = this.donate.bind(this); - this.handleChange = this.handleChange.bind(this); + return (

This donation will result in {Reputation(repFromDonation(donateAmt, props.p))} reputation gain

); } - // Returns rep gain for a given donation amount - calculateRepGain(amt: number): number { - return amt / CONSTANTS.DonateMoneyToRepDivisor * this.props.p.faction_rep_mult; - } - donate(): void { - const fac = this.props.faction; - const amt = this.state.donateAmt; - if (isNaN(amt) || amt <= 0) { - dialogBoxCreate(`Invalid amount entered!`); - } else if (!this.props.p.canAfford(amt)) { - dialogBoxCreate(`You cannot afford to donate this much money!`); - } else { - this.props.p.loseMoney(amt); - const repGain = this.calculateRepGain(amt); - this.props.faction.playerReputation += repGain; - dialogBoxCreate(<> - You just donated {Money(amt)} to {fac.name} to gain {Reputation(repGain)} reputation - ); - this.props.rerender(); - } - } - - handleChange(e: React.ChangeEvent): void { - const amt = numeralWrapper.parseMoney(e.target.value); - - if (isNaN(amt)) { - this.setState({ - donateAmt: 0, - status: <>Invalid donate amount entered!, - }); - } else { - const repGain = this.calculateRepGain(amt); - this.setState({ - donateAmt: amt, - status: <>This donation will result in {Reputation(repGain)} reputation gain, - }); - } - } - - render(): React.ReactNode { - return ( -
-
- - -

{this.state.status}

-
-
- ) - } + return (
+
+ + + + { + props.disabled ? +

Unlocked at {props.favorToDonate} favor with {props.faction.name}

: +
+ +
+ } +
+
); } diff --git a/src/Faction/ui/Info.tsx b/src/Faction/ui/Info.tsx index f3bbaaa5e..5dbec5bec 100644 --- a/src/Faction/ui/Info.tsx +++ b/src/Faction/ui/Info.tsx @@ -11,7 +11,7 @@ import { AutoupdatingParagraph } from "../../ui/React/AutoupdatingParagraph"; import { ParagraphWithTooltip } from "../../ui/React/ParagraphWithTooltip"; import { Reputation } from "../../ui/React/Reputation"; import { Favor } from "../../ui/React/Favor"; -import { MathComponent } from 'mathjax-react' +import { MathComponent } from 'mathjax-react'; type IProps = { faction: Faction;