fp/services/next/app/profile/page.tsx

242 lines
10 KiB
TypeScript

'use client';
import 'react-loading-skeleton/dist/skeleton.css';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSpinner, faCheckCircle, faXmarkCircle } from "@fortawesome/free-solid-svg-icons";
import { useMutation, useQueryClient } from "@tanstack/react-query";
// import { updateIsUsernamePublic } from "./hooks/updateProfile";
import { useQuery } from '@tanstack/react-query';
import ProtectedRoute from "../components/protected-route";
import VibrateTest from "../components/vibrate-test";
import { useSession } from "next-auth/react"
import { LoginButton, LogoutButton } from "../components/auth-buttons";
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import Link from 'next/link';
import { useEffect } from 'react';
import { useState } from 'react';
import { fetchPatreonCurrentlyEntitledTiers } from './hooks/patreonCurrentlyEntitledTiers';
import { Spinner } from '../components/spinner';
import { signIn, signOut } from "next-auth/react";
export default function Page() {
const queryClient = useQueryClient()
// const sessionContext = Session.useSessionContext()
// if (sessionContext.loading) {
// return <Spinner></Spinner>
// }
const { data, status, update } = useSession()
async function renewJwt() {
await signOut({ redirect: false });
await signIn("keycloak", { redirect: false });
}
// const { data: patreonTier, isPending, refetch } = useQuery({
// queryKey: ['user/tier'],
// queryFn: () => fetchPatreonCurrentlyEntitledTiers(),
// })
// const keycloakGroupQuery = useQuery({
// queryKey: ['user/group'],
// queryFn: () => fetchKeycloakGroup()
// })
// const attributesMutation = useMutation({
// mutationFn: updateIsUsernamePublic,
// mutationKey: ['user/attributes'],
// onSuccess: () => queryClient.invalidateQueries({ queryKey: ['user/attributes'] })
// })
// const metadataQuery = useQuery({
// queryKey: ['user/metadata'],
// queryFn: () => fetchMetadata()
// })
// const [ isUsernamePublic, setIsUsernamePublic ] = useState<boolean>()
// const [ username, setUsername ] = useState('')
// useEffect(() => {
// if (metadataQuery.data?.metadata) {
// setUsername(formatPatronUsername(metadataQuery.data.metadata.first_name, metadataQuery.data.metadata.last_name))
// setIsUsernamePublic(metadataQuery.data.metadata.isUsernamePublic)
// }
// }, [metadataQuery.data])
const isUsernamePublic = (data?.profile?.username_visibility === 'public')
const [isGo, setIsGo] = useState<boolean>()
// useEffect(() => {
// const fetchData = async () => {
// const res = await fetch(`${process.env.KEYCLOAK_URL}/protocol/openid-connect/token`, {
// method: 'POST',
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
// body: new URLSearchParams({
// client_id: process.env.KEYCLOAK_CLIENT_ID,
// client_secret: process.env.KEYCLOAK_CLIENT_SECRET,
// grant_type: 'refresh_token',
// refresh_token: session.refreshToken,
// }),
// });
// const data = await res.json();
// if (res.ok) {
// // Update session with new token
// session.accessToken = data.access_token;
// session.refreshToken = data.refresh_token;
// res.status(200).json(session);
// } else {
// res.status(400).json({ error: 'Token refresh failed' });
// }
// }
// fetchData();
// }, [isGo]);
return (
<div className="content">
{/* {(metadataQuery.isPending) && <Spinner></Spinner>} */}
<div className="section">
<p className="title is-3">Debug section</p>
{/* {(isPending) ? <span><Spinner></Spinner> Syncronizing Patron entitlements...</span> : <span>Patreon entitlements synced.</span>} */}
{/* <p>metadataQuery as follows</p> */}
{/* <pre><code>{JSON.stringify(metadataQuery.data, null, 2)}</code></pre> */}
<p>session as follows</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
{(status === 'unauthenticated') && <LoginButton></LoginButton>}
{/* <button className='button' onClick={() => refetch()}>Refetch</button> */}
<button className='button' onClick={() => update()}>Update</button>
<button className='button' onClick={() => renewJwt()}>RenewJWT</button>
</div>
{(data?.user) &&
<div className="section">
<h1 className="title is-1 mb-3">Profile</h1>
<LogoutButton></LogoutButton>
<div className="card mt-5">
<div className="card-content">
<div className="media-content">
{/* <p className="title is-4">{username}</p> */}
<p className="subtitle is-6">{data?.user?.name}</p>
</div>
</div>
</div>
{/* <h2>Patronage</h2>
<div className='box'>
<p>You belong to the {patreonTier} tier. Thank you!</p>
</div> */}
<h2 className="title is-2">Patron Perks</h2>
<div className="box">
<h3 className="title is-3">Test Perk (not real)</h3>
<ProtectedRoute featureName="Test Perk" requiredUserRole="default-roles-futureporn">
<p>Hey look at you, you're granted access to this perk!</p>
</ProtectedRoute>
</div>
<div className="box">
<h3 className="title is-3">Website Shoutout</h3>
<ProtectedRoute featureName="Website shoutout" requiredUserRole="patron">
{isUsernamePublic && <span className="mr-2">{data.user.name} will be displayed on the <Link href="/patrons">/patrons page</Link></span>}
{!isUsernamePublic && <span className="mr-2">Your username will be hidden from the <Link href="/patrons">/patrons page</Link> due to your privacy setting.</span>}
{/* Users can update privacy pref at https://keycloak.fp.sbtp.xyz/realms/futureporn/account/ */}
</ProtectedRoute>
</div>
<div className='box'>
<h3 className="title is-3">Premium Content Delivery Network (CDN1)</h3>
<ProtectedRoute featureName="CDN1" requiredUserRole="patron">
<p><FontAwesomeIcon icon={faCheckCircle} className="mr-2"></FontAwesomeIcon> You have access to Futureporn's Premium CDN for reliable video playback</p>
</ProtectedRoute>
</div>
<div className='box'>
<h3 className="title is-3">Economy Content Delivery Network (CDN2)</h3>
<ProtectedRoute featureName="CDN2" requiredUserRole="default-roles-futureporn">
<p><FontAwesomeIcon icon={faCheckCircle} className="mr-2"></FontAwesomeIcon> You have access to Futureporn's Economy CDN for basic video playback</p>
</ProtectedRoute>
</div>
<div className="box">
<h3 className="title is-3">Vibrate (test)</h3>
<VibrateTest></VibrateTest>
</div>
</div>
}
</div>
)
// if (metadataQuery.isPending) return <Spinner></Spinner>;
// return <pre><code>{JSON.stringify(metadataQuery.data, null, 2)}</code></pre>
// return <p>@todo</p>
// if (!isPending) return <Spinner></Spinner>;
// if (!data) return <p>there is no data</p>;
// if (!data?.metadata) return <p>there is no data.metadata</p>;
// const { first_name, last_name } = data.metadata
// const username = formatPatronUsername(first_name, last_name)
// const { metadata } = data || {}
// const { isUsernamePublic } = metadata
// return (
// <>
// <div className="content">
// <div className="section">
// <h1 className="title is-1 mb-3">Profile</h1>
// <div className="field is-horizontal">
// <div className="field-label">Username</div>
// <p className="field is-expanded">
// {isPending &&
// <SkeletonTheme baseColor="#000" highlightColor="#000">
// <Skeleton count={1} enableAnimation={false} width="10em" />
// </SkeletonTheme>
// }
// {!isPending && <p><i>{username}</i></p>}
// </p>
// </div>
// <div className="field is-horizontal">
// <div className="field-label">User ID</div>
// <div className="field is-expanded">
// <p><i>{sessionContext.userId}</i></p>
// </div>
// </div>
// <h2 className="title is-2">Patron Perks</h2>
// <h3 className="title is-3">Website Shoutout</h3>
// <PatronRoute featureName="Website shoutout" requiredUserRole="patron">
// <div className="box">
// <span className="mr-2">Display {(!!username) ? username : <SkeletonTheme baseColor="#000" highlightColor="#000"><Skeleton count={1} enableAnimation={false} width="10em" /></SkeletonTheme>} publicly?</span>
// <input className="mr-2" type="checkbox" checked={isUsernamePublic} onChange={(evt) => attributesMutation.mutate({ isUsernamePublic: evt.target.checked })}/>
// {(attributesMutation.status === 'success') && <FontAwesomeIcon color="lime" icon={faCheckCircle}></FontAwesomeIcon>}
// {(attributesMutation.status === 'pending') && <FontAwesomeIcon icon={faSpinner}></FontAwesomeIcon>}
// {(attributesMutation.status === 'error') && <FontAwesomeIcon color="red" icon={faXmarkCircle}></FontAwesomeIcon>}
// </div>
// </PatronRoute>
// <h3 className="title is-3">Content Delivery Network (CDN)</h3>
// <PatronRoute featureName="CDN" requiredUserRole="patron">
// <p><FontAwesomeIcon icon={faCheckCircle} className="mr-2"></FontAwesomeIcon> You have access to Futureporn's CDN for reliable video playback</p>
// </PatronRoute>
// <h3 className="title is-3">Vibrate (test)</h3>
// <VibrateTest></VibrateTest>
// </div>
// </div>
// </>
// )
}