Skip to content

Commit

Permalink
feat: add chakra
Browse files Browse the repository at this point in the history
  • Loading branch information
pom421 authored Mar 27, 2022
2 parents 1c0a850 + f08a304 commit 11ce44f
Show file tree
Hide file tree
Showing 6 changed files with 1,162 additions and 111 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
"check-all": "yarn lint && yarn type-check && yarn test --watchAll=false"
},
"dependencies": {
"@chakra-ui/react": "^1.8.6",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"classnames": "^2.3.1",
"d3": "^7.2.1",
"debounce": "^1.2.1",
"fetch-jsonp": "^1.2.1",
"framer-motion": "^6",
"js-yaml-loader": "^1.2.2",
"next": "^12.1.0",
"ramda": "^0.23.0",
Expand Down
232 changes: 141 additions & 91 deletions src/components/Kiosque.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import m from "../domain/model"
import Vignette from "./Vignette.jsx"
import { cacheWikiPages } from "../utils/wikipedia"
import Filters from "./Filters"
import { Box, HStack, Radio, RadioGroup, VStack } from "@chakra-ui/react"

const normalise = (s) => removeAccents(s?.toLowerCase())

Expand Down Expand Up @@ -70,34 +71,54 @@ const questions = [
{ question: "Quel nombre d'actionnaires par média ?" },
]

export default class Kiosque extends React.Component {
state = {
search: null,
filters: {},
selectedQuestion: null,
wikiCacheReady: false,
}
const defaultState = {
search: null,
filters: {},
selectedQuestion: null,
wikiCacheReady: false,
}

export function Kiosque() {
const [state, setState] = React.useState(defaultState)
const formRef = React.useRef(null)

const { selectedQuestion, search, filters, wikiCacheReady } = state

console.log("filters", filters)

componentDidMount() {
cacheWikiPages(m.entitiesByType("journal")).then(() => this.setState({ wikiCacheReady: true }))
const selectedQuestionData = questions.find(({ question }) => question === selectedQuestion)
const selectedQuestionName = selectedQuestionData?.name
const selectedQuestionFilter = selectedQuestionData?.filter

const questionAnswers = selectedQuestionFilter ? R.toPairs(selectedQuestionFilter()) : []
const sorted = R.sortBy(R.head)(questionAnswers)

React.useEffect(() => {
cacheWikiPages(m.entitiesByType("journal")).then(() => setState({ wikiCacheReady: true }))
window.model = m
}, [])

function onRadioClickOld({ target: { name, value } }) {
const newFilters = filters[name] === value ? R.dissoc(name)(filters) : R.assoc(name, value)(filters)

setState({ filters: newFilters })
}

onRadioClick = ({ target: { name, value } }) => {
const { filters } = this.state,
newFilters = filters[name] === value ? R.dissoc(name)(filters) : R.assoc(name, value)(filters)
function onRadioClick() {
const data = Object.fromEntries(new FormData(formRef.current))

this.setState({ filters: newFilters })
console.log("data", data)

setState({ filters: data })
}

searchInput = ({ target: { value } }) =>
this.setState({
function searchInput({ target: { value } }) {
setState({
search: value.length < 3 ? null : normalise(value),
})
}

vignettes(questionItems, size) {
const { search, filters } = this.state

function vignettes(questionItems, size) {
return R.pipe(
R.filter(
(e) =>
Expand All @@ -114,81 +135,110 @@ export default class Kiosque extends React.Component {
)(questionItems ? questionItems : m.entitiesByType("journal"))
}

render() {
const { selectedQuestion } = this.state
const selectedQuestionData = questions.find(({ question }) => question === selectedQuestion)
const selectedQuestionName = selectedQuestionData?.name
const selectedQuestionFilter = selectedQuestionData?.filter

const questionAnswers = selectedQuestionFilter ? R.toPairs(selectedQuestionFilter()) : []
const sorted = R.sortBy(R.head)(questionAnswers)

return (
<div id="kiosque">
<div id="search">
<input type="text" placeholder="Trouvez un journal..." onChange={this.searchInput} />
<Filters onClick={this.onRadioClick} state={this.state.filters} />
return (
<div id="kiosque">
<div id="search">
<form ref={formRef}>
<input type="text" placeholder="Trouvez un journal..." onChange={searchInput} />
{/* <Filters onClick={onRadioClick} state={filters} /> */}
<HStack spacing="8" justify="center" my="8">
<RadioGroup name="périodicité" onChange={onRadioClick}>
<VStack align="start">
<Radio label="mensuel" value="mensuelle">
Mensuelle
</Radio>
<Radio label="hebdomadaire" value="hebdomadaire">
Hebdomadaire
</Radio>
<Radio label="quotidien" value="quotidienne">
Quotidienne
</Radio>
</VStack>
</RadioGroup>

<RadioGroup name="couverture" onChange={onRadioClick}>
<VStack align="start">
<Radio label="national" value="nationale">
Nationale
</Radio>
<Radio label="local" value="locale">
Locale
</Radio>
</VStack>
</RadioGroup>

<RadioGroup name="papier" align="start" onChange={onRadioClick}>
<VStack>
<Radio label="papier et en ligne" value="oui">
Oui
</Radio>
<Radio label="en ligne seulement" value="non">
Non
</Radio>
</VStack>
</RadioGroup>
</HStack>
<i className="fa fa-search" aria-hidden="true"></i>
</div>
<div id="questions">
{selectedQuestion ? (
<button onClick={() => this.setState({ selectedQuestion: null })}>
<p id="backToQuestionList">
<i className="fa fa-undo" aria-hidden="true"></i>&nbsp;&nbsp;revenir à la liste des sujets
</p>
</button>
) : (
<p>...ou explorez un sujet :</p>
)}
<ul id="question-list">
{questions.map(({ name, question, filter, icon }) => (
<li
key={name}
className={classNames({
selected: question === selectedQuestion,
oneSelected: selectedQuestion,
unavailable: !filter,
})}
>
<span className="iconWrapper">
{filter ? (
<i className={"fa " + icon} aria-hidden="true"></i>
) : (
<span className="iconUnavailabe">À venir</span>
)}
</span>
<a href="#" onClick={() => this.setState({ focusedAnswer: null, selectedQuestion: question })}>
{question}
</a>
</li>
))}
</ul>
{selectedQuestion && selectedQuestionFilter && (
<section id="questionAnswers" data-question={selectedQuestionName}>
<ul id="answerSummary">
{sorted.map(([text, items]) => (
<li key={text} className={classNames("answerBlock")}>
<div className="score">
{items.length}
{/* {selectedQuestionBackgrounds && selectedQuestionBackgrounds[text[0]] && (
</form>
</div>
<div id="questions">
{selectedQuestion ? (
<button onClick={() => setState({ selectedQuestion: null })}>
<p id="backToQuestionList">
<i className="fa fa-undo" aria-hidden="true"></i>&nbsp;&nbsp;revenir à la liste des sujets
</p>
</button>
) : (
<p>...ou explorez un sujet :</p>
)}
<ul id="question-list">
{questions.map(({ name, question, filter, icon }) => (
<li
key={name}
className={classNames({
selected: question === selectedQuestion,
oneSelected: selectedQuestion,
unavailable: !filter,
})}
>
<span className="iconWrapper">
{filter ? (
<i className={"fa " + icon} aria-hidden="true"></i>
) : (
<span className="iconUnavailabe">À venir</span>
)}
</span>
<a href="#" onClick={() => setState({ focusedAnswer: null, selectedQuestion: question })}>
{question}
</a>
</li>
))}
</ul>
{selectedQuestion && selectedQuestionFilter && (
<section id="questionAnswers" data-question={selectedQuestionName}>
<ul id="answerSummary">
{sorted.map(([text, items]) => (
<li key={text} className={classNames("answerBlock")}>
<div className="score">
{items.length}
{/* {selectedQuestionBackgrounds && selectedQuestionBackgrounds[text[0]] && (
<img src={require("../images/" + selectedQuestionBackgrounds[text[0]])} />
)} */}
</div>
<div className="text">{text.split(": ")[1]}</div>
{this.state.wikiCacheReady && <ul className="answerVignettes">{this.vignettes(items, "small")}</ul>}
</li>
))}
</ul>
</section>
)}
</div>
{!selectedQuestion &&
(this.state.wikiCacheReady ? (
<ul id="vignettes">{this.vignettes(null, "big")}</ul>
) : (
<div style={{ textAlign: "center", margin: "10%" }}>Chargement des images en cours...</div>
))}
</div>
<div className="text">{text.split(": ")[1]}</div>
{wikiCacheReady && <ul className="answerVignettes">{vignettes(items, "small")}</ul>}
</li>
))}
</ul>
</section>
)}
</div>
)
}
{!selectedQuestion &&
(wikiCacheReady ? (
<ul id="vignettes">{vignettes(null, "big")}</ul>
) : (
<div style={{ textAlign: "center", margin: "10%" }}>Chargement des images en cours...</div>
))}
</div>
)
}
5 changes: 4 additions & 1 deletion src/pages/_app.page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import Layout from "../components/Layout"
import { ChakraProvider } from "@chakra-ui/react"
import "../styles/globals.css"

function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
<ChakraProvider>
<Component {...pageProps} />
</ChakraProvider>
</Layout>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/kiosque.page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react"
import Kiosque from "../components/Kiosque"
import { Kiosque } from "@/components/Kiosque"

function KiosquePage() {
return <Kiosque />
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.tsbuildinfo

Large diffs are not rendered by default.

Loading

0 comments on commit 11ce44f

Please sign in to comment.