Skip to content
This repository has been archived by the owner on Jan 3, 2025. It is now read-only.

Commit

Permalink
Add action button to copy emails to clipboard (#382)
Browse files Browse the repository at this point in the history
* Add action button to copy emails to clipboard

* Add button to copy individual email

* Factor out TableRow from reg admin table

* Replace button with link icon, add confirmation

* Remove unused Button import
  • Loading branch information
kr-matthews authored Dec 8, 2023
1 parent 8ed57b8 commit cc28113
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ export default function RegistrationActions({
const anyCancellable = cancelled.length < selectedCount
const anyWaitlistable = waiting.length < selectedCount

const selectedEmails = [...pending, ...accepted, ...cancelled, ...waiting]
// TODO: get real email from backend
.map((user) => user + '@worldcubeassociation.org')
.join(',')

const { mutate: updateRegistrationMutation } = useMutation({
mutationFn: updateRegistration,
onError: (data) => {
Expand Down Expand Up @@ -77,6 +82,11 @@ export default function RegistrationActions({
})
}

const copyEmails = (emails) => {
navigator.clipboard.writeText(emails)
setMessage('Copied to clipboard. Remember to use bcc!', 'positive')
}

return (
anySelected && (
<Button.Group className={styles.actions}>
Expand All @@ -93,22 +103,19 @@ export default function RegistrationActions({

<Button>
<a
href={`mailto:?bcc=${[
...pending,
...accepted,
...cancelled,
...waiting,
]
.map((user) => user + '@worldcubeassociation.org')
.join(',')}`}
href={`mailto:?bcc=${selectedEmails}`}
id="email-selected"
target="_blank"
className="btn btn-info selected-registrations-actions"
>
<UiIcon name="envelope" /> Email
<UiIcon name="envelope" /> Send Email
</a>
</Button>

<Button onClick={() => copyEmails(selectedEmails)}>
<UiIcon name="copy" /> Copy Emails
</Button>

{isOrganizerOrDelegate && (
<>
{anyApprovable && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query'
import { FlagIcon, UiIcon } from '@thewca/wca-components'
import React, { useContext, useMemo, useReducer } from 'react'
import { Link } from 'react-router-dom'
import { Checkbox, Header, Popup, Table } from 'semantic-ui-react'
import { Checkbox, Header, Icon, Popup, Table } from 'semantic-ui-react'
import { CompetitionContext } from '../../../api/helper/context/competition_context'
import { getAllRegistrations } from '../../../api/registration/get/get_registrations'
import { BASE_ROUTE } from '../../../routes'
Expand Down Expand Up @@ -194,7 +194,6 @@ function RegistrationAdministrationTable({
registrations,
select,
unselect,
competition_id,
selected,
}) {
const { competitionInfo } = useContext(CompetitionContext)
Expand Down Expand Up @@ -239,100 +238,20 @@ function RegistrationAdministrationTable({
<Table.Body>
{registrations.length > 0 ? (
registrations.map((registration) => {
const id = registration.user.id
return (
<Table.Row
key={registration.user.id}
active={selected.includes(registration.user.id)}
>
<Table.Cell>
<Checkbox
onChange={(_, data) => {
if (data.checked) {
select([registration.user.id])
} else {
unselect([registration.user.id])
}
}}
checked={selected.includes(registration.user.id)}
/>
</Table.Cell>
<Table.Cell>
<Link
to={`${BASE_ROUTE}/${competition_id}/${registration.user.id}/edit`}
>
Edit
</Link>
</Table.Cell>
<Table.Cell>
{registration.user.wca_id && (
<a
href={`https://www.worldcubeassociation.org/persons/${registration.user.wca_id}`}
>
{registration.user.wca_id}
</a>
)}
</Table.Cell>
<Table.Cell>{registration.user.name}</Table.Cell>
<Table.Cell>
<FlagIcon iso2={registration.user.country.iso2} />
{registration.user.country.name}
</Table.Cell>
<Table.Cell>
<Popup
content={new Date(
registration.competing.registered_on
).toTimeString()}
trigger={
<span>
{new Date(
registration.competing.registered_on
).toLocaleDateString()}
</span>
}
/>
</Table.Cell>

{competitionInfo['using_stripe_payments?'] && (
<>
<Table.Cell>
{registration.payment.payment_status ?? 'not paid'}
</Table.Cell>
<Table.Cell>
{registration.payment.updated_at && (
<Popup
content={new Date(
registration.payment.updated_at
).toTimeString()}
trigger={
<span>
{new Date(
registration.payment.updated_at
).toLocaleDateString()}
</span>
}
/>
)}
</Table.Cell>
</>
)}
<Table.Cell>
{registration.competing.event_ids.length}
</Table.Cell>
<Table.Cell>{registration.guests}</Table.Cell>
<Table.Cell title={registration.competing.comment}>
{truncateComment(registration.competing.comment)}
</Table.Cell>
<Table.Cell title={registration.competing.admin_comment}>
{truncateComment(registration.competing.admin_comment)}
</Table.Cell>
<Table.Cell>
<a
href={`mailto:${registration.user_id}@worldcubeassociation.org`}
>
<UiIcon name="mail" />
</a>
</Table.Cell>
</Table.Row>
<TableRow
key={id}
registration={registration}
isSelected={selected.includes(id)}
onCheckboxChange={(_, data) => {
if (data.checked) {
select([id])
} else {
unselect([id])
}
}}
/>
)
})
) : (
Expand All @@ -344,3 +263,76 @@ function RegistrationAdministrationTable({
</Table>
)
}

function TableRow({ registration, isSelected, onCheckboxChange }) {
const { id, wca_id, name, country } = registration.user
const { registered_on, event_ids, comment, admin_comment } =
registration.competing
const { payment_status, updated_at } = registration.payment
// TODO: get actual email
const email = `${registration.user_id}@worldcubeassociation.org`

const { competitionInfo, competition_id } = useContext(CompetitionContext)

const copyEmail = () => {
navigator.clipboard.writeText(email)
setMessage('Copied email address to clipboard.', 'positive')
}

return (
<Table.Row key={id} active={isSelected}>
<Table.Cell>
<Checkbox onChange={onCheckboxChange} checked={isSelected} />
</Table.Cell>
<Table.Cell>
<Link to={`${BASE_ROUTE}/${competition_id}/${id}/edit`}>Edit</Link>
</Table.Cell>
<Table.Cell>
{wca_id && (
<a href={`https://www.worldcubeassociation.org/persons/${wca_id}`}>
{wca_id}
</a>
)}
</Table.Cell>
<Table.Cell>{name}</Table.Cell>
<Table.Cell>
<FlagIcon iso2={country.iso2} />
{country.name}
</Table.Cell>
<Table.Cell>
<Popup
content={new Date(registered_on).toTimeString()}
trigger={<span>{new Date(registered_on).toLocaleDateString()}</span>}
/>
</Table.Cell>

{competitionInfo['using_stripe_payments?'] && (
<>
<Table.Cell>{payment_status ?? 'not paid'}</Table.Cell>
<Table.Cell>
{updated_at && (
<Popup
content={new Date(updated_at).toTimeString()}
trigger={
<span>{new Date(updated_at).toLocaleDateString()}</span>
}
/>
)}
</Table.Cell>
</>
)}
<Table.Cell>{event_ids.length}</Table.Cell>
<Table.Cell>{registration.guests}</Table.Cell>
<Table.Cell title={comment}>{truncateComment(comment)}</Table.Cell>
<Table.Cell title={admin_comment}>
{truncateComment(admin_comment)}
</Table.Cell>
<Table.Cell>
<a href={`mailto:${email}`}>
<UiIcon name="mail" />
</a>{' '}
<Icon link onClick={copyEmail} name="copy" title="Copy Email Address" />
</Table.Cell>
</Table.Row>
)
}

0 comments on commit cc28113

Please sign in to comment.