semantic-ui-react#Divider TypeScript Examples

The following examples show how to use semantic-ui-react#Divider. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LobbyUserPanel.tsx    From FLECT_Amazon_Chime_Meeting with Apache License 2.0 6 votes vote down vote up
render() {
        const props = this.props as any

        return (
            <div  style={{padding:"10px"}}>
                <PreviewPanel  {...props}/>
                <Divider hidden />

                <ConfigPanel {...props} />
                <Divider hidden />

                <ActionsPanel {...props} />

            </div>
        )
    }
Example #2
Source File: bigbook.tsx    From website with MIT License 6 votes vote down vote up
render() {
		const { crew, markdownRemark } = this.props;

		return (
			<React.Fragment>
				<Divider horizontal>
					<Header>
						<Link to={`/crew${markdownRemark.fields.slug}`}>
							{crew.name} <Rating defaultRating={crew.max_rarity} maxRating={5} icon='star' size='large' disabled />
						</Link>
					</Header>
				</Divider>
				<Grid columns={2}>
					<Grid.Row>
						<Grid.Column width={4}>
							{crew.series && <Image src={`/media/series/${crew.series}.png`} size='small' />}
							<Link to={`/crew${markdownRemark.fields.slug}`}>
								<Image src={`${process.env.GATSBY_ASSETS_URL}${crew.imageUrlFullBody}`} size='small' />
							</Link>
						</Grid.Column>
						<Grid.Column width={12}>
							<CommonCrewData crew={crew} markdownRemark={markdownRemark} />

							<div dangerouslySetInnerHTML={{ __html: markdownRemark.html }} />
						</Grid.Column>
					</Grid.Row>
				</Grid>
			</React.Fragment>
		);
	}
Example #3
Source File: SubReport.tsx    From peterportal-client with MIT License 6 votes vote down vote up
SubReport: FC<SubReportProps> = (props) => {
    return (
        <div className='subreport'>
            <div className='subreport-content'>
                <h5>Reported at {props.timestamp}</h5>
                <p>{props.reason}</p>
            </div>
            {!props.isLast && <Divider />}
        </div>
    );
}
Example #4
Source File: bb.tsx    From website with MIT License 6 votes vote down vote up
render() {
		const { crew, markdownRemark } = this.props;

		return (
			<React.Fragment>
				<p>
					<b style={{ color: markdownRemark.frontmatter.in_portal ? 'unset' : 'red' }}>{crew.name}</b> - {getCoolStats(crew, true)}{' | '}
					{crew.collections.length > 0 ? (
						<span>
							{crew.collections
								.map(col => (
									<Link key={col} to={`/collections/#${encodeURIComponent(col)}`}>
										{col}
									</Link>
								))
								.reduce((prev, curr) => [prev, ', ', curr])}
								{' | '}
						</span>
					) : (
						<span />
					)}
					{markdownRemark.frontmatter.events} events <Link to={`/crew${markdownRemark.fields.slug}`}>more...</Link>
				</p>

				<div dangerouslySetInnerHTML={{ __html: markdownRemark.html }} />

				<Divider />
			</React.Fragment>
		);
	}
Example #5
Source File: announcements.tsx    From website with MIT License 6 votes vote down vote up
Announcements = ({ data: { allMarkdownRemark } }) => {
	const announcements = allMarkdownRemark.edges;

	return (
		<Layout title='DataCore Announcements'>
			<Header as='h2'>DataCore Announcements</Header>
			{announcements.map(({ node }) => {
				const datePosted = new Date(node.frontmatter.date);
				return (
					<div key={node.id}>
						<Header>{node.frontmatter.title}</Header>
						<p>{datePosted.toLocaleDateString()}</p>
						<div dangerouslySetInnerHTML={{ __html: node.html }} />
						<Divider />
					</div>
				);
			})}
		</Layout>
	);
}
Example #6
Source File: Characters.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Characters: VFC<RouteComponentProps> = ({ match }) => (
  <>
    <header>
      <h1>『SLAM DUNK』登場人物</h1>
    </header>
    <Switch>
      <Route exact path={`${match.path}`}>
        <AllCharacters />
      </Route>
      <Route path={`${match.path}/:schoolCode`}>
        <SchoolCharacters />
      </Route>
      <Redirect to="/" />
    </Switch>
    <Divider hidden />
    <HomeButton />
  </>
)
Example #7
Source File: Characters.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Characters: VFC = () => (
  <>
    <header>
      <h1>『SLAM DUNK』登場人物</h1>
    </header>
    <Outlet />
    <Divider hidden />
    <HomeButton />
  </>
)
Example #8
Source File: Members.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Members: VFC<Props> = ({
  orgCode = 'UnknownCompany',
  users = [],
  isLoading = false,
}) => {
  const title = `${capitalize(orgCode)} の開発メンバー`;

  return (
    <>
      <Helmet>
        <title>{title}</title>
      </Helmet>
      <header className="app-header">
        <h1>{title}</h1>
      </header>
      {isLoading ? <Spinner /> : <MemberList users={users} />}
      <Divider hidden />
      <HomeButton />
    </>
  );
}
Example #9
Source File: Members.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Members: VFC<Props> = ({
  orgCode = 'UnknownCompany',
  users = [],
  isLoading = false,
}) => {
  const title = `${capitalize(orgCode)} の開発メンバー`;

  return (
    <>
      <Helmet>
        <title>{title}</title>
      </Helmet>
      <header className="app-header">
        <h1>{title}</h1>
      </header>
      {isLoading ? <Spinner /> : <MemberList users={users} />}
      <Divider hidden />
      <HomeButton />
    </>
  );
}
Example #10
Source File: Members.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Members: VFC<Props> = ({
  orgCode = 'UnknownCompany',
  users = [],
  isLoading = false,
}) => {
  const title = `${capitalize(orgCode)} の開発メンバー`;

  return (
    <>
      <Helmet>
        <title>{title}</title>
      </Helmet>
      <header className="app-header">
        <h1>{title}</h1>
      </header>
      {isLoading ? <Spinner /> : <MemberList users={users} />}
      <Divider hidden />
      <HomeButton />
    </>
  );
}
Example #11
Source File: Members.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 6 votes vote down vote up
Members: VFC<{ orgCode: string }> = ({ orgCode = 'UnknownCompany' }) => {
  const title = `${capitalize(orgCode)} の開発メンバー`;

  return (
    <>
      <Helmet>
        <title>{title}</title>
      </Helmet>
      <header className="app-header">
        <h1>{title}</h1>
      </header>
      <ErrorBoundary
        statusMessages={{
          404: `‘${orgCode}’ というコードの組織は見つかりません`,
        }}
      >
        <Suspense fallback={<Spinner size="big" />}>
          <MemberList orgCode={orgCode} />
        </Suspense>
      </ErrorBoundary>
      <Divider hidden />
      <HomeButton />
    </>
  );
}
Example #12
Source File: LobbyUserPanel.tsx    From FLECT_Amazon_Chime_Meeting with Apache License 2.0 5 votes vote down vote up
render(){
        const props = this.props as any
        return(
            <div>
                {this.state.open ?
                    (
                        <div>

                        <Card width="100%">
                            <Button basic size="tiny"  compact onClick={()=>{this.handleClick()}} >
                                {/* <Header as='h5'> */}
                                    <Icon name="angle up" />Configurations
                                {/* </Header> */}
                            </Button>                            
                            <Card.Content>
                                <p>
                                    <MicControl {...props} />
                                </p>
                                <p>
                                    <VideoControl {...props} />
                                </p>
                                <p>
                                    <SpeakerControl {...props} />
                                </p>
                                <Divider />
                                <p>
                                    <VideoResolutionControl {...props} />
                                </p>
                                <p>
                                    <SettingControl {...props}/>
                                </p>
                            </Card.Content>
                        </Card>
                        </div>
                    )
                    :
                    (
                        <div>
                        <Card  >
                            <Button basic size="tiny"  compact onClick={()=>{this.handleClick()}} >
                                {/* <Header as='h5'> */}
                                    <Icon name="angle down" />Configurations
                                {/* </Header> */}
                            </Button>
                        </Card>
                        </div>

                    )

                }
            </div>
        )
    }
Example #13
Source File: bridgecrew.tsx    From website with MIT License 5 votes vote down vote up
render() {
		if (this.state.allcrew.length === 0) {
			return (
				<Layout title='Bridge crew assembly'>
					<div className='ui medium centered text active inline loader'>Loading data...</div>
				</Layout>
			);
		}

		let peopleToShow = [...this.state.peopleList];

		return (
			<Layout title='Bridge crew assembly'>
				<Header as='h4'>Bridge crew assembly</Header>
				<p>Assemble your bridge crew.</p>
				<Form>
					<Form.Group>
						<Dropdown
							clearable
							fluid
							multiple
							search
							selection
							closeOnChange
							options={peopleToShow}
							placeholder='Select or search for crew'
							label='Bridge crew'
							value={this.state.currentSelectedItems}
							onChange={(e, { value }) => this._selectionChanged(value)}
						/>
					</Form.Group>
				</Form>

				<Divider horizontal hidden />

				<div style={{ height: '500px', overflow: 'hidden', textAlign: 'center', padding: '25px', backgroundColor: '#203147', border: '2px solid lightblue' }}>
					<Header as='h3'>Bridge Crew</Header>
					{this.state.entries.map((entry, idx) => (
							<img src={`${process.env.GATSBY_ASSETS_URL}${entry.crew.imageUrlFullBody}`} style={{ height: '725px', margin: '0 -6.5%' }} />
					))}
				</div>
			</Layout>
		);
	}
Example #14
Source File: behold.tsx    From website with MIT License 5 votes vote down vote up
render() {
		if (this.state.allcrew.length === 0) {
			return (
				<Layout title='Behold helper / crew comparison'>
					<div className='ui medium centered text active inline loader'>Loading data...</div>
				</Layout>
			);
		}

		let peopleToShow = [...this.state.peopleList];
		if (this.state.minRarity) {
			peopleToShow = peopleToShow.filter((crew) => crew.max_rarity >= this.state.minRarity);
		}

		return (
			<Layout title='Behold helper / crew comparison'>
				<Header as='h2'>Behold helper / crew comparison</Header>
				<Form>
					<Form.Group>
						<Dropdown
							clearable
							fluid
							multiple
							search
							selection
							closeOnChange
							options={peopleToShow}
							placeholder='Search for crew to compare'
							label='Behold crew'
							value={this.state.currentSelectedItems}
							onChange={(e, { value }) => this._selectionChanged(value)}
						/>
						<Form.Field
							control={Dropdown}
							placeholder={this.state.minRarity ? `Minimum rarity: ${this.state.minRarity}` : `Minimum rarity`}
							selection
							options={rarityOptions}
							value={this.state.minRarity}
							onChange={(e, { value }) => this.setState({ minRarity: value })}
						/>
					</Form.Group>
				</Form>
				{this.state.currentSelectedItems?.length > 0 && (
					<Button compact icon='add user' color='green' content='Preview all in your roster' onClick={() => { this._addProspects(); }} />
				)}

				<Divider horizontal hidden />

				<Grid columns={3} stackable centered padded divided>
					{this.state.entries.map((entry, idx) => (
						<Grid.Column key={idx}>
							<Header as='h5'>
								<Link to={`/crew/${entry.crew.symbol}/`}>
									{entry.crew.name}{' '}
									<Rating defaultRating={entry.crew.max_rarity} maxRating={entry.crew.max_rarity} icon='star' size='small' disabled />
								</Link>
							</Header>
							<CommonCrewData compact={true} crewDemands={entry.crewDemands} crew={entry.crew} markdownRemark={entry.markdownRemark} roster={this.state.roster}/>
							{entry.markdown && (
								<React.Fragment>
									<div dangerouslySetInnerHTML={{ __html: entry.markdown }} />
									<div style={{ marginTop: '1em' }}>
										<a href={`https://www.bigbook.app/crew/${entry.crew.symbol}`}>View {entry.crew.name} on Big Book</a>
									</div>
								</React.Fragment>
							)}
						</Grid.Column>
					))}
				</Grid>
			</Layout>
		);
	}
Example #15
Source File: Members2.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 5 votes vote down vote up
Members: VFC<Props> = ({ orgCodeList, prefetch = () => undefined }) => {
  const [orgCode, setOrgCode] = useState('');
  const [input, setInput] = useState('');
  const [isPending, startTransition] = useTransition();
  const { reset } = useQueryErrorResetBoundary();

  const menuItems = orgCodeList.map((code) => ({
    key: code,
    name: capitalize(code),
    onClick: () => {
      setInput('');

      if (orgCode) {
        startTransition(() => setOrgCode(code));
      } else {
        setOrgCode(code);
      }
    },
    onMouseOver: () => prefetch(code),
    active: code === orgCode,
  }));

  const handleSubmit = (event: FormEvent<HTMLFormElement>): void => {
    event.preventDefault();
    setOrgCode(input.toLowerCase().trim());
  };

  return (
    <>
      <header className="app-header">
        <h1>組織メンバーリスト</h1>
      </header>
      <form className="search-form" onSubmit={handleSubmit}>
        <Input
          placeholder="組織コードを入力..."
          type="text"
          value={input}
          onChange={(_, data) => setInput(data.value)}
        />
        <Button type="submit" disabled={isPending} primary>
          検索
        </Button>
      </form>
      <Menu items={menuItems} text />
      <Divider />
      <div className={isPending ? 'loading' : ''}>
        <ErrorBoundary
          fallbackRender={({ resetErrorBoundary }) => (
            <>
              <Message warning>
                {orgCode} というコードの組織は見つかりません
              </Message>
              <Button color="olive" onClick={() => resetErrorBoundary()}>
                エラーをリセット
              </Button>
            </>
          )}
          onReset={() => reset()}
        >
          <SuspenseList revealOrder="forwards">
            <Suspense fallback={<Spinner size="small" />}>
              <OrgInfo orgCode={orgCode} />
            </Suspense>
            <Suspense fallback={<Spinner size="large" />}>
              <MemberList orgCode={orgCode} />
            </Suspense>
          </SuspenseList>
        </ErrorBoundary>
      </div>
    </>
  );
}
Example #16
Source File: Members.tsx    From Riakuto-StartingReact-ja3.1 with Apache License 2.0 5 votes vote down vote up
Members: VFC<Props> = ({ orgCodeList, prefetch = () => undefined }) => {
  const [orgCode, setOrgCode] = useState('');
  const [input, setInput] = useState('');
  const [isPending, startTransition] = useTransition();
  const ebKey = useRef(0);

  const menuItems = orgCodeList.map((code) => ({
    key: code,
    name: capitalize(code),
    onClick: () => {
      setInput('');

      if (orgCode) {
        startTransition(() => setOrgCode(code));
      } else {
        setOrgCode(code);
      }
    },
    onMouseOver: () => prefetch(code),
    active: code === orgCode,
  }));

  const handleSubmit = (event: FormEvent<HTMLFormElement>): void => {
    event.preventDefault();
    setOrgCode(input.toLowerCase().trim());
  };

  return (
    <>
      <header className="app-header">
        <h1>組織メンバーリスト</h1>
      </header>
      <form className="search-form" onSubmit={handleSubmit}>
        <Input
          placeholder="組織コードを入力..."
          type="text"
          value={input}
          onChange={(_, data) => setInput(data.value)}
        />
        <Button type="submit" disabled={isPending} primary>
          検索
        </Button>
      </form>
      <Menu items={menuItems} text />
      <Divider />
      <div className={isPending ? 'loading' : ''}>
        <ErrorBoundary
          statusMessages={{
            404: `‘${orgCode}’ というコードの組織は見つかりません`,
          }}
          onError={() => {
            ebKey.current += 1;
          }}
          key={ebKey.current}
        >
          <SuspenseList revealOrder="forwards">
            <Suspense fallback={<Spinner size="small" />}>
              <OrgInfo orgCode={orgCode} />
            </Suspense>
            <Suspense fallback={<Spinner size="large" />}>
              <MemberList orgCode={orgCode} />
            </Suspense>
          </SuspenseList>
        </ErrorBoundary>
      </div>
    </>
  );
}
Example #17
Source File: index.tsx    From peterportal-client with MIT License 5 votes vote down vote up
ProfessorPage: FC<RouteComponentProps<{ id: string }>> = (props) => {
    const dispatch = useAppDispatch();
    const professorGQLData = useAppSelector(state => state.popup.professor);
    const [error, setError] = useState('');

    useEffect(() => {
        // make a gql query if directly landed on this page
        if (professorGQLData == null || professorGQLData.ucinetid != props.match.params.id) {
            searchAPIResult('professor', props.match.params.id)
                .then(professor => {
                    if (professor) {
                        dispatch(setProfessor(professor as ProfessorGQLData))
                    }
                    else {
                        setError(`Professor ${props.match.params.id} does not exist!`);
                    }
                })
        }
    }, [])

    // if professor does not exists
    if (error) {
        return <Error message={error} />
    }
    // loading results
    else if (!professorGQLData) {
        return <LoadingPage />;
    }
    else {
        return (
            <Twemoji options={{ className: 'twemoji' }}>
                <div className='professor-page'>
                    <div>
                        <SideInfo searchType='professor' name={professorGQLData.name}
                            title={professorGQLData.title} school={professorGQLData.schools[0]} description={professorGQLData.department}
                            tags={[professorGQLData.ucinetid, professorGQLData.shortened_name]} professor={professorGQLData} />
                    </div>
                    <article className='professor-page-body'>
                        <div className='professor-page-section'>
                            <div>
                                <h2>?️ Schedule of Classes</h2>
                            </div>
                            <Divider />
                            <Schedule professorID={professorGQLData.shortened_name} />
                        </div>

                        <div className='professor-page-section'>
                            <div>
                                <h2>? Grade Distribution</h2>
                            </div>
                            <Divider />
                            <GradeDist professor={professorGQLData} />
                        </div>

                        <div className='professor-page-section'>
                            <div>
                                <h2>? Reviews</h2>
                            </div>
                            <Divider />
                            <Review professor={professorGQLData} />
                        </div>
                    </article>
                </div>
            </Twemoji>
        )
    }
}
Example #18
Source File: index.tsx    From peterportal-client with MIT License 5 votes vote down vote up
CoursePage: FC<RouteComponentProps<{ id: string }>> = (props) => {
    const dispatch = useAppDispatch();
    const courseGQLData = useAppSelector(state => state.popup.course);
    const [error, setError] = useState('');

    useEffect(() => {
        // make a gql query if directly landed on this page
        if (courseGQLData == null || courseGQLData.id != props.match.params.id) {
            searchAPIResult('course', props.match.params.id)
                .then(course => {
                    console.log("COURSE", course)
                    if (course) {
                        dispatch(setCourse(course as CourseGQLData))
                    }
                    else {
                        setError(`Course ${props.match.params.id} does not exist!`);
                    }
                })
        }
    }, [])

    // if course does not exists
    if (error) {
        return <Error message={error} />
    }
    // loading results
    else if (!courseGQLData) {
        return <LoadingPage />;
    }
    else {
        return (
            <Twemoji options={{ className: 'twemoji' }}>
                <div className='course-page'>
                    <div>
                        <SideInfo searchType='course' name={courseGQLData.department + ' ' + courseGQLData.number}
                            title={courseGQLData.title} school={courseGQLData.school} description={courseGQLData.description}
                            tags={getCourseTags(courseGQLData)} course={courseGQLData} />
                    </div>
                    <div className='course-page-body'>
                        <div className='course-page-section'>
                            <div>
                                <h2>? Prerequisite Tree</h2>
                            </div>
                            <Divider />
                            <PrereqTree {...courseGQLData} />
                        </div>

                        <div className='course-page-section'>
                            <div>
                                <h2>?️ Schedule of Classes</h2>
                            </div>
                            <Divider />
                            <Schedule courseID={courseGQLData.department + ' ' + courseGQLData.number} />
                        </div>

                        <div className='course-page-section'>
                            <div>
                                <h2>? Grade Distribution</h2>
                            </div>
                            <Divider />
                            <GradeDist course={courseGQLData} />
                        </div>

                        <div className='course-page-section'>
                            <div>
                                <h2>? Reviews</h2>
                            </div>
                            <Divider />
                            <Review course={courseGQLData} />
                        </div>
                    </div>
                </div>
            </Twemoji>
        )
    }
}
Example #19
Source File: Verify.tsx    From peterportal-client with MIT License 5 votes vote down vote up
Verify: FC = () => {
    const [reviews, setReviews] = useState<ReviewData[]>([]);
    const [loaded, setLoaded] = useState<boolean>(false);

    interface AdminResponse {
        admin: boolean
    }

    const getUnverifiedReviews = async () => {
        const response: AxiosResponse<ReviewData[]> = await axios.get('/reviews?verified=false');
        setReviews(response.data);
        setLoaded(true);
    }

    useEffect(() => {
        getUnverifiedReviews();
    }, []);

    const verifyReview = async (reviewID: string) => {
        await axios.patch('/reviews/verify', { id: reviewID });
        getUnverifiedReviews();
    }

    const deleteReview = async (reviewID: string) => {
        await axios.delete('/reviews', { data: { id: reviewID } });
        getUnverifiedReviews();
    }

    if (!loaded) {
        return <p>Loading...</p>;
    } else if (reviews.length === 0) {
        return <p>No reviews to display at the moment.</p>;
    } else {
        return <div className='verify-container'>
            <h1>Unverified Reviews</h1>
            <p>Verifying a review will display the review on top of unverified reviews.</p>
            <p>Deleting a review will remove it permanently.</p>
            {
                reviews.map((review, i) => <div key={`verify-${i}`} className='verify'>
                    <Divider />
                    <SubReview review={review}></SubReview>
                    <div className='verify-footer'>
                        <Button variant='danger' className='mr-3' onClick={() => deleteReview(review._id!)}>Delete</Button>
                        <Button variant='success' onClick={() => verifyReview(review._id!)}>Verify</Button>
                    </div>
                </div>)
            }
        </div>
    }
}
Example #20
Source File: SettingsTab.tsx    From watchparty with MIT License 5 votes vote down vote up
SettingRow = ({
  icon,
  name,
  description,
  checked,
  disabled,
  onChange,
  content,
  subOnly,
  helpIcon,
}: {
  icon: string;
  name: string;
  description?: React.ReactNode;
  checked?: boolean;
  disabled: boolean;
  updateTS?: number;
  onChange?: (e: React.FormEvent, data: CheckboxProps) => void;
  content?: React.ReactNode;
  subOnly?: boolean;
  helpIcon?: React.ReactNode;
}) => {
  return (
    <React.Fragment>
      <Divider inverted horizontal />
      <div>
        <div style={{ display: 'flex' }}>
          <Icon size="large" name={icon as any} />
          <div>
            {name} {helpIcon}
            {subOnly ? (
              <Label size="mini" color="orange">
                Subscriber only
              </Label>
            ) : null}
          </div>
          {!content && (
            <Radio
              style={{ marginLeft: 'auto' }}
              toggle
              checked={checked}
              disabled={disabled}
              onChange={onChange}
            />
          )}
        </div>
        <div className="smallText" style={{ marginBottom: '8px' }}>
          {description}
        </div>
        {content}
      </div>
    </React.Fragment>
  );
}
Example #21
Source File: commoncrewdata.tsx    From website with MIT License 4 votes vote down vote up
renderOtherRanks(crew, roster = false) {
		let v = [];
		let g = [];
		let b = [];

		const skillName = short => CONFIG.SKILLS[CONFIG.SKILLS_SHORT.find(c => c.short === short).name];
		const rankHandler = rank => roster
			? roster.filter(c => c.ranks[rank] && crew.ranks[rank] > c.ranks[rank]).length + 1
			: crew.ranks[rank];
		const tripletHandler = rank => roster
			? roster.filter(c => c.ranks[rank] &&
													 c.ranks[rank].name == crew.ranks[rank].name &&
													 crew.ranks[rank].rank > c.ranks[rank].rank).length + 1
			: crew.ranks[rank].rank;

		// Need to filter by skills first before sorting by voyage triplet
		const tripletFilter = crew.ranks.voyTriplet
								? crew.ranks.voyTriplet.name.split('/')
									.map(s => 'skill:'+s.trim())
									.reduce((prev, curr) => prev+' '+curr)
								: '';

		for (let rank in crew.ranks) {
			if (rank.startsWith('V_')) {
				v.push(
					<Statistic key={rank}>
						<Statistic.Label>{rank.substr(2).replace('_', ' / ')}</Statistic.Label>
						<Statistic.Value>{rankLinker(roster, rankHandler(rank), crew.symbol, 'ranks.'+rank)}</Statistic.Value>
					</Statistic>
				);
			} else if (rank.startsWith('G_')) {
				g.push(
					<Statistic key={rank}>
						<Statistic.Label>{rank.substr(2).replace('_', ' / ')}</Statistic.Label>
						<Statistic.Value>{rankLinker(roster, rankHandler(rank), crew.symbol, 'ranks.'+rank)}</Statistic.Value>
					</Statistic>
				);
			} else if (rank.startsWith('B_') && crew.ranks[rank]) {
				b.push(
					<Statistic key={rank}>
						<Statistic.Label>{skillName(rank.substr(2))}</Statistic.Label>
						<Statistic.Value>{rankLinker(roster, rankHandler(rank), crew.symbol, CONFIG.SKILLS_SHORT.find(c => c.short === rank.substr(2)).name, 'descending')}</Statistic.Value>
					</Statistic>
				);
			}
		}

		return (
			<React.Fragment>
				<Segment>
					<Header as="h5">Base ranks</Header>
					<Statistic.Group widths="three" size={'mini'} style={{ paddingBottom: '0.5em' }}>
						{b}
					</Statistic.Group>
				</Segment>
				<Segment>
					<Header as="h5">Voyage skill ranks</Header>
					{crew.ranks.voyTriplet && (
						<React.Fragment>
							<Statistic.Group widths="one" size={'mini'}>
								<Statistic>
									<Statistic.Label>{crew.ranks.voyTriplet.name}</Statistic.Label>
									<Statistic.Value>{rankLinker(roster, tripletHandler('voyTriplet'), crew.symbol, 'ranks.voyRank', 'ascending', tripletFilter)}</Statistic.Value>
								</Statistic>
							</Statistic.Group>
							<Divider />
						</React.Fragment>
				)}
					<Statistic.Group widths="three" size={'mini'} style={{ paddingBottom: '0.5em' }}>
						{v}
					</Statistic.Group>
				</Segment>
				<Segment>
					<Header as="h5">Gauntlet pair ranks</Header>
					<Statistic.Group widths="three" size={'mini'} style={{ paddingBottom: '0.5em' }}>
						{g}
					</Statistic.Group>
				</Segment>
			</React.Fragment>
		);
	}
Example #22
Source File: missionslist.tsx    From website with MIT License 4 votes vote down vote up
MissionsList = (props: MissionsListProps) => {
	const { groupId, shuttlers, setShuttlers, activeShuttles } = props;

	const [editMission, setEditMission] = React.useState(undefined);
	const [state, dispatch] = React.useReducer(reducer, {
		data: shuttlers.shuttles.filter(shuttle => shuttle.groupId === groupId),
		column: null,
		direction: null
	});
	const { data, column, direction } = state;

	React.useEffect(() => {
		dispatch({ type: 'UPDATE_DATA', data: shuttlers.shuttles.filter(shuttle => shuttle.groupId === groupId), column, direction });
	}, [shuttlers]);

	const CheckDropdown = () => {
		if (data.length === 0) return (<></>);

		const checkOptions = [];

		const threeSeaters = [], fourSeaters = [];
		data.forEach(shuttle => {
			if (shuttle.seats.length <= 4)
				fourSeaters.push(shuttle.id);
			if (shuttle.seats.length === 3)
				threeSeaters.push(shuttle.id);
		});
		if (threeSeaters.length > 0)
			checkOptions.push({ key: 'three-seaters', text: `Select only 3-seaters (${threeSeaters.length})`, ids: threeSeaters });
		if (fourSeaters.length > 0)
			checkOptions.push({ key: 'four-seaters', text: `Select only 3- and 4- seaters (${fourSeaters.length})`, ids: fourSeaters });

		if (activeShuttles?.length > 0) {
			const openIds = activeShuttles.map(adventure => adventure.symbol);
			checkOptions.push({ key: `open-adventures`, text: `Select only open in-game (${openIds.length})`, ids: openIds });
		}

		const factions = [];
		data.forEach(shuttle => {
			if (shuttle.faction > 0 && !factions.includes(shuttle.faction)) factions.push(shuttle.faction);
		});
		if (factions.length > 1) {
			factions.forEach(factionId => {
				const ids = data.filter(shuttle => shuttle.faction === factionId).map(shuttle => shuttle.id);
				const faction = allFactions.find(af => af.id === factionId);
				checkOptions.push({ key: `faction-${factionId}`, text: `Select only ${faction.name} (${ids.length})`, ids });
			});
		}

		return (
			<Dropdown
				icon='check'
				floating
			>
				<Dropdown.Menu>
					<Dropdown.Item icon='check' text={`Select all (${data.length})`} onClick={() => checkMissions([])} />
					{missionsSelected > 0 && (
						<Dropdown.Item icon='x' text='Unselect all' onClick={() => checkMissions([], false)} />
					)}
					{checkOptions.length > 0 && <Dropdown.Divider />}
					{checkOptions.map(option => (
						<Dropdown.Item key={option.key} text={option.text} onClick={() => checkMissions(option.ids)} />
					))}
				</Dropdown.Menu>
			</Dropdown>
		);
	};

	const tableConfig = [
		{ title: <CheckDropdown />, align: 'center' },
		{ column: 'name', title: 'Mission' },
		{ column: 'faction', title: 'Faction', align: 'center' },
		{ column: 'seats.length', title: 'Seats', align: 'center' },
		{ column: 'skills', title: 'Skills', span: 5 },
		{ title: '' }
	];

	const MissionEditor = (props: { shuttle: Shuttle }) => {
		const [shuttle, setShuttle] = React.useState(JSON.parse(JSON.stringify(props.shuttle)));

		const factionOptions = allFactions.sort((a, b) => a.name.localeCompare(b.name)).map(faction => {
			return { key: faction.id, value: faction.id, text: (<span style={{ whiteSpace: 'nowrap' }}>{faction.name}</span>) };
		});

		const EditorSeat = (props: { seat: ShuttleSeat, seatNum: number }) => {
			const { seatNum, seat } = props;

			const skillOptions = [
				{ key: 'CMD', text: 'CMD', value: 'command_skill' },
				{ key: 'DIP', text: 'DIP', value: 'diplomacy_skill' },
				{ key: 'ENG', text: 'ENG', value: 'engineering_skill' },
				{ key: 'MED', text: 'MED', value: 'medicine_skill' },
				{ key: 'SCI', text: 'SCI', value: 'science_skill' },
				{ key: 'SEC', text: 'SEC', value: 'security_skill' }
			];

			return (
				<Grid textAlign='center' columns={3}>
					<Grid.Column>
						<Dropdown
							direction='right'
							compact
							selection
							options={skillOptions}
							value={seat.skillA}
							onChange={(e, { value }) => updateMissionSeat(seatNum, 'skillA', value)}
						/>
					</Grid.Column>
					<Grid.Column>
						<Button circular
							disabled={seat.skillB == '' ? true : false}
							onClick={() => updateMissionSeat(seatNum, 'operand', seat.operand == 'AND' ? 'OR' : 'AND')}
						>
							{seat.skillB == '' ? '' : seat.operand}
						</Button>
					</Grid.Column>
					<Grid.Column>
						<Dropdown
							compact
							selection
							clearable
							options={skillOptions}
							value={seat.skillB}
							onChange={(e, { value }) => updateMissionSeat(seatNum, 'skillB', value)}
						/>
					</Grid.Column>
				</Grid>
			);
		};

		return (
			<Modal
				open={true}
				onClose={() => applyEdits()}
			>
				<Modal.Header>Edit Mission</Modal.Header>
				<Modal.Content scrolling>
					{renderContent()}
				</Modal.Content>
				<Modal.Actions>
					<Button positive onClick={() => applyEdits()}>
						Close
					</Button>
				</Modal.Actions>
			</Modal>
		);

		function renderContent(): void {
			return (
				<React.Fragment>
					<Grid columns={2} divided stackable>
						<Grid.Column>
							<div>
								<Header as='h4'>Mission name</Header>
								<Input style={{ marginTop: '-1em' }}
									placeholder='Mission name...'
									value={shuttle.name}
									onChange={(e, { value }) => updateMissionName(value)}>
										<input />
										<Button icon onClick={() => updateMissionName('')} >
											<Icon name='delete' />
										</Button>
								</Input>
							</div>
							<div style={{ marginTop: '1em' }}>
								<Header as='h4'>Faction</Header>
								<Dropdown
									style={{ marginTop: '-1em' }}
									selection
									options={factionOptions}
									value={shuttle.faction}
									onChange={(e, { value }) => updateFaction(value)}
								/>
							</div>
						</Grid.Column>
						<Grid.Column>
							<Header as='h4'>Seats</Header>
							<p style={{ marginTop: '-1em' }}>Set each seat to the skills required. Add seats as necessary.</p>
							<Table collapsing unstackable compact='very' size='small'>
								<Table.Body>
									{shuttle.seats.map((seat, seatNum) => (
										<Table.Row key={seatNum}>
											<Table.Cell textAlign='right'>{seatNum+1}</Table.Cell>
											<Table.Cell textAlign='center'>
												<EditorSeat seatNum={seatNum} seat={seat} />
											</Table.Cell>
											<Table.Cell textAlign='right'>
												{shuttle.seats.length > 1 && <Button compact icon='trash' color='red' onClick={() => deleteMissionSeat(seatNum)} />}
											</Table.Cell>
										</Table.Row>
									))}
								</Table.Body>
							</Table>
							<Button compact icon='plus square outline' content='Add Seat' onClick={() => addMissionSeat()} />
						</Grid.Column>
					</Grid>
					<div style={{ marginTop: '1em' }}>
						<Divider />
						<p>If you no longer need this mission, you can delete it here. Note: missions will be automatically deleted after the event has concluded.</p>
						<p><Button icon='trash' color='red' content='Delete Mission' onClick={() => deleteMission(shuttle.id)} /></p>
					</div>
				</React.Fragment>
			);
		}

		function updateMissionName(newName: string): void {
			shuttle.name = newName;
			setShuttle({...shuttle});
		}

		function updateFaction(newFaction: number): void {
			shuttle.faction = newFaction;
			setShuttle({...shuttle});
		}

		function updateMissionSeat(seatNum: number, key: string, value: string): void {
			shuttle.seats[seatNum][key] = value;
			setShuttle({...shuttle});
		}

		function addMissionSeat(): void {
			shuttle.seats.push(new ShuttleSeat());
			setShuttle({...shuttle});
		}

		function deleteMissionSeat(seatNum: number): void {
			shuttle.seats.splice(seatNum, 1);
			setShuttle({...shuttle});
		}

		function applyEdits(): void {
			if (shuttle.priority === 0) shuttle.priority = missionsSelected + 1;
			const shuttleNum = shuttlers.shuttles.findIndex(s => s.id === shuttle.id);
			shuttlers.shuttles[shuttleNum] = shuttle;
			updateShuttlers();
			setEditMission(undefined);
		}
	};

	const missionsSelected = data.filter(shuttle => shuttle.priority > 0).length;

	return (
		<React.Fragment>
			<div>Click all the missions that you want to run, then click 'Recommend Crew' to see the best seats for your crew.</div>
			<Table celled striped selectable sortable singleLine>
				<Table.Header>
					<Table.Row>
						{tableConfig.map((cell, idx) => (
							<Table.HeaderCell key={idx}
								sorted={column === cell.column ? direction : null}
								onClick={() => dispatch({ type: 'CHANGE_SORT', column: cell.column, reverse: cell.reverse })}
								colSpan={cell.span ?? 1}
								textAlign={cell.align ?? 'left'}
							>
								{cell.title}
							</Table.HeaderCell>
						))}
					</Table.Row>
				</Table.Header>
				<Table.Body>
					{data.length === 0 && (
						<Table.Row>
							<Table.Cell colSpan={10} textAlign='center'>
								No missions available.
							</Table.Cell>
						</Table.Row>
					)}
					{data.map(shuttle => (
						<Table.Row key={shuttle.id} style={{ cursor: 'pointer' }}
							onClick={() => toggleMissionStatus(shuttle.id)}
							onDoubleClick={() => { toggleMissionStatus(shuttle.id); props.recommendShuttlers(); }}
						>
							<Table.Cell textAlign='center'>
								{shuttle.priority > 0 && (<Icon color='green' name='check' />)}
							</Table.Cell>
							<Table.Cell>
								<span style={{ fontSize: '1.1em' }}><b>{shuttle.name}</b></span>
							</Table.Cell>
							<Table.Cell textAlign='center'>
								<ShuttleFactionView factionId={shuttle.faction} size={1.5} />
							</Table.Cell>
							<Table.Cell textAlign='center'>{shuttle.seats.length}</Table.Cell>
							{[0, 1, 2, 3, 4].map(seatNum => (
								<Table.Cell key={seatNum} textAlign='center'>
									{shuttle.seats.length > seatNum && (
										<SeatSkillView seat={shuttle.seats[seatNum]} />
									)}
								</Table.Cell>
							))}
							<Table.Cell textAlign='right'>
								{!shuttle.readonly && (
									<Button icon='edit' content='Edit' onClick={(e) => { setEditMission(shuttle); e.stopPropagation(); }}/>
								)}
							</Table.Cell>
						</Table.Row>
					))}
				</Table.Body>
				<Table.Footer>
					<Table.Row>
						<Table.HeaderCell colSpan={10} textAlign='right'>
							{missionsSelected > 0 && (<Button compact icon='rocket' color='green' content='Recommend Crew' onClick={() => props.recommendShuttlers()} />)}
							{missionsSelected === 0 && (<Button compact icon='rocket' content='Recommend Crew' />)}
						</Table.HeaderCell>
					</Table.Row>
				</Table.Footer>
			</Table>
			{editMission && <MissionEditor shuttle={editMission} />}
			<p>If the mission you want isn't listed here, click 'Create Mission' to input the mission parameters manually. Tip: open shuttle missions in-game before uploading your player data to DataCore so that this tool can import the missions automatically.</p>
			<Button icon='plus square' content='Create Mission' onClick={() => createMission() } />
		</React.Fragment>
	);

	function reducer(state, action): any {
		switch (action.type) {
			case 'UPDATE_DATA':
				//const defaultColumn = action.data.filter(shuttle => shuttle.priority > 0).length ? 'priority' : 'name';
				const updatedData = action.data.slice();
				firstSort(updatedData, action.column ?? 'name', action.direction ?? 'ascending');
				return {
					column: action.column ?? 'name',
					data: updatedData,
					direction: action.direction ?? 'ascending'
				};
			case 'CHANGE_SORT':
				if (!action.column) {
					return {
						column: state.column,
						data: state.data,
						direction: state.direction
					};
				}
				if (state.column === action.column && action.column !== 'priority') {
					return {
						...state,
						data: state.data.slice().reverse(),
						direction: state.direction === 'ascending' ? 'descending' : 'ascending'
					};
				}
				else {
					const data = state.data.slice();
					firstSort(data, action.column, action.reverse);
					return {
						column: action.column,
						data: data,
						direction: action.reverse ? 'descending' : 'ascending'
					};
				}
			default:
				throw new Error();
		}
	}

	function firstSort(data: any[], column: string, reverse: boolean = false): any[] {
		data.sort((a, b) => {
			if (column === 'name') return a.name.localeCompare(b.name);
			let aValue = column.split('.').reduce((prev, curr) => prev.hasOwnProperty(curr) ? prev[curr] : undefined, a);
			let bValue = column.split('.').reduce((prev, curr) => prev.hasOwnProperty(curr) ? prev[curr] : undefined, b);
			// Always show selected missions at the top when sorting by priority
			if (column === 'priority') {
				if (aValue === 0) aValue = 100;
				if (bValue === 0) bValue = 100;
			}
			if (column === 'skills') {
				aValue = a.seats.length;
				bValue = b.seats.length;
			}
			// Tiebreaker goes to name ascending
			if (aValue === bValue) return a.name.localeCompare(b.name);
			if (reverse) bValue - aValue;
			return aValue - bValue;
		});
	}

	function checkMissions(shuttleIds: string[], checkState: boolean = true): void {
		let priority = 0;
		shuttlers.shuttles.forEach(shuttle => {
			if (shuttleIds.length === 0)
				shuttle.priority = checkState ? ++priority : 0;
			else
				shuttle.priority = checkState && shuttleIds.includes(shuttle.id) ? ++priority : 0;
		});
		updateShuttlers();
		if (shuttleIds.length !== 0)
			dispatch({ type: 'CHANGE_SORT', column: 'priority' });
	}

	function createMission(): void {
		const shuttle = new Shuttle(groupId);
		shuttle.seats.push(new ShuttleSeat());
		shuttlers.shuttles.push(shuttle);
		updateShuttlers();
		setEditMission(shuttle);
	}

	function deleteMission(shuttleId: string): void {
		const shuttleNum = shuttlers.shuttles.findIndex(shuttle => shuttle.id === shuttleId);
		shuttlers.shuttles.splice(shuttleNum, 1);
		updateShuttlers();
		setEditMission(undefined);
	}

	function toggleMissionStatus(shuttleId: string): void {
		const shuttle = shuttlers.shuttles.find(shuttle => shuttle.id === shuttleId);
		shuttle.priority = shuttle.priority === 0 ? missionsSelected+1 : 0;
		updateShuttlers();
	}

	function updateShuttlers(): void {
		setShuttlers({...shuttlers});
	}
}
Example #23
Source File: Home.tsx    From watchparty with MIT License 4 votes vote down vote up
Home = ({ user }: { user: firebase.User | undefined }) => {
  return (
    <div>
      <div className={styles.container}>
        <Hero
          heroText={'Watch videos in-sync with friends far away.'}
          subText={'No registration or download required.'}
          action={
            <div style={{ marginTop: '8px', width: '160px' }}>
              <NewRoomButton user={user} />
            </div>
          }
          image={'/screenshot4.png'}
        />
        <Divider horizontal>
          <Header inverted as="h4">
            <Icon name="film" />
            Multiple ways to watch
          </Header>
        </Divider>
        <div className={styles.featureSection}>
          <Feature
            icon="slideshare"
            title={`Screensharing`}
            text="Share a browser tab or an application."
          />
          <Feature
            icon="desktop"
            title={`VBrowser`}
            text="Launch a virtual browser in the cloud that all room members can view and control. No need to worry about slow upload speeds!"
          />
          <Feature
            icon="file"
            title={`File`}
            text="Upload and stream your own file."
          />
          <Feature
            icon="linkify"
            title={`URL`}
            text="Paste in a URL for everyone to watch from."
          />
          <Feature
            icon="youtube"
            title={`YouTube`}
            text="Watch videos in-sync from YouTube."
          />
        </div>
        <Hero
          heroText={'React to moments together.'}
          subText={"Find moments of shared joy even when you're apart."}
          image={'/screenshot18.png'}
          color="green"
        />
        <Divider horizontal>
          <Header inverted as="h4">
            <Icon name="cogs" />
            Features
          </Header>
        </Divider>
        <div className={styles.featureSection}>
          <Feature
            icon="sync"
            title="Synchronized"
            text="Starts, stops, and seeks are synchronized to everyone, so take those restroom and snack breaks without worrying about falling behind."
          />
          <Feature
            icon="conversation"
            title="Chat"
            text="Chat with others in your room. Memes and inside jokes encouraged."
          />
          <Feature
            icon="video"
            title="Video chat"
            text="Jump into video chat if there's something that you just can't express with text."
          />
        </div>
        <Hero
          heroText={'Theater mode.'}
          subText={
            'Bring video and chat front-and-center for minimal distractions.'
          }
          image={'/screenshot14.png'}
        />
        <Divider horizontal />
        <div
          style={{
            padding: '30px',
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
          }}
        >
          <div className={styles.heroText}>Get started!</div>
          <div className={styles.featureSection}>
            <Step.Group style={{ margin: '8px' }}>
              <Step>
                <Icon name="certificate" />
                <Step.Content>
                  <Step.Title>1.</Step.Title>
                  <Step.Description>Make a room</Step.Description>
                </Step.Content>
              </Step>

              <Step>
                <Icon name="group" />
                <Step.Content>
                  <Step.Title>2.</Step.Title>
                  <Step.Description>Share link with friends</Step.Description>
                </Step.Content>
              </Step>

              <Step>
                <Icon name="film" />
                <Step.Content>
                  <Step.Title>3.</Step.Title>
                  <Step.Description>Pick something to watch</Step.Description>
                </Step.Content>
              </Step>

              <Step>
                <Icon name="thumbs up outline" />
                <Step.Content>
                  <Step.Title>4.</Step.Title>
                  <Step.Description>Success!</Step.Description>
                </Step.Content>
              </Step>
            </Step.Group>
          </div>
          <div style={{ width: '160px' }}>
            <NewRoomButton user={user} />
          </div>
        </div>
      </div>
    </div>
  );
}
Example #24
Source File: LobbyRoomList.tsx    From FLECT_Amazon_Chime_Meeting with Apache License 2.0 4 votes vote down vote up
render() {
        const gs = this.props as GlobalState
        const props = this.props as any
        const appState = props.appState as AppState

        const joinedMeetingIds = Object.keys(appState.joinedMeetings)


        const meetings = gs.meetings.map((meeting:MeetingInfo)=>{
            let joinButton

            const currentMeetingId = meeting.meetingId

            if(joinedMeetingIds.includes(currentMeetingId)){
                joinButton = (
                    <Button basic color="red" floated='right'
                        onClick={()=>{
                                console.log("CLICK LEAVE", meeting.meetingId)
                                props._leaveMeeting(meeting.meetingId, appState.joinedMeetings[currentMeetingId].meetingSession.configuration.credentials!.attendeeId)
                            }}                    
                    >
                        leave
                        <Icon name='chevron left' />
                    </Button>
                )
            }else{
                joinButton = (
                    <Button basic color="teal" floated='right'
                        onClick={()=>{
                                console.log("CLICK JOIN", meeting.meetingId)
                                props._joinMeeting(meeting.meetingId, gs)
                            }}>                    
                        join
                        <Icon name='chevron right' />
                    </Button>

                )
            }
            return (
                <Item>
                    {/* <Item.Image size='mini' src='/' /> */}
                    <Item.Content>

                        <Item.Header>
                            <Icon name="lock open" />
                            {meeting.meetingName}
                        </Item.Header>
                        <Item.Meta>
                            <div>
                                <b>Owner: </b> 
                                {meeting.metaData.UserName} 
                            </div>
                            <div>
                                <b>Open Date: </b> 
                                <span>{new Date(Number(meeting.metaData.StartTime)).toLocaleDateString()}</span>
                                <span>{new Date(Number(meeting.metaData.StartTime)).toLocaleTimeString()}</span>
                            </div>
                        </Item.Meta>
                        <Item.Extra>
                            {joinButton}
                        </Item.Extra>
                    </Item.Content>
                </Item>
            )
        })


        return (
            <div>
                <div>

                <Modal dimmer={'blurring'} size={'small'} open={this.state.open} onClose={this.close}>
                    <Modal.Header>Create New Meeting</Modal.Header>
                    <Modal.Content>
                        <Form>
                            <Form.Field>
                                <label>Room Name</label>
                                <input placeholder='name' ref={this.roomNameRef}/>
                            </Form.Field>
                            <Form.Field>
                                <Checkbox label='Use Passcode?(not implement)' checked={this.state.usePasscodeChecked}
                                    onClick={()=>{this.setState({ usePasscodeChecked: !this.state.usePasscodeChecked })}}
                                />
                                <label>Pass Code(not implement)</label>
                                <input placeholder='pass' ref={this.roomPassCodeRef}/>
                            </Form.Field>
                            <Form.Field>
                            <Checkbox label='Secret?(not implement)' checked={this.state.secretRoomCreateChecked}
                                    onClick={()=>{this.setState({ secretRoomCreateChecked: !this.state.secretRoomCreateChecked })}}
                                />
                            </Form.Field>
                        </Form>

                    </Modal.Content>
                    <Modal.Actions>
                        <Button negative onClick={this.close}>Cancel</Button>
                        <Button positive icon='checkmark' labelPosition='right' content='Create' onClick={this.createMeeting}/>
                    </Modal.Actions>
                </Modal>
                </div>
                <div>
                    <Segment padded>
                        <Divider horizontal>
                            <Header as='h2' textAlign="left">
                                Lobby
                            </Header>
                        </Divider>
                        <Header as='h3' textAlign="left">
                            Actions
                        </Header>
                        <List link>
                            <List.Item as='a' active onClick={(e, d)=>{this.show()}}>
                                <Header as='h5' textAlign={'left'}>
                                    <Icon name="chat"  active />New Meeting!
                                </Header>
                            </List.Item>
                            <List.Item as='a' active onClick={()=>{props.refreshRoomList()}}>
                                <Header as='h5' textAlign={'left'}>
                                    <Icon name="refresh"  active />Refresh Meeting List
                                </Header>
                            </List.Item>

                        </List>

                        <Divider hidden />


                        <Header as='h3' textAlign="left">
                            Meetings
                        </Header>
  
                        <div>
                            <Item.Group >
                                {meetings}

                            </Item.Group>                            

                        </div>
                    </Segment>
                </div>
            </div>
        )
    }
Example #25
Source File: crewchallenge.tsx    From website with MIT License 4 votes vote down vote up
DailyGame = () => {
	const portalCrew = React.useContext(PortalCrewContext);
	const [dailyId, setDailyId] = useStateWithStorage('datalore/dailyId', '', { rememberForever: true, onInitialize: variableReady });
	const [solution, setSolution] = useStateWithStorage('datalore/dailySolution', '', { rememberForever: true, onInitialize: variableReady });
	const [guesses, setGuesses] = useStateWithStorage('datalore/dailyGuesses', [], { rememberForever: true, onInitialize: variableReady });
	const [stats, setStats] = useStateWithStorage('datalore/dailyStats', new PlayerStats(), { rememberForever: true, onInitialize: variableReady });
	const [loadState, setLoadState] = React.useState(0);
	const [solveState, setSolveState] = React.useState(SolveState.Unsolved);
	const [showStats, setShowStats] = React.useState(false);

	const currentTime = new Date();

	// Game time is current day midnight ET
	const gameTime = new Date(currentTime);
	gameTime.setUTCHours(gameTime.getUTCHours()-4);	// ET is UTC-4
	gameTime.setUTCHours(4, 0, 0, 0);	// Midnight ET is 4:00:00 UTC

	// Daily reset time is next midnight ET
	const resetTime = new Date(gameTime);
	resetTime.setUTCDate(resetTime.getUTCDate()+1)

	React.useEffect(() => {
		if (loadState === 4) initializeDailyGame();
	}, [loadState]);

	React.useEffect(() => {
		setShowStats(solveState !== SolveState.Unsolved);
	}, [solveState]);

	if (loadState < 4 || solution === '')
		return (<></>);

	const rules = new GameRules();

	return (
		<React.Fragment>
			<p>How well do you know the characters from Star Trek Timelines? We pick one mystery crew member every day. Guess who it is, using your knowledge of <b>Variants</b>, <b>Series</b>, <b>Rarity</b>, <b>Skills</b>, and <b>Traits</b> to help narrow the possibilities. You have <b>{DEFAULT_GUESSES} tries</b> to guess the mystery crew. Good luck!</p>
			<CrewChallengeGame rules={rules} solution={solution}
				guesses={guesses} setGuesses={setGuesses}
				solveState={solveState} setSolveState={setSolveState}
				gameTime={gameTime} onGameEnd={handleGameEnd} />
			{renderResetTime()}
			{renderStats()}
		</React.Fragment>
	);

	function variableReady(keyName: string): void {
		setLoadState(prevState => Math.min(prevState + 1, 4));
	}

	function initializeDailyGame(): void {
		const getGameIdFromDate = (gameTime: Date) => {
			const utcYear = gameTime.getUTCFullYear(), utcMonth = gameTime.getUTCMonth()+1, utcDate = gameTime.getUTCDate();
			return `${utcYear}/${utcMonth}/${utcDate}`;
		};

		const getSeed = (gameId: string) => {
			const seedrandom = require('seedrandom');
			const rng = seedrandom(gameId);
			return Math.floor(rng()*portalCrew.length);
		};

		const getFreshSeed = (gameId: string) => {
			let randomSeed = getSeed(gameId);
			while (recentSeeds.includes(randomSeed)) {
				gameId += '+';
				randomSeed = getSeed(gameId);
			}
			return randomSeed;
		};

		// Don't re-use likely solutions from the past 3 weeks
		const recentSeeds = [];
		const previousDay = new Date(gameTime);
		previousDay.setUTCDate(previousDay.getUTCDate()-21);
		for (let i = 0; i < 20; i++) {
			previousDay.setUTCDate(previousDay.getUTCDate()+1);
			let previousId = getGameIdFromDate(previousDay);
			const previousSeed = getFreshSeed(previousId);
			recentSeeds.push(previousSeed);
		}

		// Daily game id is based on game time
		const gameId = getGameIdFromDate(gameTime);
		setDailyId(gameId);

		const dailySeed = getFreshSeed(gameId);
		const dailySolution = portalCrew[dailySeed].symbol;

		// Create new game
		if (dailyId === '' || dailyId !== gameId) {
			setGuesses([]);
			setSolution(dailySolution);
			setSolveState(SolveState.Unsolved);
			return;
		}

		// No existing solution, get solveState from daily solution
		if (solution === '') {
			setSolution(dailySolution);
			if (guesses.includes(dailySolution))
				setSolveState(SolveState.Winner);
			else if (guesses.length >= DEFAULT_GUESSES)
				setSolveState(SolveState.Loser);
			return;
		}

		// Get solveState from existing solution
		if (guesses.includes(solution))
			setSolveState(SolveState.Winner);
		else if (guesses.length >= DEFAULT_GUESSES)
			setSolveState(SolveState.Loser);
	}

	function handleGameEnd(solveState: number): void {
		stats.plays++;
		if (solveState === SolveState.Winner) {
			stats.wins++;
			stats.guesses[guesses.length]++;
			stats.streak++;
			stats.maxStreak = Math.max(stats.streak, stats.maxStreak);
		}
		else {
			stats.guesses.fail++;
			stats.streak = 0;
		}
		setStats({... stats});
	}

	function renderStats(): JSX.Element {
		if (stats.plays === 0) return (<></>);
		if (!showStats)
			return (
				<div style={{ marginTop: '2em' }}>
					<Button icon='chart bar' content='Stats' onClick={() => setShowStats(true)} />
				</div>
			);

		return (
			<React.Fragment>
				<Divider />
				<Header as='h3'>Statistics</Header>
				<Statistic.Group size='small'>
					<Statistic>
						<Statistic.Value>{stats.plays}</Statistic.Value>
						<Statistic.Label>Played</Statistic.Label>
					</Statistic>
					<Statistic>
						<Statistic.Value>{Math.floor(stats.wins/stats.plays*100)}</Statistic.Value>
						<Statistic.Label>Win%</Statistic.Label>
					</Statistic>
					<Statistic>
						<Statistic.Value>{stats.streak}</Statistic.Value>
						<Statistic.Label>Current Streak</Statistic.Label>
					</Statistic>
					<Statistic>
						<Statistic.Value>{stats.maxStreak}</Statistic.Value>
						<Statistic.Label>Max Streak</Statistic.Label>
					</Statistic>
				</Statistic.Group>
			</React.Fragment>
		);
	}

	function renderResetTime(): JSX.Element {
		if (!showStats || solveState === SolveState.Unsolved) return (<></>);

		const formatTime = (seconds: number) => {
			const h = Math.floor(seconds / 3600);
			const m = Math.floor(seconds % 3600 / 60);
			const s = Math.floor(seconds % 3600 % 60);
			return h+'h ' +m+'m';
		};

		return (
			<div style={{ marginTop: '2em' }}>
				A new mystery crew will be available in <b>{formatTime((resetTime.getTime()-currentTime.getTime())/1000)}</b>.
			</div>
		);
	}
}
Example #26
Source File: crewpage.tsx    From website with MIT License 4 votes vote down vote up
render() {
		const { location } = this.props;
		const { markdownRemark, crewJson, site: { siteMetadata } } = this.props.data;
		if (crewJson.edges.length === 0) {
			return <span>Crew not found!</span>;
		}

		const { comments } = this.state;

		let hasBigBookEntry = markdownRemark && markdownRemark.frontmatter && markdownRemark.frontmatter.published;

		const userName = this._getCurrentUsername();

		const crew = crewJson.edges[0].node;
		return (
			<Layout narrowLayout={true}>
				<Helmet titleTemplate={siteMetadata.titleTemplate} defaultTitle={siteMetadata.defaultTitle}>
					<title>{crew.name}</title>
					<meta property='og:type' content='website' />
					<meta property='og:title' content={`${crew.name} - ${siteMetadata.defaultTitle}`} />
					<meta property='og:site_name' content='DataCore' />
					<meta property='og:image' content={`${process.env.GATSBY_ASSETS_URL}${crew.imageUrlPortrait}`} />
					<meta property='og:description' content={markdownRemark.rawMarkdownBody.trim() || siteMetadata.defaultDescription} />
					<meta property='og:url' content={`${siteMetadata.baseUrl}${location.pathname}`} />
				</Helmet>
				<CrewFullEquipTree
					visible={this.state.modalVisible}
					items={this.state.items}
					crew={crew}
					onClosed={() => this.setState({ modalVisible: false })}
				/>
				<Grid columns={2}>
					<Grid.Row stretched>
						<Grid.Column width={16}>
							<Header>
								{crew.name} <Rating defaultRating={crew.max_rarity} maxRating={crew.max_rarity} icon='star' size='large' disabled />
							</Header>
						</Grid.Column>
					</Grid.Row>
					<Grid.Row>
						<Grid.Column width={4}>
							{crew.series && <Image src={`/media/series/${crew.series}.png`} size='small' />}
							<Image src={`${process.env.GATSBY_ASSETS_URL}${crew.imageUrlFullBody}`} size='small' />
						</Grid.Column>
						<Grid.Column width={12}>
							<CommonCrewData crew={crew} markdownRemark={markdownRemark} />

							<div style={{ margin: '1em 0', textAlign: 'right' }}>
								<Button icon='add user' color='green' content='Preview in your roster' onClick={() => { this._addProspect(crew); }} />
							</div>

							{this.state.items.length > 0 ? (
								<React.Fragment>
									{this.renderEquipment(crew)}
									{this.renderEquipmentDetails(crew)}
									<Button
										onClick={() => this.setState({ modalVisible: true })}
										style={{ marginTop: '1em' }}
										content='Full equipment tree'
										icon='right arrow'
										labelPosition='right'
									/>
								</React.Fragment>
							) : (
									<div className='ui medium centered text active inline loader'>Loading items...</div>
								)}

							<Segment>
								<Header as='h4'>{crew.action.name}</Header>
								<p>
									Boosts {CONFIG.CREW_SHIP_BATTLE_BONUS_TYPE[crew.action.bonus_type]} by {crew.action.bonus_amount}
								</p>
								<p>
									Initialize: {crew.action.initial_cooldown}s, Cooldown: {crew.action.cooldown}s, Duration: {crew.action.duration}s
									</p>
								{crew.action.limit && <p>Uses Per Battle: {crew.action.limit}</p>}

								{crew.action.ability && (
									<p>
										Bonus ability:
										{CONFIG.CREW_SHIP_BATTLE_ABILITY_TYPE[crew.action.ability.type].replace('%VAL%', crew.action.ability.amount)}{' '}
										{crew.action.ability.condition > 0 && (
											<span>Trigger: {CONFIG.CREW_SHIP_BATTLE_TRIGGER[crew.action.ability.condition]}</span>
										)}
									</p>
								)}

								<p>
									<b>Accuracy:</b> +{crew.ship_battle.accuracy} <b>Crit Bonus:</b> +{crew.ship_battle.crit_bonus}{' '}
									{crew.ship_battle.crit_chance && (
										<span>
											<b>Crit Rating:</b> +{crew.ship_battle.crit_chance}{' '}
										</span>
									)}
									<b>Evasion:</b> +{crew.ship_battle.evasion}
								</p>
								{crew.action.penalty && (
									<p>
										Decrease {CONFIG.CREW_SHIP_BATTLE_BONUS_TYPE[crew.action.penalty.type]} by {crew.action.penalty.amount}
									</p>
								)}

								{this.renderChargePhases(crew.action, crew.action.charge_phases)}
							</Segment>
						</Grid.Column>
					</Grid.Row>
				</Grid>
				<Divider horizontal hidden />
				{hasBigBookEntry && (
					<React.Fragment>
						<div dangerouslySetInnerHTML={{ __html: markdownRemark.html }} />
						<div style={{ marginTop: '1em', textAlign: 'right' }}>
							-- <a href={`https://www.bigbook.app/crew/${crew.symbol}`}>The Big Book of Behold Advice</a>
						</div>
					</React.Fragment>
				)}
				{/*userName && (
						<div>
							<br />
							<p>Hello, {userName}. You can edit your comment below:</p>
							<SimpleMDE
								value={this.state.commentMarkdown}
								onChange={value => this._handleMarkDownChange(value)}
								options={{ hideIcons: ['fullscreen', 'guide', 'image', 'side-by-side'] }}
							/>
							<Button onClick={() => this._saveComment(crew.symbol, window.localStorage.getItem('token'))} content='Save comment' />
						</div>
					)}
					{comments && (
						<Comment.Group>
							<Header as='h3' dividing>
								Comments
							</Header>

							{comments.map(comment => (
								<Comment key={comment.id}>
									<Comment.Avatar src={comment.user.avatar || `${process.env.GATSBY_ASSETS_URL}crew_portraits_cm_empty_sm.png`} />
									<Comment.Content>
										<Comment.Author>{comment.user.loginUserName}</Comment.Author>
										<Comment.Metadata>
											<div>{comment.lastUpdate}</div>
										</Comment.Metadata>
										<Comment.Text>
											<div dangerouslySetInnerHTML={{ __html: marked(comment.markdown) }} />
										</Comment.Text>
									</Comment.Content>
								</Comment>
							))}
						</Comment.Group>
							)*/}
				<Divider horizontal hidden style={{ marginTop: '4em' }} />
				<ExtraCrewDetails
					crew_archetype_id={crew.archetype_id}
					max_rarity={crew.max_rarity}
					base_skills={crew.base_skills}
					traits={crew.traits} traits_hidden={crew.traits_hidden}
					unique_polestar_combos={crew.unique_polestar_combos}
				/>
			</Layout>
		);
	}