diff --git a/packages/web/components/templates/ProfileLayout.tsx b/packages/web/components/templates/ProfileLayout.tsx
index e2d3d6b1a..975ffafb1 100644
--- a/packages/web/components/templates/ProfileLayout.tsx
+++ b/packages/web/components/templates/ProfileLayout.tsx
@@ -3,6 +3,7 @@ import { OmnivoreNameLogo } from '../elements/images/OmnivoreNameLogo'
import { theme } from '../tokens/stitches.config'
type ProfileLayoutProps = {
+ logoDestination?: string
children: React.ReactNode
}
@@ -46,7 +47,7 @@ export function ProfileLayout(props: ProfileLayoutProps): JSX.Element {
>
diff --git a/packages/web/lib/networking/mutations/bulkActionMutation.ts b/packages/web/lib/networking/mutations/bulkActionMutation.ts
new file mode 100644
index 000000000..935e5a8e6
--- /dev/null
+++ b/packages/web/lib/networking/mutations/bulkActionMutation.ts
@@ -0,0 +1,43 @@
+import { gql } from 'graphql-request'
+import { gqlFetcher } from '../networkHelpers'
+
+export enum BulkAction {
+ ARCHIVE = 'ARCHIVE',
+ DELETE = 'DELETE',
+}
+
+type BulkActionResponseData = {
+ success: boolean
+}
+
+type BulkActionResponse = {
+ errorCodes?: string[]
+ bulkAction?: BulkActionResponseData
+}
+
+export async function bulkActionMutation(action: BulkAction): Promise {
+ const mutation = gql`
+ mutation {
+ bulkAction (action: ${action}) {
+ ... on BulkActionSuccess {
+ success
+ }
+ ... on BulkActionError {
+ errorCodes
+ }
+ }
+ }
+ `
+
+ console.log('bulkActionbulkActionMutation', mutation)
+
+ try {
+ const response = await gqlFetcher(mutation, { action })
+ console.log('response', response)
+ const data = response as BulkActionResponse | undefined
+ return data?.bulkAction?.success ?? false
+ } catch (error) {
+ console.error(error)
+ return false
+ }
+}
diff --git a/packages/web/pages/tools/bulk.tsx b/packages/web/pages/tools/bulk.tsx
new file mode 100644
index 000000000..9b4031937
--- /dev/null
+++ b/packages/web/pages/tools/bulk.tsx
@@ -0,0 +1,172 @@
+import { useCallback, useState } from 'react'
+import { applyStoredTheme } from '../../lib/themeUpdater'
+
+import { Box, VStack } from '../../components/elements/LayoutPrimitives'
+
+import { StyledText } from '../../components/elements/StyledText'
+import { ProfileLayout } from '../../components/templates/ProfileLayout'
+import {
+ BulkAction,
+ bulkActionMutation,
+} from '../../lib/networking/mutations/bulkActionMutation'
+import { Button } from '../../components/elements/Button'
+import { theme } from '../../components/tokens/stitches.config'
+import { ConfirmationModal } from '../../components/patterns/ConfirmationModal'
+import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
+import { useRouter } from 'next/router'
+
+type RunningState = 'none' | 'confirming' | 'running' | 'completed'
+
+export default function BulkPerformer(): JSX.Element {
+ const router = useRouter()
+
+ applyStoredTheme(false)
+
+ const [action, setAction] = useState()
+ const [errorMessage, setErrorMessage] = useState()
+ const [runningState, setRunningState] = useState('none')
+
+ const performAction = useCallback(() => {
+ ;(async () => {
+ console.log('performing action: ', action)
+ if (!action) {
+ showErrorToast('Unable to run action, no action set.')
+ return
+ }
+ try {
+ const success = await bulkActionMutation(action)
+ if (!success) {
+ throw 'Success not returned'
+ }
+ showSuccessToast('Bulk action is being performed.')
+ setRunningState('completed')
+ } catch (err) {
+ showErrorToast('Error performing bulk action.')
+ }
+ })()
+ }, [action])
+
+ return (
+
+
+
+ Perform a Bulk Action
+
+
+ Use this tool to perform a bulk operation on all the items in your
+ library.
+ More info
+
+
+ Note: This operation can not be undone.
+
+
+ {runningState == 'completed' ? (
+
+ Your bulk action has started. Please note that it can take some
+ time for these actions to complete. During this time, we recommend
+ not modifying your library as new items could be updated by the
+ action.
+
+ ) : (
+ <>
+
+
+
+
+
+ >
+ )}
+
+ {runningState == 'confirming' && (
+ setRunningState('none')}
+ />
+ )}
+ {runningState == 'completed' && (
+
+
+
+ )}
+
+ {errorMessage && (
+ {errorMessage}
+ )}
+
+
+
+ )
+}
diff --git a/packages/web/pages/tools/import/matter-archive.tsx b/packages/web/pages/tools/import/matter-archive.tsx
index c9f4a872f..0262fc5de 100644
--- a/packages/web/pages/tools/import/matter-archive.tsx
+++ b/packages/web/pages/tools/import/matter-archive.tsx
@@ -67,7 +67,7 @@ export default function ImportUploader(): JSX.Element {
}
return (
-
+