Skip to content

Commit

Permalink
feat: wip, initial create from library dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
henryk1229 committed Aug 11, 2023
1 parent 15a8122 commit c06da31
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 1 deletion.
190 changes: 190 additions & 0 deletions src/components/CreateFromLibraryDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import Button from "@material-ui/core/Button";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import TextField from "@material-ui/core/TextField";
import Tooltip from "@material-ui/core/Tooltip";
import Autocomplete from "@material-ui/lab/Autocomplete";
import type { Campaign } from "@spoke/spoke-codegen";
import React, { useCallback, useMemo, useState } from "react";

// TODO - campaign variables
type DefaultTemplateCampaign = Pick<
Campaign,
"title" | "description" | "interactionSteps" | "campaignVariables"
>;

// TODO - hook up github page
const DUMMY_LIBRARY = [
{
title: "GOTV",
description: "a get out the vote campaign for your candidate or issue",
interactionSteps: {
scriptOptions: [""]
}
},
{
title: "Fundraising",
description: "a fundraising campaign for your candidate or issue",
interactionSteps: {
scriptOptions: [""]
}
},
{
title: "Voter Reg",
description: "a voter registration campaign for your area",
interactionSteps: {
scriptOptions: [""]
}
}
];

export interface CreateCampaignFromLibraryDialogProps {
organizationId: string;
open: boolean;
onClose?: () => Promise<void> | void;
}

// eslint-disable-next-line max-len
export const CreateCampaignFromLibraryDialog: React.FC<CreateCampaignFromLibraryDialogProps> = (
props
) => {
const [
selectedTemplate,
setSelectedTemplate
] = useState<TemplateCampaignFragment | null>(null);
const [quantity, setQuantity] = useState<number | null>(1);

// TODO
const working = false;

// TODO - fetch default templates
// const { data, error } = useGetTemplateCampaignsQuery({
// variables: { organizationId: props.organizationId }
// });
// const [
// createFromTemplate,
// { loading: working }
// ] = useCreateCampaignFromTemplateMutation({
// refetchQueries: [GetAdminCampaignsDocument]
// });

const templates = DUMMY_LIBRARY;
// data?.organization?.templateCampaigns?.edges?.map(({ node }) => node) ?? [];

const handleChangeTemplate = useCallback(
(
_event: React.ChangeEvent<unknown>,
value: DefaultTemplateCampaign | null
) => {
setSelectedTemplate(value);
},
[setSelectedTemplate]
);

const handleKeyDown: React.KeyboardEventHandler = useCallback((event) => {
const badKey = event.keyCode === 69 || event.keyCode === 101;
if (badKey) event.preventDefault();
}, []);

const handleChangeQuantity: React.ChangeEventHandler<
HTMLInputElement | HTMLTextAreaElement
> = useCallback(
(event) => {
const textValue = event.target.value.replace(/\D/g, "");
const intValue = parseInt(textValue, 10);
const finalValue = Number.isNaN(intValue) ? null : Math.max(1, intValue);
setQuantity(finalValue);
},
[setQuantity]
);

const canCreate = useMemo(
() => quantity !== null && selectedTemplate !== null && !working,
[quantity, selectedTemplate, working]
);

const handleClickCreate = useCallback(async () => {
if (!(quantity !== null && selectedTemplate !== null && !working)) return;

// await createFromTemplate({
// variables: { templateId: selectedTemplate.id, quantity }
// });
props.onClose?.();
}, [quantity, selectedTemplate, props.onClose]);

return (
<Dialog
onClose={props.onClose}
aria-labelledby="create-from-library-dialog-title"
open={props.open}
>
<DialogTitle id="create-from-library-dialog-title">
Select Campaign from Spoke Rewired Library
</DialogTitle>
<DialogContent>
<DialogContentText>Select a campaign to get started</DialogContentText>
{/* {error && (
<DialogContentText>
Error fetching templates: {error.message}
</DialogContentText>
)} */}
<Autocomplete
options={templates}
getOptionLabel={(template) => template.title}
value={selectedTemplate}
onChange={handleChangeTemplate}
style={{ width: 300 }}
renderInput={(params) => (
<TextField {...params} label="Template campaign name" />
)}
/>
<br />
<Tooltip
title="View an outline of this campaign's script"
placement="top"
>
<Button
key="open-script-preview"
variant="contained"
onClick={() => {
console.log("TODO");
// window.open(`/preview/${previewUrl}`, "_blank");
}}
size="small"
>
Open Script Preview
</Button>
</Tooltip>
<br />
<TextField
fullWidth
label="Quantity"
type="number"
value={quantity ?? ""}
onChange={handleChangeQuantity}
onKeyDown={handleKeyDown}
/>
</DialogContent>
<DialogActions>
<Button onClick={props.onClose}>Cancel</Button>
<Button
color="primary"
disabled={!canCreate}
onClick={handleClickCreate}
>
Create
</Button>
</DialogActions>
</Dialog>
);
};

export default CreateCampaignFromLibraryDialog;

// github page
// - lists default template campaigns
// - has script preview for each campaign?
// - script preview button here similar to ScriptPreviewButton but open link to github page?
15 changes: 14 additions & 1 deletion src/containers/AdminCampaignList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle";
import CreateIcon from "@material-ui/icons/Create";
import FileCopyIcon from "@material-ui/icons/FileCopyOutlined";
import LibraryAddOutlinedIcon from "@material-ui/icons/LibraryAddOutlined";
import SpeedDial from "@material-ui/lab/SpeedDial";
import SpeedDialAction from "@material-ui/lab/SpeedDialAction";
import SpeedDialIcon from "@material-ui/lab/SpeedDialIcon";
Expand All @@ -18,6 +19,7 @@ import { withRouter } from "react-router-dom";
import { compose } from "recompose";

import CreateCampaignFromTemplateDialog from "../components/CreateCampaignFromTemplateDialog";
import CreateCampaignFromLibraryDialog from "../components/CreateFromLibraryDialog";
import LoadingIndicator from "../components/LoadingIndicator";
import theme from "../styles/theme";
import { withAuthzContext } from "./AuthzProvider";
Expand Down Expand Up @@ -47,7 +49,8 @@ class AdminCampaignList extends React.Component {
releasingInProgress: false,
releasingAllReplies: false,
releaseAllRepliesError: undefined,
releaseAllRepliesResult: undefined
releaseAllRepliesResult: undefined,
createFromLibraryOpen: false
};

handleClickNewButton = async () => {
Expand Down Expand Up @@ -289,13 +292,23 @@ class AdminCampaignList extends React.Component {
tooltipTitle="Create from Template"
onClick={() => this.setState({ createFromTemplateOpen: true })}
/>
<SpeedDialAction
icon={<LibraryAddOutlinedIcon />}
tooltipTitle="Create from Library"
onClick={() => this.setState({ createFromLibraryOpen: true })}
/>
</SpeedDial>
) : null}
<CreateCampaignFromTemplateDialog
organizationId={organizationId}
open={this.state.createFromTemplateOpen}
onClose={() => this.setState({ createFromTemplateOpen: false })}
/>
<CreateCampaignFromLibraryDialog
organizationId={organizationId}
open={this.state.createFromLibraryOpen}
onClose={() => this.setState({ createFromLibraryOpen: false })}
/>
</div>
);
}
Expand Down

0 comments on commit c06da31

Please sign in to comment.