diff --git a/package.json b/package.json
index d288a04..981b9e3 100644
--- a/package.json
+++ b/package.json
@@ -79,12 +79,6 @@
"plugin:prettier/recommended"
]
},
- "ava": {
- "require": [
- "babel-register"
- ],
- "babel": "inherit"
- },
"browserslist": {
"production": [
">0.2%",
diff --git a/src/components/OrgLink.js b/src/components/OrgLink.js
new file mode 100644
index 0000000..11a8381
--- /dev/null
+++ b/src/components/OrgLink.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import { string } from 'prop-types';
+
+import { Link } from 'react-router-dom';
+
+import { slugify } from '../utils';
+
+const OrgLink = ({ name, uuid }) => (
+
+ {name}
+
+);
+
+OrgLink.propTypes = {
+ name: string.isRequired,
+ uuid: string.isRequired,
+};
+
+export default OrgLink;
diff --git a/src/components/PdfForm.js b/src/components/PdfForm.js
new file mode 100644
index 0000000..7343d26
--- /dev/null
+++ b/src/components/PdfForm.js
@@ -0,0 +1,147 @@
+import React, { useState } from 'react';
+
+import { bool, func, number, shape, string } from 'prop-types';
+
+import OrganizationSelector from '../containers/OrganizationSelector';
+import UserSelector from '../containers/UserSelector';
+
+const onNumericChange = (currentValue, setter) => (e) => {
+ const parsed = parseInt(e.target.value, 10);
+ isNaN(parsed) ? setter(currentValue) : setter(parsed);
+};
+
+const PdfForm = ({ onSubmit, defaultValues = {} }) => {
+ const [organizationNameMatch, setOrganizationNameMatch] = useState(
+ defaultValues.organization && {
+ label: defaultValues.organization.name,
+ value: defaultValues.organization.uuid,
+ }
+ );
+ const [organization, setOrganization] = useState(
+ defaultValues.organization && defaultValues.organization.uuid
+ );
+ const [userNameMatch, setUserNameMatch] = useState(
+ defaultValues.user && {
+ label: defaultValues.user.name,
+ value: defaultValues.user.uuid,
+ }
+ );
+ const [user, setUser] = useState(
+ defaultValues.user && defaultValues.user.uuid
+ );
+ const [year, setYear] = useState(defaultValues.year);
+ const [url, setUrl] = useState(defaultValues.url);
+ const [currentPage, setCurrentPage] = useState(defaultValues.currentPage);
+ const [done, setDone] = useState(defaultValues.done);
+
+ const handleSubmit = (e) => {
+ e.preventDefault();
+ onSubmit({
+ organization,
+ user,
+ url,
+ done: !!done,
+ year,
+ current_page: currentPage,
+ });
+ };
+
+ const onYearChange = onNumericChange(year, setYear);
+ const onCurrentPageChange = onNumericChange(currentPage, setCurrentPage);
+
+ return (
+
+ );
+};
+
+PdfForm.propTypes = {
+ onSubmit: func.isRequired,
+ defaultValues: shape({
+ organization: shape({
+ uuid: string,
+ name: string,
+ }),
+ user: shape({
+ uuid: string,
+ name: string,
+ }),
+ url: string,
+ done: bool,
+ year: number,
+ currentPage: number,
+ }),
+};
+
+PdfForm.defaultProps = {
+ defaultValues: {
+ url: '',
+ done: false,
+ year: new Date().getUTCFullYear(),
+ currentPage: 1,
+ },
+};
+
+export default PdfForm;
diff --git a/src/containers/AdminLinks.js b/src/containers/AdminLinks.js
index 6d94260..125d0bc 100644
--- a/src/containers/AdminLinks.js
+++ b/src/containers/AdminLinks.js
@@ -7,6 +7,7 @@ const AdminLinks = ({ user }) =>
user ? (
<>
+
>
) : (
diff --git a/src/containers/EditPdf.js b/src/containers/EditPdf.js
new file mode 100644
index 0000000..049f601
--- /dev/null
+++ b/src/containers/EditPdf.js
@@ -0,0 +1,76 @@
+import React from 'react';
+import { string } from 'prop-types';
+
+import { useParams } from 'react-router-dom';
+
+import { gql, useMutation, useQuery } from '@apollo/client';
+
+import PdfForm from '../components/PdfForm';
+
+const GET_PDF = gql`
+ query getPdf($uuid: String) {
+ pdf(uuid: $uuid) {
+ organization {
+ name
+ uuid
+ }
+ user {
+ uuid
+ name
+ }
+ url
+ uuid
+ year
+ done
+ }
+ }
+`;
+
+const UPDATE_PDF = gql`
+ mutation updatePdf($input: PdfInput!) {
+ upsertPdf(input: $input) {
+ uuid
+ }
+ }
+`;
+
+const EditPdf = () => {
+ const { uuid } = useParams();
+
+ const { loading, error, data } = useQuery(GET_PDF, {
+ variables: { uuid },
+ });
+
+ const [
+ updatePdf,
+ { loading: updatePdfLoading, error: updatePdfError, data: updatePdfData },
+ ] = useMutation(UPDATE_PDF);
+
+ if (loading) return <>Loading...>;
+
+ if (error) throw new Error('todo catch these?');
+
+ const updateError = updatePdfError && {updatePdfError.message}
;
+ const updated = updatePdfData && Updated PDF
;
+
+ const onSubmit = (input) => {
+ updatePdf({
+ variables: {
+ input: { ...input, uuid },
+ },
+ });
+ };
+
+ return (
+ <>
+
+ {updated}
+ {updatePdfLoading && 'Loading...'}
+ {updateError}
+ >
+ );
+};
+
+EditPdf.propTypes = { uuid: string.isRequired };
+
+export default EditPdf;
diff --git a/src/containers/ListPdfs.js b/src/containers/ListPdfs.js
new file mode 100644
index 0000000..5d0118e
--- /dev/null
+++ b/src/containers/ListPdfs.js
@@ -0,0 +1,68 @@
+import React from 'react';
+import { gql, useQuery } from '@apollo/client';
+
+import { Link } from 'react-router-dom';
+
+import OrgLink from '../components/OrgLink';
+
+const LIST_PDFS_QUERY = gql`
+ query pdfs {
+ pdfs(limit: 9999, limitToCurrentUser: false) {
+ organization {
+ name
+ uuid
+ }
+ user {
+ uuid
+ name
+ }
+ url
+ uuid
+ year
+ done
+ }
+ }
+`;
+
+const ListPdfs = () => {
+ const { loading, error, data } = useQuery(LIST_PDFS_QUERY);
+
+ if (loading) return <>Loading...>;
+
+ if (error) throw new Error('todo catch these?');
+
+ return (
+
+
+
+ User |
+ Organization |
+ PDF URL |
+ Year |
+ Done? |
+ |
+
+
+
+ {data.pdfs.map(({ url, uuid, year, done, organization, user }) => (
+
+ {user ? user.name : '-'} |
+
+
+ |
+
+ {url}
+ |
+ {year} |
+ {done ? '✔️' : ''} |
+
+ edit
+ |
+
+ ))}
+
+
+ );
+};
+
+export default ListPdfs;
diff --git a/src/containers/ManagePdfs.js b/src/containers/ManagePdfs.js
new file mode 100644
index 0000000..6ac838a
--- /dev/null
+++ b/src/containers/ManagePdfs.js
@@ -0,0 +1,77 @@
+import React from 'react';
+
+import { gql, useMutation } from '@apollo/client';
+
+import PdfForm from '../components/PdfForm';
+
+import ListPdfs from './ListPdfs';
+
+const ADD_PDF = gql`
+ mutation addPdf($input: PdfInput!) {
+ upsertPdf(input: $input) {
+ uuid
+ }
+ }
+`;
+
+const ADD_PDF_OPTS = {
+ update(cache, { data: { upsertPdf } }) {
+ cache.modify({
+ fields: {
+ pdfs(existingPdfs = []) {
+ const newPdfRef = cache.writeFragment({
+ data: upsertPdf,
+ fragment: gql`
+ fragment NewPdf on Pdf {
+ id
+ type
+ }
+ `,
+ });
+ return [...existingPdfs, newPdfRef];
+ },
+ },
+ });
+ },
+};
+
+const ManagePdfs = () => {
+ const [
+ addPdf,
+ { loading: addPdfLoading, error: addPdfError, data: addPdfData },
+ ] = useMutation(ADD_PDF, ADD_PDF_OPTS);
+
+ if (addPdfError) {
+ console.log(
+ 'xxx',
+ addPdfError.message,
+ addPdfError.graphQLErrors,
+ addPdfError.extraInfo,
+ addPdfError.networkError,
+ addPdfError.errors,
+ addPdfData
+ );
+ }
+ const error = addPdfError && {addPdfError.message}
;
+ const created = addPdfData && Added PDF {addPdfData.upsertPdf.uuid}
;
+
+ const onSubmit = (input) => {
+ addPdf({
+ variables: {
+ input,
+ },
+ });
+ };
+
+ return (
+
+
+
+ {created}
+ {addPdfLoading && 'Loading...'}
+ {error}
+
+ );
+};
+
+export default ManagePdfs;
diff --git a/src/containers/OrgNteeTags.js b/src/containers/OrgNteeTags.js
index f496d27..94a84ed 100644
--- a/src/containers/OrgNteeTags.js
+++ b/src/containers/OrgNteeTags.js
@@ -1,20 +1,15 @@
import React from 'react';
-import {
- Link,
- Switch,
- Route,
- useRouteMatch,
- useParams,
-} from 'react-router-dom';
+import { Switch, Route, useRouteMatch, useParams } from 'react-router-dom';
import { useQuery, gql } from '@apollo/client';
import Helmet from 'react-helmet';
import Page from '../components/Page';
+import OrgLink from '../components/OrgLink';
-import { dollarsFormatter, slugify } from '../utils';
+import { dollarsFormatter } from '../utils';
const GET_ORG_NTEE_TAG = gql`
query getNteeOrganizationTypes($nteeUuid: String!) {
@@ -93,11 +88,9 @@ const OrgNteeTag = () => {
ntee.organizations.map((org, i) => (
-
- {org.name}
-
+
+
+
|
{org.totalFunded
diff --git a/src/containers/OrganizationSelector.js b/src/containers/OrganizationSelector.js
index 5b3ab43..4893a92 100644
--- a/src/containers/OrganizationSelector.js
+++ b/src/containers/OrganizationSelector.js
@@ -33,12 +33,12 @@ const OrganizationSelector = ({ onOrgSelected, setValue, value }) => {
debugger;
}
- const options = data.organizations.map(({ name, uuid }) => {
- return {
- label: name,
- value: uuid,
- };
- });
+ const options = data.organizations
+ ? data.organizations.map(({ name, uuid }) => ({
+ label: name,
+ value: uuid,
+ }))
+ : [value];
const handleInputChange = (inputValue) => {
setValue(inputValue);
@@ -52,6 +52,7 @@ const OrganizationSelector = ({ onOrgSelected, setValue, value }) => {
return (
|