// Dependencies
import { uiRoles as roles } from '@freesewing/config'
import { userAvatarUrl } from '@freesewing/utils'
// Hooks
import React, { useState, useContext, useEffect } from 'react'
import { useAccount } from '@freesewing/react/hooks/useAccount'
import { useBackend } from '@freesewing/react/hooks/useBackend'
// Context
import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
import { ModalContext } from '@freesewing/react/context/Modal'
// Components
import { Spinner } from '@freesewing/react/components/Spinner'
//import { Hits } from 'shared/components/admin.mjs'
import { Link as WebLink } from '@freesewing/react/components/Link'
import { SearchIcon } from '@freesewing/react/components/Icon'
import { KeyVal } from '@freesewing/react/components/KeyVal'
import { Markdown } from '@freesewing/react/components/Markdown'
import { ModalWrapper } from '@freesewing/react/components/Modal'
import { AccountStatus, UserRole } from '@freesewing/react/components/Account'
export const SubscriberAdministration = ({ page }) => {
const [subscribers, setSubscribers] = useState()
const [q, setQ] = useState()
const [hits, setHits] = useState([])
const backend = useBackend()
const loadSubscribers = async () => {
const [status, body] = await backend.adminLoadSubscribers()
if (status === 200 && body.subscribers) setSubscribers(body.subscribers)
}
const search = async () => {
if (!subscribers) await loadSubscribers()
const found = []
for (const lang in subscribers) {
found.push(
...subscribers[lang]
.filter((sub) => sub.email.toLowerCase().includes(q.toLowerCase()))
.map((sub) => ({ ...sub, lang }))
)
}
setHits(found)
}
const unsubscribe = async (ehash) => {
await backend.newsletterUnsubscribe(ehash)
await loadSubscribers()
await search()
}
return (
<>
{subscribers ? (
<>
Search subscribers
setQ(evt.target.value)}
className="tw:daisy-input tw:w-full tw:daisy-input-bordered tw:flex tw:flex-row"
type="text"
placeholder="Username, ID, or E-mail address"
/>
Email |
Language |
Unsubscribe |
{hits.map((hit, i) => (
{hit.email}
|
{hit.lang.toUpperCase()} |
|
))}
>
) : (
)}
>
)
}
export const UserAdministration = ({ Link = false }) => {
const backend = useBackend()
const [q, setQ] = useState('')
const [results, setResults] = useState()
const [loading, setLoading] = useState(false)
const search = async () => {
/*
* Search backend
*/
setLoading(true)
const [status, body] = await backend.adminSearchUsers(q)
if (status === 200 && body.result === 'success' && body.users) {
setResults(body.users)
}
setLoading(false)
}
return (
<>
Search users
setQ(evt.target.value)}
className="tw:daisy-input tw:w-full tw:daisy-input-bordered tw:flex tw:flex-row"
type="text"
placeholder="Username, ID, or E-mail address"
/>
{loading ?
:
}
>
)
}
export const Hits = ({ results, Link = false }) => {
if (!Link) Link = WebLink
return (
<>
{results && results.username && results.username.length > 0 && (
<>
Results based on username
{results.username.map((user) => (
))}
>
)}
{results && results.email && results.email.length > 0 && (
<>
Results based on E-mail address
{results.email.map((user) => (
))}
>
)}
>
)
}
export const User = ({ user, Link }) => {
const { setModal } = useContext(ModalContext)
return (
{user.username}
)
}
export const ImpersonateButton = ({ userId }) => {
const backend = useBackend()
const { setLoadingStatus } = useContext(LoadingStatusContext)
const { impersonate } = useAccount()
if (!userId) return null
const impersonateUser = async () => {
setLoadingStatus([true, 'Contacting backend'])
const [status, body] = await backend.adminImpersonateUser(userId)
if (status === 200 && body.result === 'success') {
impersonate(body)
setLoadingStatus([true, 'Now impersonating', true, true])
} else setLoadingStatus([true, 'An error occured', true, false])
}
return (
)
}
export const Row = ({ title, val }) => (
{title} |
{val} |
)
export const ManageUser = ({ userId }) => {
// Hooks
const backend = useBackend()
const { setLoadingStatus } = useContext(LoadingStatusContext)
const { account } = useAccount()
const { role } = account
// State
const [user, setUser] = useState({})
const [patterns, setPatterns] = useState({})
const [sets, setSets] = useState({})
// Effect
useEffect(() => {
const loadUser = async () => {
const result = await backend.adminLoadUser(userId)
if (result.success) {
setUser(result.data.user)
setPatterns(result.data.patterns)
setSets(result.data.sets)
}
}
loadUser()
}, [userId])
const updateUser = async (data) => {
setLoadingStatus([true, 'status:contactingBackend'])
const result = await backend.adminUpdateUser({ id: userId, data })
if (result.success) {
setLoadingStatus([true, 'status:settingsSaved', true, true])
setUser(result.data.user)
} else setLoadingStatus([true, 'status:backendError', true, false])
}
return user.id ? (
: null}
/>
{role === 'admin' ? (
{roles.map((role) => (
))}
) : null}
{user.mfaEnabled && (
)}
{Object.keys(freeSewingConfig.statuses).map((status) => (
))}
{user.id ? : null}
{patterns ? : null}
{sets ? : null}
) : (
)
}