diff --git a/packages/web/components/templates/settings/SettingsTable.tsx b/packages/web/components/templates/settings/SettingsTable.tsx
new file mode 100644
index 000000000..444d91086
--- /dev/null
+++ b/packages/web/components/templates/settings/SettingsTable.tsx
@@ -0,0 +1,309 @@
+import { Plus, Trash } from 'phosphor-react'
+import { Toaster } from 'react-hot-toast'
+import { Button } from '../../elements/Button'
+import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
+import { MoreOptionsIcon } from '../../elements/images/MoreOptionsIcon'
+import { InfoLink } from '../../elements/InfoLink'
+import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
+import { StyledText } from '../../elements/StyledText'
+import { styled, theme } from '../../tokens/stitches.config'
+import { PrimaryLayout } from '../PrimaryLayout'
+
+type SettingsTableProps = {
+ pageId: string
+ pageHeadline: string
+ pageInfoLink: string
+ headerTitle: string
+
+ createTitle?: string
+ createAction?: () => void
+
+ children: React.ReactNode
+}
+
+type CreateButtonProps = {
+ title: string
+ action: () => void
+}
+
+type SettingsTableRowProps = {
+ key: string
+ title: string
+ isFirst: boolean
+ isLast: boolean
+
+ sublineElement: JSX.Element
+ titleElement?: JSX.Element
+ extraElement?: JSX.Element
+
+ deleteTitle: string
+ onDelete: () => void
+}
+
+type MoreOptionsProps = {
+ title: string
+ onDelete: () => void
+}
+
+const MoreOptions = (props: MoreOptionsProps) => (
+
+
+
+ }
+ >
+ {
+ return true
+ }}
+ >
+
+
+
+
+
+
+)
+
+export const SettingsTableRow = (props: SettingsTableRowProps): JSX.Element => {
+ return (
+
+
+
+
+
+ {props.title}
+
+ {props.sublineElement}
+
+ {props.titleElement}
+ {/*
+
+ */}
+
+
+
+
+ {props.extraElement}
+
+
+
+
+
+
+
+ )
+}
+
+const CreateButton = (props: CreateButtonProps): JSX.Element => {
+ return (
+
+ )
+}
+
+export const SettingsTable = (props: SettingsTableProps): JSX.Element => {
+ return (
+
+
+
+
+
+
+
+
+ {props.pageHeadline}{' '}
+
+
+
+ {props.createAction && props.createTitle && (
+
+ )}
+
+
+
+ {props.headerTitle}
+
+
+
+ {props.children}
+
+
+
+
+ )
+}
diff --git a/packages/web/pages/settings/emails.tsx b/packages/web/pages/settings/emails.tsx
index 29fa58c85..c7d16b1f3 100644
--- a/packages/web/pages/settings/emails.tsx
+++ b/packages/web/pages/settings/emails.tsx
@@ -1,29 +1,26 @@
-import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
import { Button } from '../../components/elements/Button'
import { useGetNewsletterEmailsQuery } from '../../lib/networking/queries/useGetNewsletterEmailsQuery'
import { createNewsletterEmailMutation } from '../../lib/networking/mutations/createNewsletterEmailMutation'
import { deleteNewsletterEmailMutation } from '../../lib/networking/mutations/deleteNewsletterEmailMutation'
import { MoreOptionsIcon } from '../../components/elements/images/MoreOptionsIcon'
-import { Plus, Trash, Copy } from 'phosphor-react'
+import { Trash, Copy } from 'phosphor-react'
import {
Dropdown,
DropdownOption,
} from '../../components/elements/DropdownElements'
import { theme, styled } from '../../components/tokens/stitches.config'
-import {
- Box,
- SpanBox,
- HStack,
- VStack,
-} from '../../components/elements/LayoutPrimitives'
+import { Box, HStack } from '../../components/elements/LayoutPrimitives'
import { useCopyLink } from '../../lib/hooks/useCopyLink'
-import { Toaster } from 'react-hot-toast'
import { useCallback, useMemo } from 'react'
import { StyledText } from '../../components/elements/StyledText'
import { applyStoredTheme } from '../../lib/themeUpdater'
import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
-import { InfoLink } from '../../components/elements/InfoLink'
import { formattedShortDate } from '../../lib/dateFormatting'
+import Link from 'next/link'
+import {
+ SettingsTable,
+ SettingsTableRow,
+} from '../../components/templates/settings/SettingsTable'
enum TextType {
EmailAddress,
@@ -35,42 +32,6 @@ type CopyTextButtonProps = {
type: TextType
}
-const HeaderWrapper = styled(Box, {
- width: '100%',
- '@md': {
- display: 'block',
- },
-})
-
-const TableCard = styled(Box, {
- backgroundColor: '$grayBg',
- display: 'flex',
- alignItems: 'center',
- padding: '10px 12px',
- border: '0.5px solid $grayBgActive',
- width: '100%',
-
- '&:hover': {
- border: '0.5px solid #FFD234',
- },
- '@md': {
- paddingLeft: '0',
- },
-})
-
-const TableHeading = styled(Box, {
- backgroundColor: '$grayBgActive',
- border: '1px solid rgba(0, 0, 0, 0.06)',
- display: 'none',
- alignItems: 'center',
- padding: '10px 0 10px 20px',
- borderRadius: '5px 5px 0px 0px',
- width: '100%',
- '@md': {
- display: 'flex',
- },
-})
-
const CopyTextBtnWrapper = styled(Box, {
background: '$grayBgActive',
borderRadius: '6px',
@@ -87,52 +48,6 @@ const CopyTextBtnWrapper = styled(Box, {
marginLeft: '10px',
})
-const MoreOptions = ({ onDelete }: { onDelete: () => void }) => (
-
-
-
- }
- >
- {
- return true
- }}
- >
-
-
-
-
-
-
-)
-
function CopyTextButton(props: CopyTextButtonProps): JSX.Element {
const { copyLink, isLinkCopied } = useCopyLink(
props.text,
@@ -198,224 +113,89 @@ export default function EmailsPage(): JSX.Element {
}, [emailAddresses])
return (
-
-
-
-
-
-
-
- Email Addresses
-
-
-
-
-
-
- Address
-
-
-
- {sortedEmailAddresses &&
- sortedEmailAddresses.map((email, i) => {
- const isLastChild = i === sortedEmailAddresses.length - 1
-
- return (
-
-
-
+
+ }
+ extraElement={
+
+ <>
+
-
-
- {email.address}
-
-
- {`created ${formattedShortDate(email.createdAt)}, ${
- email.subscriptionCount
- } subscriptions`}
-
-
-
-
-
-
- deleteEmail(email.id)} />
-
-
- {email.confirmationCode && (
-
- <>
-
- {`Gmail: ${email.confirmationCode}`}
-
-
-
-
-
-
- >
-
- )}
-
-
-
- deleteEmail(email.id)} />
+ {`Gmail: ${email.confirmationCode}`}
+
+
+
+
+
-
-
- )
- })}
-
-
-
-
+ >
+
+ }
+ />
+ )
+ })}
+
)
}
diff --git a/packages/web/pages/settings/subscriptions.tsx b/packages/web/pages/settings/subscriptions.tsx
index 704edb121..473df7bb6 100644
--- a/packages/web/pages/settings/subscriptions.tsx
+++ b/packages/web/pages/settings/subscriptions.tsx
@@ -1,18 +1,20 @@
import { useState } from 'react'
-import { PrimaryLayout } from '../../components/templates/PrimaryLayout'
-import { Toaster } from 'react-hot-toast'
import { applyStoredTheme } from '../../lib/themeUpdater'
import { ConfirmationModal } from '../../components/patterns/ConfirmationModal'
import { useGetSubscriptionsQuery } from '../../lib/networking/queries/useGetSubscriptionsQuery'
import { unsubscribeMutation } from '../../lib/networking/mutations/unsubscribeMutation'
import { showErrorToast, showSuccessToast } from '../../lib/toastHelpers'
-import { Table } from '../../components/elements/Table'
+import {
+ SettingsTable,
+ SettingsTableRow,
+} from '../../components/templates/settings/SettingsTable'
+import { StyledText } from '../../components/elements/StyledText'
+import Link from 'next/link'
export default function SubscriptionsPage(): JSX.Element {
const { subscriptions, revalidate } = useGetSubscriptionsQuery()
- const [confirmUnsubscribeName, setConfirmUnsubscribeName] = useState<
- string | null
- >(null)
+ const [confirmUnsubscribeName, setConfirmUnsubscribeName] =
+ useState(null)
applyStoredTheme(false)
@@ -26,42 +28,93 @@ export default function SubscriptionsPage(): JSX.Element {
revalidate()
}
- const headers = ['Name', 'Email', 'Updated Time']
- const rows = new Map()
- subscriptions.forEach((subscription) =>
- rows.set(subscription.name, [
- subscription.name,
- subscription.newsletterEmail,
- subscription.updatedAt.toString(),
- ])
- )
+ function formattedShortDate(date: Date): string {
+ return new Intl.DateTimeFormat('en-US', {
+ dateStyle: 'short',
+ }).format(date)
+ }
return (
-
-
+
+ <>
+ {subscriptions &&
+ subscriptions.map((subscription, i) => {
+ return (
+ onUnsubscribe(subscription.name)}
+ deleteTitle="Unsubscribe"
+ sublineElement={
+
+ {`Last received ${formattedShortDate(
+ subscription.updatedAt
+ )}, `}
+
+ {subscription.newsletterEmail}
+
+
+ }
+ />
+ )
+ })}
- {confirmUnsubscribeName ? (
- {
- await onUnsubscribe(confirmUnsubscribeName)
- setConfirmUnsubscribeName(null)
- }}
- onOpenChange={() => setConfirmUnsubscribeName(null)}
- />
- ) : null}
-
-
+ {confirmUnsubscribeName ? (
+ {
+ await onUnsubscribe(confirmUnsubscribeName)
+ setConfirmUnsubscribeName(null)
+ }}
+ onOpenChange={() => setConfirmUnsubscribeName(null)}
+ />
+ ) : null}
+ >
+
)
+
+ // return (
+ //
+ //
+
+ // {confirmUnsubscribeName ? (
+ // {
+ // await onUnsubscribe(confirmUnsubscribeName)
+ // setConfirmUnsubscribeName(null)
+ // }}
+ // onOpenChange={() => setConfirmUnsubscribeName(null)}
+ // />
+ // ) : null}
+ //
+ //
+ // )
}