Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Style the 'All Raids' page #67

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/components/tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from '@emotion/styled'

const Tabs = styled.nav`
display: flex;
& > * + * {
margin-left: var(--space-4);
}
`

interface TabItemProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
isSelected: boolean
}

const TabItem = styled.a`
cursor: pointer;
color: var(--black);
font-weight: ${({ isSelected }: TabItemProps) =>
isSelected ? '600' : '400'};
`

export { Tabs, TabItem }
154 changes: 128 additions & 26 deletions src/routes/raids/index.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,144 @@
import React from 'react'

import { Link } from 'react-router-dom'
import LoadingSpinner from '#components/loading-spinner'
import useCollection from '#utils/useCollection'
import { Tabs, TabItem } from '#components/tabs/Tabs'
import styled from '@emotion/styled'

type Tab = {
value: string
title: string
}

const tabs: Tab[] = [
{ title: 'Active', value: 'active' },
{ title: 'Completed', value: 'completed' },
]

const Container = styled.div`
display: flex;
justify-content: space-around;
padding: var(--space-7) var(--space-4);
flex-direction: row-reverse;
@media (max-width: 640px) {
flex-direction: column;
& > * + * {
margin-top: var(--space-5);
}
}
`

const Raids = styled.ul`
padding: var(--space-4) 0;
& > * + * {
margin-top: var(--space-4);
}
`

const Raid = styled.li`
background: white;
width: 25rem;
@media (max-width: 640px) {
width: 18rem;
}
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
padding: var(--space-4);
`

const Input = styled.input`
padding: 10px;
width: 300px;
`

interface FormElements extends HTMLFormControlsCollection {
dungeonInput: HTMLInputElement
}
interface FilterFormElements extends HTMLFormElement {
readonly elements: FormElements
}

const AllRaids = () => {
const collectionData = useCollection<ViewRaidData>('raid-stats')
const [currentTab, setCurrentTab] = React.useState(tabs[0].value)
const [dungeon, setDungeon] = React.useState('')

if (collectionData.state === 'success') {
const data = collectionData.data
const dataInCurrentTab = data.filter((r) => r.status === currentTab)
const filteredData = dungeon
? dataInCurrentTab.filter((r) =>
r.dungeon.toLowerCase().includes(dungeon),
)
: dataInCurrentTab

return (
<>
<h1>Raids</h1>
<h2>Active</h2>
<ul>
{data
.filter((r) => r.status === 'active')
.map((s) => (
<li key={s.id}>
<Link to={`/raids/${s.id}`}>
{s.title} | {s.dungeon}
</Link>
</li>
<Container>
<div>
<h3>Filters</h3>
<form
onSubmit={(e: React.SyntheticEvent<FilterFormElements>) => {
e.preventDefault()
setDungeon(
e.currentTarget.elements.dungeonInput.value.toLowerCase(),
)
}}
>
<div>
<label
htmlFor="dungeonInput"
className="block text-sm font-medium text-gray-700"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't see styles for these classes and we should be using styled components, no?

>
Dungeon
</label>
<div>
<Input
type="text"
id="dungeonInput"
placeholder="hospitalrun/hospitalrun-frontend"
/>
</div>
</div>
</form>
</div>

<div>
<h1>Raids</h1>
<Tabs aria-label="Tabs">
{tabs.map((tab: Tab) => (
<TabItem
key={tab.value}
isSelected={tab.value === currentTab}
{...(tab.value === currentTab
? { 'aria-current': 'page' }
: {})}
onClick={() => setCurrentTab(tab.value)}
>
{tab.title}
</TabItem>
))}
</ul>
<h2>Completed</h2>
<ul>
{data
.filter((r) => r.status === 'completed')
.map((s) => (
<li key={s.id}>
<Link to={`/raids/${s.id}`}>
{s.title} | {s.dungeon}
</Link>
</li>
</Tabs>

<Raids>
{filteredData.map((s) => (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not sure if everyone agrees, but im not really a fan of single letter variables.

<Raid key={s.id}>
<h5>{s.title}</h5>
<Link to={`/raids/${s.id}`}>{s.dungeon}</Link>
</Raid>
))}
</ul>
</>
{filteredData.length === 0 && (
<Raid>
<span role="img" aria-label="cross">
</span>
<span> No raids here </span>
<span role="img" aria-label="cross">
</span>
Comment on lines +130 to +136
Copy link
Contributor

@YPAzevedo YPAzevedo Jan 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the Emoji component for this :)

</Raid>
)}
</Raids>
</div>
</Container>
)
} else {
return collectionData.state === 'loading' ? (
Expand Down