diff --git a/packages/client/src/App.tsx b/packages/client/src/App.tsx
index 4a2d8cd5..6bc30d06 100644
--- a/packages/client/src/App.tsx
+++ b/packages/client/src/App.tsx
@@ -7,8 +7,8 @@ import { NewProject } from './pages/projects/NewProject';
import { ProjectControl } from './pages/projects/ProjectControl';
import { SuccessPage } from './pages/SuccessPage';
import { NewStudy } from './pages/studies/NewStudy';
-import { ContributePage } from './pages/contribute/Contribute';
-import { TagView } from './components/TagView.component';
+import { ContributeLanding } from './pages/contribute/ContributeLanding';
+import { TaggingInterface } from './pages/contribute/TaggingInterface';
import { StudyControl } from './pages/studies/StudyControl';
import { ProjectAccess } from './pages/datasets/ProjectAccess';
import { ProjectUserPermissions } from './pages/projects/ProjectUserPermissions';
@@ -131,8 +131,8 @@ const MyRoutes: FC = () => {
} />
} />
} />
- } />
- } />
+ } />
+ } />
} />
diff --git a/packages/client/src/components/EntryView.component.tsx b/packages/client/src/components/EntryView.component.tsx
index cb8b619b..2be4d788 100644
--- a/packages/client/src/components/EntryView.component.tsx
+++ b/packages/client/src/components/EntryView.component.tsx
@@ -1,32 +1,38 @@
+import { Box } from '@mui/material';
import { Entry } from '../graphql/graphql';
import { useEffect, useRef } from 'react';
export interface EntryViewProps {
entry: Entry;
width: number;
+ pauseFrame?: 'start' | 'end' | 'middle';
+ autoPlay?: boolean;
+ mouseOverControls?: boolean;
+ displayControls?: boolean;
}
export const EntryView: React.FC = (props) => {
- return getEntryView(props.entry);
+ return getEntryView(props);
};
-const getEntryView = (entry: Entry) => {
- if (entry.contentType.startsWith('video/')) {
- return ;
+const getEntryView = (props: EntryViewProps) => {
+ if (props.entry.contentType.startsWith('video/')) {
+ return ;
}
- if (entry.contentType.startsWith('image/')) {
- return ;
+ if (props.entry.contentType.startsWith('image/')) {
+ return ;
}
console.error('Unknown entry type');
return Placeholder
;
};
+// TODO: Add in ability to control video play, pause, and middle frame selection
const VideoEntryView: React.FC = (props) => {
const videoRef = useRef(null);
/** Start the video at the begining */
const handleStart: React.MouseEventHandler = () => {
- if (!videoRef.current) {
+ if (!videoRef.current || (props.mouseOverControls != undefined && !props.mouseOverControls)) {
return;
}
videoRef.current.currentTime = 0;
@@ -35,20 +41,25 @@ const VideoEntryView: React.FC = (props) => {
/** Stop the video */
const handleStop: React.MouseEventHandler = () => {
- if (!videoRef.current) {
+ if (!videoRef.current || (props.mouseOverControls != undefined && !props.mouseOverControls)) {
return;
}
videoRef.current.pause();
- setMiddleFrame();
+ setPauseFrame();
};
/** Set the video to the middle frame */
- const setMiddleFrame = async () => {
+ const setPauseFrame = async () => {
if (!videoRef.current) {
return;
}
- const duration = await getDuration();
- videoRef.current.currentTime = duration / 2;
+
+ if (!props.pauseFrame || props.pauseFrame === 'middle') {
+ const duration = await getDuration();
+ videoRef.current.currentTime = duration / 2;
+ } else if (props.pauseFrame === 'start') {
+ videoRef.current.currentTime = 0;
+ }
};
/** Get the duration, there is a known issue on Chrome with some audio/video durations */
@@ -81,16 +92,29 @@ const VideoEntryView: React.FC = (props) => {
// Set the video to the middle frame when the video is loaded
useEffect(() => {
- setMiddleFrame();
+ setPauseFrame();
}, [videoRef.current]);
return (
-
+
+
+
);
};
const ImageEntryView: React.FC = (props) => {
- return
;
+ return (
+
+
+
+ );
};
diff --git a/packages/client/src/components/SideBar.component.tsx b/packages/client/src/components/SideBar.component.tsx
index 832e1960..91fcbdc4 100644
--- a/packages/client/src/components/SideBar.component.tsx
+++ b/packages/client/src/components/SideBar.component.tsx
@@ -50,7 +50,7 @@ export const SideBar: FC = ({ open, drawerWidth }) => {
name: 'Contribute',
action: () => {},
icon: ,
- subItems: [{ name: 'Tag in Study', action: () => navigate('/study/contribute') }]
+ subItems: [{ name: 'Tag in Study', action: () => navigate('/contribute/landing') }]
},
{
name: 'Logout',
diff --git a/packages/client/src/components/TagView.component.tsx b/packages/client/src/components/TagView.component.tsx
deleted file mode 100644
index 5d2fa274..00000000
--- a/packages/client/src/components/TagView.component.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import { JsonForms } from '@jsonforms/react';
-import { materialRenderers, materialCells } from '@jsonforms/material-renderers';
-import { useLocation, useNavigate } from 'react-router-dom';
-import { Box, Button, Container, Typography } from '@mui/material';
-import { useState } from 'react';
-
-export const TagView = () => {
- const { state } = useLocation();
- console.log(state);
- const [initialData, setData] = useState({
- name: '',
- name_noDefault: '',
- description: '',
- done: true,
- rating: 0,
- cost: 3.14,
- dueDate: '2019-05-01'
- });
-
- const navigate = useNavigate();
-
- const handleNext = () => {
- //first save tagged data by sending it to backend
- //then tag the next entry
-
- setData({ name: '', name_noDefault: '', description: '', done: false, rating: 0, cost: 0, dueDate: '2023-07-24' });
- };
-
- const handleClick = (route: string) => {
- navigate('/' + route);
- };
-
- return (
-
- {state ? (
-
-
-
-
-
-
-
-
- ) : (
-
- No Entries Tagged
-
-
- )}
-
- );
-};
diff --git a/packages/client/src/components/contribute/NoTagNotification.component.tsx b/packages/client/src/components/contribute/NoTagNotification.component.tsx
new file mode 100644
index 00000000..05382cf9
--- /dev/null
+++ b/packages/client/src/components/contribute/NoTagNotification.component.tsx
@@ -0,0 +1,14 @@
+import { Stack, Typography } from '@mui/material';
+
+export interface NoTagNotificationProps {
+ studyName: string;
+}
+
+export const NoTagNotification: React.FC = ({ studyName }) => {
+ return (
+
+ No tags Remaining
+ No tags left for "{studyName}", please check back later
+
+ );
+};
diff --git a/packages/client/src/components/contribute/TagForm.component.tsx b/packages/client/src/components/contribute/TagForm.component.tsx
new file mode 100644
index 00000000..9d627d5a
--- /dev/null
+++ b/packages/client/src/components/contribute/TagForm.component.tsx
@@ -0,0 +1,64 @@
+import { JsonForms } from '@jsonforms/react';
+import { Study } from '../../graphql/graphql';
+import { materialRenderers } from '@jsonforms/material-renderers';
+import { SetStateAction, useState, Dispatch } from 'react';
+import { Box, Stack, Button } from '@mui/material';
+import { ErrorObject } from 'ajv';
+
+export interface TagFormProps {
+ study: Study;
+ setTagData: Dispatch>;
+}
+
+export const TagForm: React.FC = (props) => {
+ const [data, setData] = useState({});
+ const [dataValid, setDataValid] = useState(false);
+
+ const handleFormChange = (data: any, errors: ErrorObject[] | undefined) => {
+ setData(data);
+
+ // No errors, data could be submitted
+ if (!errors || errors.length === 0) {
+ setDataValid(true);
+ } else {
+ setDataValid(false);
+ }
+ };
+
+ const handleSubmit = () => {
+ // Ideally should not get here
+ if (!dataValid) {
+ return;
+ }
+ props.setTagData(data);
+
+ // Get ready for the next tag
+ handleClear();
+ };
+
+ const handleClear = () => {
+ setData({});
+ };
+
+ return (
+
+
+ handleFormChange(data, errors)}
+ renderers={materialRenderers}
+ />
+
+
+
+
+
+
+ );
+};
diff --git a/packages/client/src/graphql/entry.ts b/packages/client/src/graphql/entry.ts
index 4585bdab..6e170a4e 100644
--- a/packages/client/src/graphql/entry.ts
+++ b/packages/client/src/graphql/entry.ts
@@ -10,7 +10,7 @@ export type EntryForDatasetQueryVariables = Types.Exact<{
}>;
-export type EntryForDatasetQuery = { __typename?: 'Query', entryForDataset: Array<{ __typename?: 'Entry', _id: string, organization: string, entryID: string, contentType: string, dataset: string, creator?: string | null, dateCreated: any, meta: any, signedUrl: string, signedUrlExpiration: number }> };
+export type EntryForDatasetQuery = { __typename?: 'Query', entryForDataset: Array<{ __typename?: 'Entry', _id: string, organization: string, entryID: string, contentType: string, dataset: string, creator: string, dateCreated: any, meta: any, signedUrl: string, signedUrlExpiration: number }> };
export const EntryForDatasetDocument = gql`
diff --git a/packages/client/src/graphql/graphql.ts b/packages/client/src/graphql/graphql.ts
index ef268a85..60097ca4 100644
--- a/packages/client/src/graphql/graphql.ts
+++ b/packages/client/src/graphql/graphql.ts
@@ -69,7 +69,7 @@ export type Entry = {
__typename?: 'Entry';
_id: Scalars['String']['output'];
contentType: Scalars['String']['output'];
- creator?: Maybe;
+ creator: Scalars['ID']['output'];
dataset: Scalars['ID']['output'];
dateCreated: Scalars['DateTime']['output'];
entryID: Scalars['String']['output'];
diff --git a/packages/client/src/graphql/tag.graphql b/packages/client/src/graphql/tag.graphql
deleted file mode 100644
index 9fff737a..00000000
--- a/packages/client/src/graphql/tag.graphql
+++ /dev/null
@@ -1,5 +0,0 @@
-mutation createTags($study: ID!, $entries: [ID!]!) {
- createTags(study: $study, entries: $entries) {
- _id
- }
-}
diff --git a/packages/client/src/graphql/tag.ts b/packages/client/src/graphql/tag.ts
deleted file mode 100644
index 444b38f6..00000000
--- a/packages/client/src/graphql/tag.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Generated File DO NOT EDIT. */
-/* tslint:disable */
-import * as Types from './graphql';
-
-import { gql } from '@apollo/client';
-import * as Apollo from '@apollo/client';
-const defaultOptions = {} as const;
-export type CreateTagsMutationVariables = Types.Exact<{
- study: Types.Scalars['ID']['input'];
- entries: Array | Types.Scalars['ID']['input'];
-}>;
-
-
-export type CreateTagsMutation = { __typename?: 'Mutation', createTags: Array<{ __typename?: 'Tag', _id: string }> };
-
-
-export const CreateTagsDocument = gql`
- mutation createTags($study: ID!, $entries: [ID!]!) {
- createTags(study: $study, entries: $entries) {
- _id
- }
-}
- `;
-export type CreateTagsMutationFn = Apollo.MutationFunction;
-
-/**
- * __useCreateTagsMutation__
- *
- * To run a mutation, you first call `useCreateTagsMutation` within a React component and pass it any options that fit your needs.
- * When your component renders, `useCreateTagsMutation` returns a tuple that includes:
- * - A mutate function that you can call at any time to execute the mutation
- * - An object with fields that represent the current status of the mutation's execution
- *
- * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
- *
- * @example
- * const [createTagsMutation, { data, loading, error }] = useCreateTagsMutation({
- * variables: {
- * study: // value for 'study'
- * entries: // value for 'entries'
- * },
- * });
- */
-export function useCreateTagsMutation(baseOptions?: Apollo.MutationHookOptions) {
- const options = {...defaultOptions, ...baseOptions}
- return Apollo.useMutation(CreateTagsDocument, options);
- }
-export type CreateTagsMutationHookResult = ReturnType;
-export type CreateTagsMutationResult = Apollo.MutationResult;
-export type CreateTagsMutationOptions = Apollo.BaseMutationOptions;
\ No newline at end of file
diff --git a/packages/client/src/graphql/tag/tag.graphql b/packages/client/src/graphql/tag/tag.graphql
new file mode 100644
index 00000000..8d204df3
--- /dev/null
+++ b/packages/client/src/graphql/tag/tag.graphql
@@ -0,0 +1,27 @@
+mutation createTags($study: ID!, $entries: [ID!]!) {
+ createTags(study: $study, entries: $entries) {
+ _id
+ }
+}
+
+mutation assignTag($study: ID!) {
+ assignTag(study: $study) {
+ _id,
+ entry {
+ _id,
+ organization,
+ entryID,
+ contentType,
+ dataset,
+ creator,
+ dateCreated,
+ meta,
+ signedUrl,
+ signedUrlExpiration
+ }
+ }
+}
+
+mutation completeTag($tag: ID!, $data: JSON!) {
+ completeTag(tag: $tag, data: $data)
+}
diff --git a/packages/client/src/graphql/tag/tag.ts b/packages/client/src/graphql/tag/tag.ts
new file mode 100644
index 00000000..05886d60
--- /dev/null
+++ b/packages/client/src/graphql/tag/tag.ts
@@ -0,0 +1,142 @@
+/* Generated File DO NOT EDIT. */
+/* tslint:disable */
+import * as Types from '../graphql';
+
+import { gql } from '@apollo/client';
+import * as Apollo from '@apollo/client';
+const defaultOptions = {} as const;
+export type CreateTagsMutationVariables = Types.Exact<{
+ study: Types.Scalars['ID']['input'];
+ entries: Array | Types.Scalars['ID']['input'];
+}>;
+
+
+export type CreateTagsMutation = { __typename?: 'Mutation', createTags: Array<{ __typename?: 'Tag', _id: string }> };
+
+export type AssignTagMutationVariables = Types.Exact<{
+ study: Types.Scalars['ID']['input'];
+}>;
+
+
+export type AssignTagMutation = { __typename?: 'Mutation', assignTag?: { __typename?: 'Tag', _id: string, entry: { __typename?: 'Entry', _id: string, organization: string, entryID: string, contentType: string, dataset: string, creator: string, dateCreated: any, meta: any, signedUrl: string, signedUrlExpiration: number } } | null };
+
+export type CompleteTagMutationVariables = Types.Exact<{
+ tag: Types.Scalars['ID']['input'];
+ data: Types.Scalars['JSON']['input'];
+}>;
+
+
+export type CompleteTagMutation = { __typename?: 'Mutation', completeTag: boolean };
+
+
+export const CreateTagsDocument = gql`
+ mutation createTags($study: ID!, $entries: [ID!]!) {
+ createTags(study: $study, entries: $entries) {
+ _id
+ }
+}
+ `;
+export type CreateTagsMutationFn = Apollo.MutationFunction;
+
+/**
+ * __useCreateTagsMutation__
+ *
+ * To run a mutation, you first call `useCreateTagsMutation` within a React component and pass it any options that fit your needs.
+ * When your component renders, `useCreateTagsMutation` returns a tuple that includes:
+ * - A mutate function that you can call at any time to execute the mutation
+ * - An object with fields that represent the current status of the mutation's execution
+ *
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
+ *
+ * @example
+ * const [createTagsMutation, { data, loading, error }] = useCreateTagsMutation({
+ * variables: {
+ * study: // value for 'study'
+ * entries: // value for 'entries'
+ * },
+ * });
+ */
+export function useCreateTagsMutation(baseOptions?: Apollo.MutationHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useMutation(CreateTagsDocument, options);
+ }
+export type CreateTagsMutationHookResult = ReturnType;
+export type CreateTagsMutationResult = Apollo.MutationResult;
+export type CreateTagsMutationOptions = Apollo.BaseMutationOptions;
+export const AssignTagDocument = gql`
+ mutation assignTag($study: ID!) {
+ assignTag(study: $study) {
+ _id
+ entry {
+ _id
+ organization
+ entryID
+ contentType
+ dataset
+ creator
+ dateCreated
+ meta
+ signedUrl
+ signedUrlExpiration
+ }
+ }
+}
+ `;
+export type AssignTagMutationFn = Apollo.MutationFunction;
+
+/**
+ * __useAssignTagMutation__
+ *
+ * To run a mutation, you first call `useAssignTagMutation` within a React component and pass it any options that fit your needs.
+ * When your component renders, `useAssignTagMutation` returns a tuple that includes:
+ * - A mutate function that you can call at any time to execute the mutation
+ * - An object with fields that represent the current status of the mutation's execution
+ *
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
+ *
+ * @example
+ * const [assignTagMutation, { data, loading, error }] = useAssignTagMutation({
+ * variables: {
+ * study: // value for 'study'
+ * },
+ * });
+ */
+export function useAssignTagMutation(baseOptions?: Apollo.MutationHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useMutation(AssignTagDocument, options);
+ }
+export type AssignTagMutationHookResult = ReturnType;
+export type AssignTagMutationResult = Apollo.MutationResult;
+export type AssignTagMutationOptions = Apollo.BaseMutationOptions;
+export const CompleteTagDocument = gql`
+ mutation completeTag($tag: ID!, $data: JSON!) {
+ completeTag(tag: $tag, data: $data)
+}
+ `;
+export type CompleteTagMutationFn = Apollo.MutationFunction;
+
+/**
+ * __useCompleteTagMutation__
+ *
+ * To run a mutation, you first call `useCompleteTagMutation` within a React component and pass it any options that fit your needs.
+ * When your component renders, `useCompleteTagMutation` returns a tuple that includes:
+ * - A mutate function that you can call at any time to execute the mutation
+ * - An object with fields that represent the current status of the mutation's execution
+ *
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
+ *
+ * @example
+ * const [completeTagMutation, { data, loading, error }] = useCompleteTagMutation({
+ * variables: {
+ * tag: // value for 'tag'
+ * data: // value for 'data'
+ * },
+ * });
+ */
+export function useCompleteTagMutation(baseOptions?: Apollo.MutationHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useMutation(CompleteTagDocument, options);
+ }
+export type CompleteTagMutationHookResult = ReturnType;
+export type CompleteTagMutationResult = Apollo.MutationResult;
+export type CompleteTagMutationOptions = Apollo.BaseMutationOptions;
\ No newline at end of file
diff --git a/packages/client/src/pages/contribute/Contribute.tsx b/packages/client/src/pages/contribute/Contribute.tsx
deleted file mode 100644
index dfc8c99d..00000000
--- a/packages/client/src/pages/contribute/Contribute.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import { Typography, Box, Stack, Button } from '@mui/material';
-import placeholder from './placeholder.png';
-import { useNavigate } from 'react-router-dom';
-
-const schema = {
- type: 'object',
- properties: {
- name: {
- type: 'string',
- default: 'foo'
- },
- name_noDefault: {
- type: 'string'
- },
- description: {
- type: 'string',
- default: 'bar'
- },
- done: {
- type: 'boolean',
- default: false
- },
- rating: {
- type: 'integer',
- default: 5
- },
- cost: {
- type: 'number',
- default: 5.5
- },
- dueDate: {
- type: 'string',
- format: 'date',
- default: '2019-04-01'
- }
- },
- required: ['name', 'name_noDefault']
-};
-
-const uischema = {
- type: 'VerticalLayout',
- elements: [
- {
- type: 'Control',
- scope: '#/properties/name'
- },
- {
- type: 'Control',
- scope: '#/properties/name_noDefault'
- },
- {
- type: 'Control',
- label: false,
- scope: '#/properties/done'
- },
- {
- type: 'Control',
- scope: '#/properties/description',
- options: {
- multi: true
- }
- },
- {
- type: 'Control',
- scope: '#/properties/rating'
- },
- {
- type: 'Control',
- scope: '#/properties/cost'
- },
- {
- type: 'Control',
- scope: '#/properties/dueDate'
- }
- ]
-};
-
-export const ContributePage: React.FC = () => {
- const initialData = {
- image: placeholder,
- name: 'Study 12',
- description: 'This study focuses on the verb conjugation',
- instructions: 'Analyze common verb conjugations and recognize a pattern',
- complete: false
- };
- const navigate = useNavigate();
-
- const handleSubmit = () => {
- //submit logic
- //redirect to next page
- navigate('/tagging', { state: { schema: schema, uischema: uischema } });
- };
-
- return (
-
- Study: {initialData.name}
-
-
- {initialData.complete ? 'Study Training' : 'Study Tagging'}
- Study: {initialData.name}
- Description: {initialData.description}
- Instructions: {initialData.instructions}
- {initialData.complete ? (
-
- Training Complete! Reach out to your study administrator to get access to tagging
-
- ) : (
-
- )}
-
-
-
- );
-};
diff --git a/packages/client/src/pages/contribute/ContributeLanding.tsx b/packages/client/src/pages/contribute/ContributeLanding.tsx
new file mode 100644
index 00000000..eb032f38
--- /dev/null
+++ b/packages/client/src/pages/contribute/ContributeLanding.tsx
@@ -0,0 +1,34 @@
+import { Typography, Box, Stack, Button } from '@mui/material';
+import { useNavigate } from 'react-router-dom';
+import { useStudy } from '../../context/Study.context';
+
+export const ContributeLanding: React.FC = () => {
+ const navigate = useNavigate();
+ const { study } = useStudy();
+
+ const enterTagging = () => {
+ navigate('/contribute/tagging');
+ };
+
+ // TODO: Add in check for training completion
+ return (
+ <>
+ {study && (
+
+ Study: {study.name}
+
+
+ {false ? 'Study Training' : 'Study Tagging'}
+ Study: {study.name}
+ Description: {study.description}
+ Instructions: {study.instructions}
+
+
+
+
+ )}
+ >
+ );
+};
diff --git a/packages/client/src/pages/contribute/TaggingInterface.tsx b/packages/client/src/pages/contribute/TaggingInterface.tsx
new file mode 100644
index 00000000..81d0766f
--- /dev/null
+++ b/packages/client/src/pages/contribute/TaggingInterface.tsx
@@ -0,0 +1,93 @@
+import { Box } from '@mui/material';
+import { EntryView } from '../../components/EntryView.component';
+import { TagForm } from '../../components/contribute/TagForm.component';
+import { useStudy } from '../../context/Study.context';
+import { Dispatch, SetStateAction, useEffect, useState } from 'react';
+import { AssignTagMutation, useAssignTagMutation } from '../../graphql/tag/tag';
+import { useCompleteTagMutation } from '../../graphql/tag/tag';
+import { NoTagNotification } from '../../components/contribute/NoTagNotification.component';
+import { Study } from '../../graphql/graphql';
+
+export const TaggingInterface: React.FC = () => {
+ const { study } = useStudy();
+ const [tag, setTag] = useState(null);
+ const [assignTag, assignTagResult] = useAssignTagMutation();
+ const [tagData, setTagData] = useState({});
+ const [completeTag, completeTagResult] = useCompleteTagMutation();
+
+ // Changes to study will trigger a new tag assignment
+ useEffect(() => {
+ // No study, then no tag
+ if (!study) {
+ setTag(null);
+ return;
+ }
+
+ // Assign a tag
+ assignTag({ variables: { study: study._id } });
+ }, [study]);
+
+ // Update to the assigned tag
+ useEffect(() => {
+ if (!assignTagResult.data) {
+ setTag(null);
+ return;
+ }
+
+ setTag(assignTagResult.data.assignTag);
+ }, [assignTagResult.data]);
+
+ // Changes made to the tag data
+ useEffect(() => {
+ if (tagData && tag) {
+ // Submit the tag data
+ completeTag({ variables: { tag: tag._id, data: tagData } });
+ }
+ }, [tagData]);
+
+ // Tag submission result
+ // TODO: Handle errors
+ useEffect(() => {
+ if (completeTagResult.data && study) {
+ // Assign a new tag
+ assignTag({ variables: { study: study._id } });
+ }
+ }, [completeTagResult.data]);
+
+ // TODO: View for when there is no study vs when there is no tag
+ return (
+ <>
+ {study && (
+ <>
+ {tag ? (
+
+ ) : (
+
+ )}
+ >
+ )}
+ >
+ );
+};
+
+interface MainViewProps {
+ tag: NonNullable;
+ setTagData: Dispatch>;
+ study: Study;
+}
+
+const MainView: React.FC = (props) => {
+ return (
+
+
+
+
+ );
+};
diff --git a/packages/client/src/pages/contribute/placeholder.png b/packages/client/src/pages/contribute/placeholder.png
deleted file mode 100644
index 5a6e78be..00000000
Binary files a/packages/client/src/pages/contribute/placeholder.png and /dev/null differ
diff --git a/packages/client/src/pages/studies/NewStudy.tsx b/packages/client/src/pages/studies/NewStudy.tsx
index ba89b714..3b27075c 100644
--- a/packages/client/src/pages/studies/NewStudy.tsx
+++ b/packages/client/src/pages/studies/NewStudy.tsx
@@ -9,7 +9,7 @@ import { CreateStudyDocument } from '../../graphql/study/study';
import { useProject } from '../../context/Project.context';
import { useStudy } from '../../context/Study.context';
import { useApolloClient } from '@apollo/client';
-import { CreateTagsDocument } from '../../graphql/tag';
+import { CreateTagsDocument } from '../../graphql/tag/tag';
export const NewStudy: React.FC = () => {
const [activeStep, setActiveStep] = useState(0);