130 lines
4.8 KiB
TypeScript
130 lines
4.8 KiB
TypeScript
import React, { FunctionComponent, useEffect } from 'react';
|
|
import { useUserProfile } from '../../gql/queries/profile';
|
|
import { useConference } from '../../hooks/useConference';
|
|
import { Page } from '../Page';
|
|
import { Gravatar } from './Gravatar';
|
|
|
|
export interface ConferencePageProps {
|
|
|
|
}
|
|
|
|
const StatusHandRaised = 'hand-raised';
|
|
const StatusThumbsUp = 'thumbs-up';
|
|
const StatusThumbsDown = 'thumbs-down';
|
|
const StatusNoVote = 'no-vote';
|
|
|
|
export const ConferencePage:FunctionComponent<ConferencePageProps> = () => {
|
|
const { user } = useUserProfile();
|
|
const { id, data, peers, setNickname, setEmail, ping, setStatus } = useConference();
|
|
|
|
const currentStatus = data.statuses[id];
|
|
|
|
useEffect(() => {
|
|
if (peers.length === 0) return;
|
|
if (!id || (!user.name && !user.email)) return;
|
|
setNickname(user.name || user.email.split('@')[0]);
|
|
setEmail(user.email);
|
|
}, [user.name, user.email, peers.length]);
|
|
|
|
useEffect(() => {
|
|
ping();
|
|
const intervalId = setInterval(() => ping(), 30000);
|
|
return () => clearInterval(intervalId);
|
|
}, []);
|
|
|
|
const onStatusChange = (status: string) => {
|
|
setStatus(currentStatus === status ? '' : status);
|
|
};
|
|
|
|
return (
|
|
<Page title="Conference">
|
|
<div className="container is-fluid">
|
|
<section className="mt-5">
|
|
<h3 className="is-size-3">Mes actions</h3>
|
|
<div className="buttons has-addons">
|
|
<button
|
|
className={`button is-medium ${currentStatus === StatusHandRaised ? 'is-info is-selected' : ''}`}
|
|
onClick={onStatusChange.bind(null, StatusHandRaised)}>
|
|
<span className="icon">
|
|
<i className="fa fa-hand-paper"></i>
|
|
</span>
|
|
<span>Lever la main</span>
|
|
</button>
|
|
<button
|
|
className={`button is-medium ${currentStatus === StatusThumbsUp ? 'is-success is-selected' : ''}`}
|
|
onClick={onStatusChange.bind(null, StatusThumbsUp)}>
|
|
<span className="icon">
|
|
<i className="fa fa-thumbs-up"></i>
|
|
</span>
|
|
<span>Voter pour</span>
|
|
</button>
|
|
<button
|
|
className={`button is-medium ${currentStatus === StatusNoVote ? 'is-warning is-selected' : ''}`}
|
|
onClick={onStatusChange.bind(null, StatusNoVote)}>
|
|
<span className="icon">
|
|
<i className="fa fa-mitten"></i>
|
|
</span>
|
|
<span>Ne se prononce pas</span>
|
|
</button>
|
|
<button
|
|
className={`button is-medium ${currentStatus === StatusThumbsDown ? 'is-danger is-selected' : ''}`}
|
|
onClick={onStatusChange.bind(null, StatusThumbsDown)}>
|
|
<span className="icon">
|
|
<i className="fa fa-thumbs-down"></i>
|
|
</span>
|
|
<span>Voter contre</span>
|
|
</button>
|
|
</div>
|
|
<h3 className="is-size-3">Assemblée</h3>
|
|
<div className="columns mt-1">
|
|
<UserCard className="column is-narrow"
|
|
nickname={data.nicknames[id]}
|
|
status={currentStatus}
|
|
email={user.email} />
|
|
{
|
|
peers.map(p => {
|
|
const nickname = data.nicknames[p] || '???';
|
|
const email = data.emails[p] || '';
|
|
return (
|
|
<UserCard key={`peer-${p}`} className="column is-narrow"
|
|
nickname={nickname}
|
|
status={data.statuses[p]}
|
|
email={email} />
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</Page>
|
|
);
|
|
}
|
|
|
|
export interface UserCardProps {
|
|
nickname: string
|
|
email: string
|
|
className?: string
|
|
status: string
|
|
};
|
|
|
|
export const UserCard:FunctionComponent<UserCardProps> = ({ nickname, email, className, status }) => {
|
|
return (
|
|
<div className={className}>
|
|
<div className="box">
|
|
<div className="has-text-centered">
|
|
<div className="mb-1">
|
|
{ !status ? <span className="icon"><i className="far fa-2x fa-meh-blank"></i></span> : null }
|
|
{ status === StatusHandRaised ? <span className="icon has-text-info"><i className="fa fa-2x fa-hand-paper"></i></span> : null }
|
|
{ status === StatusThumbsUp ? <span className="icon has-text-success"><i className="fa fa-2x fa-thumbs-up"></i></span> : null }
|
|
{ status === StatusNoVote ? <span className="icon has-text-warning"><i className="fa fa-2x fa-mitten"></i></span> : null }
|
|
{ status === StatusThumbsDown ? <span className="icon has-text-danger"><i className="fa fa-2x fa-thumbs-down"></i></span> : null }
|
|
</div>
|
|
<figure className="image is-128x128 is-inline-block">
|
|
<Gravatar className="is-rounded" email={email} />
|
|
</figure>
|
|
<h4 className="is-size-4">{nickname}</h4>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}; |