New source found from dndbeyond.com
This commit is contained in:
+375
-406
@@ -2,8 +2,9 @@ import axios, { Canceler } from "axios";
|
||||
import { orderBy } from "lodash";
|
||||
import React, { FocusEvent, HTMLAttributes, useContext } from "react";
|
||||
import { DispatchProp } from "react-redux";
|
||||
import { AnyAction } from "redux";
|
||||
|
||||
import { LoadingPlaceholder, Select } from "@dndbeyond/character-components/es";
|
||||
import { LoadingPlaceholder } from "@dndbeyond/character-components/es";
|
||||
import {
|
||||
AlignmentContract,
|
||||
ApiAdapterPromise,
|
||||
@@ -44,12 +45,16 @@ import {
|
||||
rulesEngineSelectors,
|
||||
serviceDataSelectors,
|
||||
} from "@dndbeyond/character-rules-engine/es";
|
||||
import MinusIcon from "@dndbeyond/fontawesome-cache/svgs/solid/minus.svg";
|
||||
import PlusIcon from "@dndbeyond/fontawesome-cache/svgs/solid/plus.svg";
|
||||
|
||||
import { Accordion } from "~/components/Accordion";
|
||||
import { Button } from "~/components/Button";
|
||||
import { CollapsibleContent } from "~/components/CollapsibleContent";
|
||||
import { HelperTextAccordion } from "~/components/HelperTextAccordion";
|
||||
import { HtmlContent } from "~/components/HtmlContent";
|
||||
import { Link } from "~/components/Link";
|
||||
import { Select } from "~/components/Select";
|
||||
import { useSource } from "~/hooks/useSource";
|
||||
import { EditorWithDialog } from "~/subApps/builder/components/EditorWithDialog";
|
||||
import { InputField } from "~/subApps/builder/components/InputField";
|
||||
@@ -70,10 +75,8 @@ import {
|
||||
appEnvSelectors,
|
||||
} from "../../../../Shared/selectors";
|
||||
import { AppLoggerUtils } from "../../../../Shared/utils";
|
||||
import Button from "../../../components/Button";
|
||||
import { GrantedFeat } from "../../../components/GrantedFeat/GrantedFeat";
|
||||
import Page from "../../../components/Page";
|
||||
import { PageBody } from "../../../components/PageBody";
|
||||
import PageSubHeader from "../../../components/PageSubHeader";
|
||||
import { BuilderAppState } from "../../../typings";
|
||||
import ConnectedBuilderPage from "../ConnectedBuilderPage";
|
||||
@@ -188,89 +191,67 @@ class CustomBackgroundManager extends React.PureComponent<
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="custom-background">
|
||||
<div className="custom-background-editor">
|
||||
<div className="custom-background-properties">
|
||||
<div className="custom-background-property custom-background-property-full">
|
||||
<div className="custom-background-property-value">
|
||||
<input
|
||||
type="text"
|
||||
defaultValue={name || ""}
|
||||
onBlur={this.handleTextInputBlur.bind(this, "name")}
|
||||
/>
|
||||
</div>
|
||||
<div className="custom-background-property-label">Name</div>
|
||||
</div>
|
||||
<div className="custom-background-property custom-background-property-textarea">
|
||||
<div className="custom-background-property-value">
|
||||
<textarea
|
||||
defaultValue={description || ""}
|
||||
onBlur={this.handleTextInputBlur.bind(this, "description")}
|
||||
/>
|
||||
</div>
|
||||
<div className="custom-background-property-label">
|
||||
Description
|
||||
</div>
|
||||
</div>
|
||||
<div className="custom-background-property custom-background-property-choice">
|
||||
<div className="custom-background-property-value">
|
||||
<Select
|
||||
onChange={this.handleNumberSelectChange.bind(
|
||||
this,
|
||||
"modifierType"
|
||||
)}
|
||||
options={modifierTypeOptions}
|
||||
value={modifierType}
|
||||
clsNames={[""]}
|
||||
/>
|
||||
</div>
|
||||
<div className="custom-background-property-label">
|
||||
Proficiency/Language Choices
|
||||
</div>
|
||||
</div>
|
||||
<div className="custom-background-property custom-background-property-choice">
|
||||
<div className="custom-background-property-value">
|
||||
<Select
|
||||
onChange={this.handleNumberSelectChange.bind(
|
||||
this,
|
||||
"featureId"
|
||||
)}
|
||||
options={featureOptions}
|
||||
value={featureId}
|
||||
clsNames={[""]}
|
||||
/>
|
||||
</div>
|
||||
<div className="custom-background-property-label">
|
||||
Background Feature
|
||||
</div>
|
||||
</div>
|
||||
<div className="custom-background-property custom-background-property-choice">
|
||||
<div className="custom-background-property-value">
|
||||
<Select
|
||||
onChange={this.handleNumberSelectChange.bind(
|
||||
this,
|
||||
"characteristicsId"
|
||||
)}
|
||||
options={characteristicsOptions}
|
||||
value={characteristicsId}
|
||||
clsNames={[""]}
|
||||
/>
|
||||
</div>
|
||||
<div className="custom-background-property-label">
|
||||
Background Characteristics
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="custom-background-actions">
|
||||
<Button onClick={this.handleSave}>Save</Button>
|
||||
</div>
|
||||
<div className={styles.customBackground}>
|
||||
<InputField
|
||||
className={styles.customBackgroundField}
|
||||
type="text"
|
||||
label="Name"
|
||||
defaultValue={name || ""}
|
||||
onBlur={this.handleTextInputBlur.bind(this, "name")}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.customBackgroundField}
|
||||
type="textarea"
|
||||
label="Description"
|
||||
defaultValue={description || ""}
|
||||
onBlur={this.handleTextInputBlur.bind(this, "description")}
|
||||
/>
|
||||
<label className={styles.customBackgroundLabel}>
|
||||
Proficiency/Language Choices
|
||||
</label>
|
||||
<Select
|
||||
className={styles.customBackgroundField}
|
||||
onChange={this.handleNumberSelectChange.bind(this, "modifierType")}
|
||||
options={modifierTypeOptions}
|
||||
value={modifierType}
|
||||
name="custom-background-description"
|
||||
/>
|
||||
<label className={styles.customBackgroundLabel}>
|
||||
Background Feature
|
||||
</label>
|
||||
<Select
|
||||
className={styles.customBackgroundField}
|
||||
onChange={this.handleNumberSelectChange.bind(this, "featureId")}
|
||||
options={featureOptions}
|
||||
value={featureId}
|
||||
name="custom-background-feature"
|
||||
/>
|
||||
<label className={styles.customBackgroundLabel}>
|
||||
Background Characteristics
|
||||
</label>
|
||||
<Select
|
||||
className={styles.customBackgroundField}
|
||||
onChange={this.handleNumberSelectChange.bind(
|
||||
this,
|
||||
"characteristicsId"
|
||||
)}
|
||||
options={characteristicsOptions}
|
||||
value={characteristicsId}
|
||||
name="custom-background-characteristics"
|
||||
/>
|
||||
<div className={styles.customBackgroundActions}>
|
||||
<Button variant="builder" size="x-small" onClick={this.handleSave}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface Props extends DispatchProp {
|
||||
// TODO: We are typing with AnyAction here to work around issues with UnknownAction, the type that was introduced in Redux 5.
|
||||
// If we decide to modernize to Redux 5, we will need to refactor much of the Rules Engine redux usage.
|
||||
interface Props extends DispatchProp<AnyAction> {
|
||||
ruleData: RuleData;
|
||||
background: Background | null;
|
||||
currentBackground: BackgroundContract | null;
|
||||
@@ -719,6 +700,7 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
options={availableOptions}
|
||||
onChange={this.handleChoiceChange}
|
||||
choiceInfo={choiceInfo}
|
||||
className={styles.backgroundChoiceSelect}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -1105,23 +1087,24 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
{description}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.accordionGroup}>
|
||||
{this.renderBackgroundChoices(background)}
|
||||
{featuresBackground &&
|
||||
this.renderBackgroundFeature(featuresBackground, [
|
||||
featuresBackground.name ? featuresBackground.name : "",
|
||||
])}
|
||||
|
||||
{this.renderBackgroundChoices(background)}
|
||||
{featuresBackground &&
|
||||
this.renderBackgroundFeature(featuresBackground, [
|
||||
featuresBackground.name ? featuresBackground.name : "",
|
||||
])}
|
||||
|
||||
{characteristicsBackground &&
|
||||
this.hasCharacteristics(characteristicsBackground) && (
|
||||
<Accordion
|
||||
summary="Suggested Characteristics"
|
||||
summaryMetaItems={metaItems}
|
||||
variant="paper"
|
||||
>
|
||||
{this.renderBackgroundSuggestionsUi(characteristicsBackground)}
|
||||
</Accordion>
|
||||
)}
|
||||
{characteristicsBackground &&
|
||||
this.hasCharacteristics(characteristicsBackground) && (
|
||||
<Accordion
|
||||
summary="Suggested Characteristics"
|
||||
summaryMetaItems={metaItems}
|
||||
variant="paper"
|
||||
>
|
||||
{this.renderBackgroundSuggestionsUi(characteristicsBackground)}
|
||||
</Accordion>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1130,15 +1113,15 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
const { customizeCollapsed } = this.state;
|
||||
const { background, getGroupedOptionsBySourceCategory } = this.props;
|
||||
|
||||
const backgroundOptions: Array<HtmlSelectOption | HtmlSelectOptionGroup> = [
|
||||
const backgroundOptions = [
|
||||
{
|
||||
label: "Custom Background",
|
||||
value: -1,
|
||||
},
|
||||
{
|
||||
label: "---------",
|
||||
disabled: true,
|
||||
value: "-----",
|
||||
optGroupLabel: "---------",
|
||||
options: [
|
||||
{
|
||||
label: "Custom Background",
|
||||
value: -1,
|
||||
},
|
||||
],
|
||||
},
|
||||
...getGroupedOptionsBySourceCategory(this.getBackgroundData()),
|
||||
];
|
||||
@@ -1152,15 +1135,8 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
let clsNames: string[] = ["custom-background-customize-header"];
|
||||
if (customizeCollapsed) {
|
||||
clsNames.push("custom-background-customize-header-closed");
|
||||
} else {
|
||||
clsNames.push("custom-background-customize-header-opened");
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<div className="ct-character-tools__marketplace-callout">
|
||||
Check your source settings on the <strong>Home</strong> tab if you
|
||||
can't find Backgrounds you've purchased.
|
||||
@@ -1169,27 +1145,24 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
<Link href="/marketplace">Marketplace</Link> for more Background
|
||||
options.
|
||||
</div>
|
||||
<div className="description-manage-background-chooser-con">
|
||||
<div className="description-manage-background-chooser-field">
|
||||
<Select
|
||||
onChangePromise={this.handleBackgroundChangePromise}
|
||||
options={backgroundOptions}
|
||||
value={backgroundId}
|
||||
clsNames={["description-manage-background-chooser"]}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.backgroundSelectContainer}>
|
||||
<Select
|
||||
className={styles.backgroundSelect}
|
||||
options={backgroundOptions}
|
||||
onChangeConfirm={this.handleBackgroundChangePromise}
|
||||
value={backgroundId}
|
||||
name="background-chooser"
|
||||
/>
|
||||
{background && background.hasCustomBackground && (
|
||||
<div className="description-manage-background-chooser-extra">
|
||||
<div
|
||||
className={clsNames.join(" ")}
|
||||
onClick={this.handleConfigureClick}
|
||||
>
|
||||
<div className="custom-background-customize-heading">
|
||||
Configure
|
||||
</div>
|
||||
<div className="custom-background-customize-trigger" />
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
className={styles.customBackgroundToggle}
|
||||
variant="builder-text"
|
||||
size="x-small"
|
||||
onClick={this.handleConfigureClick}
|
||||
>
|
||||
Configure
|
||||
{customizeCollapsed ? <PlusIcon /> : <MinusIcon />}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{background &&
|
||||
@@ -1198,7 +1171,7 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
{background &&
|
||||
background.hasCustomBackground &&
|
||||
this.renderCustomBackgroundUI()}
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1293,7 +1266,7 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
lifestyle.cost === "-" ? "" : `(${lifestyle.cost})`
|
||||
}`,
|
||||
value: lifestyle.id,
|
||||
}));
|
||||
})) as HtmlSelectOption[];
|
||||
|
||||
const numberInputAttributes = {
|
||||
min: CHARACTER_DESCRIPTION_NUMBER_VALUE.MIN,
|
||||
@@ -1302,283 +1275,279 @@ class DescriptionManage extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<Page clsNames={["description-manage"]}>
|
||||
<PageBody>
|
||||
<div className="description-manage-information">
|
||||
{this.renderInformationCollapsible()}
|
||||
<div className="description-manage-information">
|
||||
{this.renderInformationCollapsible()}
|
||||
</div>
|
||||
{this.renderBackgroundUi()}
|
||||
<Accordion
|
||||
summary="Character Details"
|
||||
summaryMetaItems={["Alignment", "Faith", "Lifestyle"]}
|
||||
variant="paper"
|
||||
>
|
||||
<div className="description-manage-alignment">
|
||||
<label className="description-manage-alignment-label">
|
||||
Alignment
|
||||
</label>
|
||||
<Select
|
||||
options={alignmentOptions}
|
||||
value={alignment === null ? null : alignment.id}
|
||||
onChange={this.handleAlignmentChange}
|
||||
name="alignment-select"
|
||||
/>
|
||||
{alignmentDescriptionNode}
|
||||
</div>
|
||||
{this.renderBackgroundUi()}
|
||||
<Accordion
|
||||
summary="Character Details"
|
||||
summaryMetaItems={["Alignment", "Faith", "Lifestyle"]}
|
||||
variant="paper"
|
||||
>
|
||||
<div className="description-manage-alignment">
|
||||
<label className="description-manage-alignment-label">
|
||||
Alignment
|
||||
</label>
|
||||
<Select
|
||||
options={alignmentOptions}
|
||||
value={alignment === null ? null : alignment.id}
|
||||
onChange={this.handleAlignmentChange}
|
||||
/>
|
||||
{alignmentDescriptionNode}
|
||||
</div>
|
||||
<div className="description-manage-faith">
|
||||
<InputField
|
||||
label="Faith"
|
||||
initialValue={faith}
|
||||
onBlur={this.handleFaithChange}
|
||||
maxLength={512}
|
||||
inputProps={
|
||||
{
|
||||
spellCheck: false,
|
||||
autoComplete: "off",
|
||||
} as HTMLAttributes<HTMLInputElement>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="description-manage-lifestyle">
|
||||
<label className="description-manage-lifestyle-label">
|
||||
Lifestyle
|
||||
</label>
|
||||
<Select
|
||||
options={lifestyleOptions}
|
||||
value={lifestyle === null ? null : lifestyle.id}
|
||||
onChange={this.handleLifestyleChange}
|
||||
/>
|
||||
{lifestyle !== null && (
|
||||
<CollapsibleContent className="description-manage-lifestyle-desc">
|
||||
{lifestyle.description ? lifestyle.description : ""}
|
||||
</CollapsibleContent>
|
||||
)}
|
||||
</div>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Physical Characteristics"
|
||||
summaryMetaItems={[
|
||||
"Hair",
|
||||
"Skin",
|
||||
"Eyes",
|
||||
"Height",
|
||||
"Weight",
|
||||
"Age",
|
||||
"Gender",
|
||||
]}
|
||||
variant="paper"
|
||||
>
|
||||
<div className="description-manage-faith">
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Hair"
|
||||
initialValue={hair}
|
||||
onBlur={this.handleHairChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Skin"
|
||||
initialValue={skin}
|
||||
onBlur={this.handleSkinChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Eyes"
|
||||
initialValue={eyes}
|
||||
onBlur={this.handleEyesChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Height"
|
||||
initialValue={height}
|
||||
onBlur={this.handleHeightChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Weight (lbs)"
|
||||
type="number"
|
||||
initialValue={weight}
|
||||
onBlur={this.handleWeightChange}
|
||||
inputProps={numberInputAttributes}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Age (Years)"
|
||||
type="number"
|
||||
initialValue={age}
|
||||
onBlur={this.handleAgeChange}
|
||||
inputProps={numberInputAttributes}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Gender"
|
||||
initialValue={gender}
|
||||
onBlur={this.handleGenderChange}
|
||||
maxLength={128}
|
||||
/>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Personal Characteristics"
|
||||
summaryMetaItems={["Personality", "Ideals", "Bonds", "Flaws"]}
|
||||
variant="paper"
|
||||
>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Personality Traits</h3>}
|
||||
editButtonLabel="Edit Traits"
|
||||
addButtonLabel="Add Traits"
|
||||
placeholder="Add traits here..."
|
||||
content={this.getTraitContent(
|
||||
Constants.TraitTypeEnum.PERSONALITY_TRAITS
|
||||
)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.PERSONALITY_TRAITS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList(
|
||||
"Personality Traits",
|
||||
"personalityTraits",
|
||||
"Choose Two"
|
||||
)}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Ideals</h3>}
|
||||
editButtonLabel="Edit Ideals"
|
||||
addButtonLabel="Add Ideals"
|
||||
placeholder="Add ideals here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.IDEALS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.IDEALS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Ideals", "ideals")}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Bonds</h3>}
|
||||
editButtonLabel="Edit Bonds"
|
||||
addButtonLabel="Add Bonds"
|
||||
placeholder="Add bonds here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.BONDS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.BONDS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Bonds", "bonds")}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Flaws</h3>}
|
||||
editButtonLabel="Edit Flaws"
|
||||
addButtonLabel="Add Flaws"
|
||||
placeholder="Add flaws here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.FLAWS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.FLAWS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Flaws", "flaws")}
|
||||
/>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Notes"
|
||||
summaryMetaItems={[
|
||||
"Organizations",
|
||||
"Allies",
|
||||
"Enemies",
|
||||
"Backstory",
|
||||
"Other",
|
||||
]}
|
||||
variant="paper"
|
||||
>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Organizations</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add organization notes here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ORGANIZATIONS)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ORGANIZATIONS
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Are there any important organizations your character belongs
|
||||
to? Any societies, orders, cults, or agencies?
|
||||
</p>
|
||||
label="Faith"
|
||||
initialValue={faith}
|
||||
onBlur={this.handleFaithChange}
|
||||
maxLength={512}
|
||||
inputProps={
|
||||
{
|
||||
spellCheck: false,
|
||||
autoComplete: "off",
|
||||
} as HTMLAttributes<HTMLInputElement>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Allies</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add allies here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ALLIES)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ALLIES
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
With whom does your character associate? When in need of aid,
|
||||
do they seek out their kinfolk, followers of their deity, or
|
||||
other members of their order? What groups or individuals are
|
||||
they aligned with?
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div className="description-manage-lifestyle">
|
||||
<label className="description-manage-lifestyle-label">
|
||||
Lifestyle
|
||||
</label>
|
||||
<Select
|
||||
options={lifestyleOptions}
|
||||
value={lifestyle === null ? null : lifestyle.id}
|
||||
onChange={this.handleLifestyleChange}
|
||||
name="lifestyle-select"
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Enemies</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add enemies here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ENEMIES)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ENEMIES
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Who does your character fear or fight? Have they sworn a vow
|
||||
to rid the world of undead? Is there an order or organization
|
||||
they are opposed to? Are there any specific foes from their
|
||||
past?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Backstory</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add a backstory..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.BACKSTORY)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.BACKSTORY
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Talk about your character's origins. Where are they from? How
|
||||
did they end up adventuring? How did they choose their class?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Other</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add additional notes here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.OTHER)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.OTHER
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Anything at all you'd like to mention about your character.
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
</PageBody>
|
||||
{lifestyle !== null && (
|
||||
<CollapsibleContent className="description-manage-lifestyle-desc">
|
||||
{lifestyle.description ? lifestyle.description : ""}
|
||||
</CollapsibleContent>
|
||||
)}
|
||||
</div>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Physical Characteristics"
|
||||
summaryMetaItems={[
|
||||
"Hair",
|
||||
"Skin",
|
||||
"Eyes",
|
||||
"Height",
|
||||
"Weight",
|
||||
"Age",
|
||||
"Gender",
|
||||
]}
|
||||
variant="paper"
|
||||
>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Hair"
|
||||
initialValue={hair}
|
||||
onBlur={this.handleHairChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Skin"
|
||||
initialValue={skin}
|
||||
onBlur={this.handleSkinChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Eyes"
|
||||
initialValue={eyes}
|
||||
onBlur={this.handleEyesChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Height"
|
||||
initialValue={height}
|
||||
onBlur={this.handleHeightChange}
|
||||
maxLength={50}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Weight (lbs)"
|
||||
type="number"
|
||||
initialValue={weight}
|
||||
onBlur={this.handleWeightChange}
|
||||
inputProps={numberInputAttributes}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Age (Years)"
|
||||
type="number"
|
||||
initialValue={age}
|
||||
onBlur={this.handleAgeChange}
|
||||
inputProps={numberInputAttributes}
|
||||
/>
|
||||
<InputField
|
||||
className={styles.inputField}
|
||||
label="Gender"
|
||||
initialValue={gender}
|
||||
onBlur={this.handleGenderChange}
|
||||
maxLength={128}
|
||||
/>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Personal Characteristics"
|
||||
summaryMetaItems={["Personality", "Ideals", "Bonds", "Flaws"]}
|
||||
variant="paper"
|
||||
>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Personality Traits</h3>}
|
||||
editButtonLabel="Edit Traits"
|
||||
addButtonLabel="Add Traits"
|
||||
placeholder="Add traits here..."
|
||||
content={this.getTraitContent(
|
||||
Constants.TraitTypeEnum.PERSONALITY_TRAITS
|
||||
)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.PERSONALITY_TRAITS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList(
|
||||
"Personality Traits",
|
||||
"personalityTraits",
|
||||
"Choose Two"
|
||||
)}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Ideals</h3>}
|
||||
editButtonLabel="Edit Ideals"
|
||||
addButtonLabel="Add Ideals"
|
||||
placeholder="Add ideals here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.IDEALS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.IDEALS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Ideals", "ideals")}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Bonds</h3>}
|
||||
editButtonLabel="Edit Bonds"
|
||||
addButtonLabel="Add Bonds"
|
||||
placeholder="Add bonds here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.BONDS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.BONDS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Bonds", "bonds")}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Flaws</h3>}
|
||||
editButtonLabel="Edit Flaws"
|
||||
addButtonLabel="Add Flaws"
|
||||
placeholder="Add flaws here..."
|
||||
content={this.getTraitContent(Constants.TraitTypeEnum.FLAWS)}
|
||||
onSave={this.handleSaveTrait.bind(
|
||||
this,
|
||||
Constants.TraitTypeEnum.FLAWS
|
||||
)}
|
||||
extraNode={this.renderTextareaSuggestionList("Flaws", "flaws")}
|
||||
/>
|
||||
</Accordion>
|
||||
<Accordion
|
||||
summary="Notes"
|
||||
summaryMetaItems={[
|
||||
"Organizations",
|
||||
"Allies",
|
||||
"Enemies",
|
||||
"Backstory",
|
||||
"Other",
|
||||
]}
|
||||
variant="paper"
|
||||
>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Organizations</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add organization notes here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ORGANIZATIONS)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ORGANIZATIONS
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Are there any important organizations your character belongs to?
|
||||
Any societies, orders, cults, or agencies?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Allies</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add allies here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ALLIES)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ALLIES
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
With whom does your character associate? When in need of aid, do
|
||||
they seek out their kinfolk, followers of their deity, or other
|
||||
members of their order? What groups or individuals are they
|
||||
aligned with?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Enemies</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add enemies here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.ENEMIES)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.ENEMIES
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Who does your character fear or fight? Have they sworn a vow to
|
||||
rid the world of undead? Is there an order or organization they
|
||||
are opposed to? Are there any specific foes from their past?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Backstory</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add a backstory..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.BACKSTORY)}
|
||||
onSave={this.handleSaveNote.bind(
|
||||
this,
|
||||
Constants.NoteKeyEnum.BACKSTORY
|
||||
)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Talk about your character's origins. Where are they from? How
|
||||
did they end up adventuring? How did they choose their class?
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
<EditorWithDialog
|
||||
heading={<h3>Other</h3>}
|
||||
editButtonLabel="Edit Notes"
|
||||
addButtonLabel="Add Notes"
|
||||
placeholder="Add additional notes here..."
|
||||
content={this.getNoteContent(Constants.NoteKeyEnum.OTHER)}
|
||||
onSave={this.handleSaveNote.bind(this, Constants.NoteKeyEnum.OTHER)}
|
||||
extraNode={
|
||||
<p className="description-suggestion-info">
|
||||
Anything at all you'd like to mention about your character.
|
||||
</p>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user