diff --git a/public/images/speaker/jose-alcocer.jpeg b/public/images/speaker/jose-alcocer.jpeg index 4ec046c..a7a6a8f 100644 Binary files a/public/images/speaker/jose-alcocer.jpeg and b/public/images/speaker/jose-alcocer.jpeg differ diff --git a/public/images/sponsor/loka.svg b/public/images/sponsor/loka.svg new file mode 100644 index 0000000..e1c8493 --- /dev/null +++ b/public/images/sponsor/loka.svg @@ -0,0 +1,55 @@ + + + + + + + + + diff --git a/public/images/team/esteban-maya.jpeg b/public/images/team/esteban-maya.jpeg index cffe9fd..5d4c72b 100644 Binary files a/public/images/team/esteban-maya.jpeg and b/public/images/team/esteban-maya.jpeg differ diff --git a/src/app/[lang]/components/NavbarCustom.js b/src/app/[lang]/components/NavbarCustom.js index 04bbaa5..2904b3c 100644 --- a/src/app/[lang]/components/NavbarCustom.js +++ b/src/app/[lang]/components/NavbarCustom.js @@ -43,6 +43,9 @@ const NavbarCustom = ({ lang }) => { + {/* + {i18nDictionary?.navbar?.schedule} + */} {i18nDictionary?.navbar?.keynotes} diff --git a/src/app/[lang]/schedule/components/Card.js b/src/app/[lang]/schedule/components/Card.js new file mode 100644 index 0000000..95a39a4 --- /dev/null +++ b/src/app/[lang]/schedule/components/Card.js @@ -0,0 +1,76 @@ +import React from 'react'; +import Link from 'next/link'; +import propTypes from 'prop-types'; +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; +import Image from 'next/image'; + +import speakerList from '@/data/speakers.json'; + +const Card = ({ talkData, index, lang, langMapping }) => { + const colorBorderSpeaker = ['border-pink', 'border-yellow', 'border-purple', 'border-blue']; + + const getSpeakerData = (id) => { + return speakerList.find((speaker) => speaker.id === id); + }; + + return ( + + + +

+ {talkData.title[lang]} ({langMapping && langMapping[talkData?.spoken_language]}) +

+ + + + {talkData.tags.map((tag) => ( + + {tag} + + ))} + + + {talkData.speakers.map((speaker) => { + const speakerData = getSpeakerData(speaker); + + return ( + + Speaker Image + + ); + })} + +
+ ); +}; + +Card.propTypes = { + talkData: propTypes.shape({ + id: propTypes.number, + first_name: propTypes.string, + last_name: propTypes.string, + biography: propTypes.shape({}), + photo: propTypes.string, + type: propTypes.string, + country_origin: propTypes.string, + facebook: propTypes.string, + twitter: propTypes.string, + linkedin: propTypes.string, + github: propTypes.string, + website: propTypes.string + }), + reverse: propTypes.bool, + index: propTypes.number, + lang: propTypes.string +}; + +export default Card; diff --git a/src/app/[lang]/schedule/components/Schedule.js b/src/app/[lang]/schedule/components/Schedule.js new file mode 100644 index 0000000..99486be --- /dev/null +++ b/src/app/[lang]/schedule/components/Schedule.js @@ -0,0 +1,82 @@ +'use client'; + +import React, { useState, useEffect } from 'react'; +import propTypes from 'prop-types'; +import Container from 'react-bootstrap/Container'; +import Form from 'react-bootstrap/Form'; +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; + +import Card from '@/app/[lang]/talks/components/Card'; +import Title from '@/app/[lang]/talks/components/Title'; + +import { useI18n } from '@/contexts/I18nContext'; + +const Schedule = ({ lang, talksList, defaultTag, allTags }) => { + const i18nDictionary = useI18n(); + const [tagFilter, setTagFilter] = useState(defaultTag || 'all'); + const [talks, setSchedule] = useState(talksList); + + useEffect(() => { + if (tagFilter === 'all') { + setSchedule(talksList); + } else { + setSchedule(talksList.filter((talk) => talk.tags.includes(tagFilter))); + } + }, [tagFilter, talksList]); + + return ( +
+
+ + <Container> + <Row className="justify-content-center"> + <Col xs={12} md={4}> + <div className="filter-container"> + <Form.Group controlId="formBasicSelect"> + <Form.Label>{i18nDictionary?.sections?.talks?.filter}</Form.Label> + <Form.Control + as="select" + value={tagFilter} + onChange={(e) => { + setTagFilter(e.target.value); + }}> + <option value="all">{i18nDictionary?.sections?.talks?.tags?.all}</option> + {allTags && + allTags.map((tag) => ( + <option key={tag} value={tag}> + {i18nDictionary?.sections?.talks?.tags?.[tag] || tag} + </option> + ))} + </Form.Control> + </Form.Group> + </div> + </Col> + </Row> + <Row className="justify-content-center"> + <Col xs={12} md={10}> + <Row> + {talks.map((talk, index) => ( + <Col xs={12} md={6} key={talk.id}> + <Card + talkData={talk} + index={index} + lang={lang} + langMapping={i18nDictionary?.languages} + /> + </Col> + ))} + </Row> + </Col> + </Row> + </Container> + </div> + </section> + ); +}; + +Schedule.propTypes = { + lang: propTypes.string +}; + +export default Schedule; diff --git a/src/app/[lang]/schedule/components/Title.js b/src/app/[lang]/schedule/components/Title.js new file mode 100644 index 0000000..a162425 --- /dev/null +++ b/src/app/[lang]/schedule/components/Title.js @@ -0,0 +1,33 @@ +import React from 'react'; +import propTypes from 'prop-types'; +import Container from 'react-bootstrap/Container'; +import Row from 'react-bootstrap/Row'; +import Col from 'react-bootstrap/Col'; + +const Title = ({ content, counter }) => { + return ( + <div className="welcome"> + <div className="welcome-bg"> + <Container> + <Row className="justify-content-center"> + <Col xs={10} md={6}> + <div className="title-container"> + <h2 className="title"> + <span className="bold"> + {content?.title} ({counter}) + </span> + </h2> + </div> + </Col> + </Row> + </Container> + </div> + </div> + ); +}; + +Title.propTypes = { + content: propTypes.object +}; + +export default Title; diff --git a/src/app/[lang]/schedule/page.js b/src/app/[lang]/schedule/page.js new file mode 100644 index 0000000..f272142 --- /dev/null +++ b/src/app/[lang]/schedule/page.js @@ -0,0 +1,43 @@ +import React from 'react'; +import propTypes from 'prop-types'; +import Schedule from './components/Schedule'; + +import talksList from '@/data/talks.json'; + +import en from '@/data/dictionaries/en.json'; +import es from '@/data/dictionaries/es.json'; + +export async function generateMetadata({ params: { lang } }, parent) { + const dataLang = lang === 'en' ? en : es; + const dataSection = dataLang?.sections; + const scheduleData = dataSection.schedule; + + return { + title: scheduleData.title + }; +} + +const getAllTags = () => { + const tags = []; + + talksList.forEach((talk) => { + talk.tags.forEach((tag) => { + if (!tags.includes(tag)) { + tags.push(tag); + } + }); + }); + return tags; +}; + +const Page = ({ params: { lang } }) => { + return <Schedule lang={lang} talksList={talksList} allTags={getAllTags()} />; +}; + +Page.propTypes = { + params: propTypes.shape({ + lang: propTypes.string + }) +}; + +export default Page; diff --git a/src/app/[lang]/speakers/[uniquepage]/Speakers.js b/src/app/[lang]/speakers/[uniquepage]/Speakers.js index 3426121..d6391a3 100644 --- a/src/app/[lang]/speakers/[uniquepage]/Speakers.js +++ b/src/app/[lang]/speakers/[uniquepage]/Speakers.js @@ -148,7 +148,7 @@ const Speakers = ({ speaker, talks, lang }) => { </span> {talks.map((talk) => ( <div key={talk.id} className="talk-wrapper"> - <Link href={`/talks/${talk.id}`} locale={lang}> + <Link href={`/${lang}/talks/${talk.id}`} locale={lang}> <h4>{talk.title[lang]}</h4> </Link> </div> diff --git a/src/data/dictionaries/en.json b/src/data/dictionaries/en.json index 9eaf2d6..443f9bb 100644 --- a/src/data/dictionaries/en.json +++ b/src/data/dictionaries/en.json @@ -50,6 +50,9 @@ "sponsors": { "title": "Sponsors", "description": "PyCon Colombia can be your platform to gain brand recognition, take leads and recruit from an audience of highly skilled professionals!" + }, + "schedule": { + "title": "Schedule" } }, "languages": { diff --git a/src/data/dictionaries/es.json b/src/data/dictionaries/es.json index c885e2c..0eeb701 100644 --- a/src/data/dictionaries/es.json +++ b/src/data/dictionaries/es.json @@ -50,6 +50,9 @@ "sponsors": { "title": "Patrocinadores", "description": "PyCon Colombia can be your platform to gain brand recognition, take leads and recruit from an audience of highly skilled professionals!" + }, + "schedule": { + "title": "Cronograma" } }, "languages": { diff --git a/src/data/schedule.json b/src/data/schedule.json new file mode 100644 index 0000000..3b578af --- /dev/null +++ b/src/data/schedule.json @@ -0,0 +1,59 @@ +[ + { + "date": "2024-06-07", + "order": [ + { + "hour": "08:00", + "events": [ + { + "title": "Attenders Arrival - Kits Delivery" + } + ] + }, + { + "hour": "08:30", + "events": [ + { + "room": "main", + "title": "Opening (Organizers)" + } + ] + }, + { + "hour": "08:45", + "events": [ + { + "room": "main", + "title": "EAFIT Opening" + } + ] + }, + { + "hour": "09:00", + "events": [ + { + "room": "main", + "title": "Quimisha Goss" + } + ] + }, + { + "hour": "10:30", + "events": [ + { + "room": "main", + "event_id": 39 + }, + { + "room": "aux_1", + "event_id": 4 + }, + { + "room": "aux_2", + "event_id": 22 + } + ] + } + ] + } +] diff --git a/src/data/sponsors.json b/src/data/sponsors.json index 5cbb3df..14fb224 100644 --- a/src/data/sponsors.json +++ b/src/data/sponsors.json @@ -17,6 +17,11 @@ "name": "Elastic", "image": "elastic.svg", "url": "https://elastic.co/" + }, + { + "name": "Loka", + "image": "loka.svg", + "url": "https://loka.com/careers" } ], "silver_plus": [ diff --git a/src/data/team.json b/src/data/team.json index 4bf8fb1..437a512 100644 --- a/src/data/team.json +++ b/src/data/team.json @@ -110,7 +110,7 @@ "facebook": "", "twitter": "@esteban_x64", "linkedin": "esteban-x64", - "github": "", + "github": "estebanx64", "website": "" }, { @@ -265,4 +265,4 @@ "github": "", "website": "" } -] \ No newline at end of file +]