From cc3616b7952491a673cbe0f42edf39443e817124 Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Fri, 3 Jan 2025 15:14:02 -0400 Subject: [PATCH 01/11] :recycle: workshops landing when logged in --- customtypes/page/index.json | 1 + prismicio-types.d.ts | 214 ++++++++++++++++++ slices/EventCards/index.jsx | 2 + slices/EventCards/mocks.json | 77 ++++--- slices/EventCards/model.json | 42 ++-- slices/Markdown/mocks.json | 108 ++++----- slices/Markdown/model.json | 27 +-- slices/SearchBar/index.js | 30 +++ slices/SearchBar/mocks.json | 47 ++++ slices/SearchBar/model.json | 52 +++++ slices/SearchBar/screenshot-default.png | Bin 0 -> 33362 bytes slices/Technologies/mocks.json | 58 ++--- slices/Technologies/model.json | 21 +- slices/TechnologiesPills/index.js | 2 + slices/TechnologiesPills/mocks.json | 106 +++++---- slices/TechnologiesPills/model.json | 25 +- slices/TitleIntroduction/mocks.json | 4 + slices/TitleIntroduction/model.json | 9 + slices/TwoColumn/mocks.json | 4 + slices/TwoColumn/model.json | 9 + slices/index.js | 1 + src/common/components/MktEventCards.jsx | 80 +++++-- src/common/components/MktSearchBar.jsx | 120 ++++++++++ .../components/MktTechnologiesPills.jsx | 10 +- src/pages/[uid]/index.jsx | 16 +- src/pages/index.jsx | 1 + 26 files changed, 837 insertions(+), 229 deletions(-) create mode 100644 slices/SearchBar/index.js create mode 100644 slices/SearchBar/mocks.json create mode 100644 slices/SearchBar/model.json create mode 100644 slices/SearchBar/screenshot-default.png create mode 100644 src/common/components/MktSearchBar.jsx diff --git a/customtypes/page/index.json b/customtypes/page/index.json index 4d1264756..077339000 100644 --- a/customtypes/page/index.json +++ b/customtypes/page/index.json @@ -38,6 +38,7 @@ "fieldset": "Slice Zone", "config": { "choices": { + "search_bar": { "type": "SharedSlice" }, "info_cards": { "type": "SharedSlice" }, "trust_cards": { "type": "SharedSlice" }, "title_introduction": { "type": "SharedSlice" }, diff --git a/prismicio-types.d.ts b/prismicio-types.d.ts index dde0be148..cf8ea5cec 100644 --- a/prismicio-types.d.ts +++ b/prismicio-types.d.ts @@ -6,6 +6,7 @@ import type * as prismicClient from "@prismicio/client"; type Simplify = { [KeyType in keyof T]: T[KeyType] }; type PageDocumentDataSlicesSlice = + | SearchBarSlice | InfoCardsSlice | TrustCardsSlice | TitleIntroductionSlice @@ -149,6 +150,38 @@ export interface EventCardsSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ margin: prismic.KeyTextField; + + /** + * Is for logged in users only field in *EventCards → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: event_cards.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; + + /** + * Search Sensitive field in *EventCards → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: event_cards.primary.search_sensitive + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + search_sensitive: prismic.BooleanField; + + /** + * Tech Filtered field in *EventCards → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: Auto filter the events by a technology + * - **API ID Path**: event_cards.primary.tech_filtered + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + tech_filtered: prismic.KeyTextField; } /** @@ -511,6 +544,17 @@ export interface MarkdownSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ padding: prismic.KeyTextField; + + /** + * Is for logged in users only field in *Markdown → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: markdown.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; } /** @@ -1014,6 +1058,107 @@ export type RoadMapSlice = prismic.SharedSlice< RoadMapSliceVariation >; +/** + * Primary content in *SearchBar → Primary* + */ +export interface SearchBarSliceDefaultPrimary { + /** + * heading top field in *SearchBar → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: search_bar.primary.heading_top + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + heading_top: prismic.KeyTextField; + + /** + * heading bottom field in *SearchBar → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: search_bar.primary.heading_bottom + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + heading_bottom: prismic.KeyTextField; + + /** + * subtitle field in *SearchBar → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: search_bar.primary.subtitle + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + subtitle: prismic.KeyTextField; + + /** + * background field in *SearchBar → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: hex + * - **API ID Path**: search_bar.primary.background + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + background: prismic.KeyTextField; + + /** + * Is for logged in users only field in *SearchBar → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: search_bar.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; +} + +/** + * Primary content in *SearchBar → Items* + */ +export interface SearchBarSliceDefaultItem { + /** + * Popular Searches field in *SearchBar → Items* + * + * - **Field Type**: Text + * - **Placeholder**: Tecnology pills at the bottom + * - **API ID Path**: search_bar.items[].popular_searches + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + popular_searches: prismic.KeyTextField; +} + +/** + * Default variation for SearchBar Slice + * + * - **API ID**: `default` + * - **Description**: Default + * - **Documentation**: https://prismic.io/docs/slice + */ +export type SearchBarSliceDefault = prismic.SharedSliceVariation< + "default", + Simplify, + Simplify +>; + +/** + * Slice variation for *SearchBar* + */ +type SearchBarSliceVariation = SearchBarSliceDefault; + +/** + * SearchBar Shared Slice + * + * - **API ID**: `search_bar` + * - **Description**: SearchBar + * - **Documentation**: https://prismic.io/docs/slice + */ +export type SearchBarSlice = prismic.SharedSlice< + "search_bar", + SearchBarSliceVariation +>; + /** * Primary content in *ShowPrices → Primary* */ @@ -1142,6 +1287,17 @@ export interface TechnologiesSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ margin: prismic.KeyTextField; + + /** + * Is for logged in users only field in *Technologies → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: technologies.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; } /** @@ -1207,6 +1363,37 @@ export interface TechnologiesPillsSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ margin: prismic.KeyTextField; + + /** + * background field in *TechnologiesPills → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: technologies_pills.primary.background + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + background: prismic.KeyTextField; + + /** + * Is for logged in users only field in *TechnologiesPills → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: technologies_pills.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; + + /** + * padding top field in *TechnologiesPills → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: technologies_pills.primary.padding_top + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + padding_top: prismic.KeyTextField; } /** @@ -1460,6 +1647,17 @@ export interface TitleIntroductionSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ button_id: prismic.KeyTextField; + + /** + * Is for logged in users only field in *TitleIntroduction → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: title_introduction.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; } /** @@ -1782,6 +1980,17 @@ export interface TwoColumnSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#select */ fontFamily: prismic.SelectField<"Lato" | "Space Grotesk Variable", "filled">; + + /** + * Is for logged in users only field in *TwoColumn → Primary* + * + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: two_column.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean + */ + is_for_logged_in_users: prismic.BooleanField; } /** @@ -1856,6 +2065,11 @@ declare module "@prismicio/client" { RoadMapSliceDefaultPrimary, RoadMapSliceVariation, RoadMapSliceDefault, + SearchBarSlice, + SearchBarSliceDefaultPrimary, + SearchBarSliceDefaultItem, + SearchBarSliceVariation, + SearchBarSliceDefault, ShowPricesSlice, ShowPricesSliceDefaultPrimary, ShowPricesSliceVariation, diff --git a/slices/EventCards/index.jsx b/slices/EventCards/index.jsx index 73c025d1e..936e3cdfa 100644 --- a/slices/EventCards/index.jsx +++ b/slices/EventCards/index.jsx @@ -12,6 +12,8 @@ const EventCards = ({ slice }) => ( id={slice?.primary?.id_key} title={slice?.primary?.title} endpoint={slice?.primary?.endpoint} + techFilter={slice?.primary?.tech_filtered} + searchSensitive={slice?.primary?.search_sensitive} margin={slice?.primary?.margin || '40px auto'} /> ); diff --git a/slices/EventCards/mocks.json b/slices/EventCards/mocks.json index 8cda9d006..c5a7b25e0 100644 --- a/slices/EventCards/mocks.json +++ b/slices/EventCards/mocks.json @@ -1,34 +1,47 @@ [ - { - "__TYPE__": "SharedSliceContent", - "variation": "default", - "primary": { - "id_key": { - "__TYPE__": "FieldContent", - "value": "fewer", - "type": "Text" - }, - "title": { - "__TYPE__": "FieldContent", - "value": "pictured", - "type": "Text" - }, - "endpoint": { - "__TYPE__": "FieldContent", - "value": "carried", - "type": "Text" - }, - "margin": { - "__TYPE__": "FieldContent", - "value": "continent", - "type": "Text" - } - }, - "items": [ - { - "__TYPE__": "GroupItemContent", - "value": [] - } - ] - } + { + "__TYPE__": "SharedSliceContent", + "variation": "default", + "primary": { + "id_key": { + "__TYPE__": "FieldContent", + "value": "fewer", + "type": "Text" + }, + "title": { + "__TYPE__": "FieldContent", + "value": "pictured", + "type": "Text" + }, + "endpoint": { + "__TYPE__": "FieldContent", + "value": "carried", + "type": "Text" + }, + "margin": { + "__TYPE__": "FieldContent", + "value": "continent", + "type": "Text" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": false + }, + "search_sensitive": { + "__TYPE__": "BooleanContent", + "value": false + }, + "tech_filtered": { + "__TYPE__": "FieldContent", + "value": "swam", + "type": "Text" + } + }, + "items": [ + { + "__TYPE__": "GroupItemContent", + "value": [] + } + ] + } ] \ No newline at end of file diff --git a/slices/EventCards/model.json b/slices/EventCards/model.json index 394a21ab3..23fc745f2 100644 --- a/slices/EventCards/model.json +++ b/slices/EventCards/model.json @@ -13,24 +13,15 @@ "primary": { "id_key": { "type": "Text", - "config": { - "label": "Id key", - "placeholder": "" - } + "config": { "label": "Id key", "placeholder": "" } }, "title": { "type": "Text", - "config": { - "label": "Title", - "placeholder": "" - } + "config": { "label": "Title", "placeholder": "" } }, "endpoint": { "type": "Text", - "config": { - "label": "Endpoint", - "placeholder": "" - } + "config": { "label": "Endpoint", "placeholder": "" } }, "margin": { "type": "Text", @@ -38,10 +29,35 @@ "label": "Margin", "placeholder": "top, right, bottom, left" } + }, + "is_for_logged_in_users": { + "type": "Boolean", + "config": { + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false + } + }, + "search_sensitive": { + "type": "Boolean", + "config": { + "label": "Search Sensitive", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false + } + }, + "tech_filtered": { + "type": "Text", + "config": { + "label": "Tech Filtered", + "placeholder": "Auto filter the events by a technology" + } } }, "items": {}, "imageUrl": "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format" } ] -} \ No newline at end of file +} diff --git a/slices/Markdown/mocks.json b/slices/Markdown/mocks.json index 444c6a92d..8fefd9cae 100644 --- a/slices/Markdown/mocks.json +++ b/slices/Markdown/mocks.json @@ -1,54 +1,58 @@ [ - { - "__TYPE__": "SharedSliceContent", - "variation": "default", - "primary": { - "title": { - "__TYPE__": "FieldContent", - "value": "left", - "type": "Text" - }, - "description": { - "__TYPE__": "FieldContent", - "value": "chart", - "type": "Text" - }, - "markdown": { - "__TYPE__": "StructuredTextContent", - "value": [ - { - "type": "paragraph", - "content": { - "text": "Consequat aliqua pariatur ea dolore reprehenderit nostrud aliquip eu magna nulla ea voluptate Lorem et. Officia aliquip occaecat reprehenderit cillum laboris minim est nulla consectetur aliqua Lorem sit tempor. Ad consectetur exercitation nisi id nostrud nulla ipsum ipsum." - } - } - ] - }, - "enable_table_of_content": { - "__TYPE__": "BooleanContent", - "value": false - }, - "id_key": { - "__TYPE__": "FieldContent", - "value": "should", - "type": "Text" - }, - "margin": { - "__TYPE__": "FieldContent", - "value": "opposite", - "type": "Text" - }, - "padding": { - "__TYPE__": "FieldContent", - "value": "won", - "type": "Text" - } - }, - "items": [ - { - "__TYPE__": "GroupItemContent", - "value": [] - } - ] - } + { + "__TYPE__": "SharedSliceContent", + "variation": "default", + "primary": { + "title": { + "__TYPE__": "FieldContent", + "value": "left", + "type": "Text" + }, + "description": { + "__TYPE__": "FieldContent", + "value": "chart", + "type": "Text" + }, + "markdown": { + "__TYPE__": "StructuredTextContent", + "value": [ + { + "type": "paragraph", + "content": { + "text": "Consequat aliqua pariatur ea dolore reprehenderit nostrud aliquip eu magna nulla ea voluptate Lorem et. Officia aliquip occaecat reprehenderit cillum laboris minim est nulla consectetur aliqua Lorem sit tempor. Ad consectetur exercitation nisi id nostrud nulla ipsum ipsum." + } + } + ] + }, + "enable_table_of_content": { + "__TYPE__": "BooleanContent", + "value": false + }, + "id_key": { + "__TYPE__": "FieldContent", + "value": "should", + "type": "Text" + }, + "margin": { + "__TYPE__": "FieldContent", + "value": "opposite", + "type": "Text" + }, + "padding": { + "__TYPE__": "FieldContent", + "value": "won", + "type": "Text" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": false + } + }, + "items": [ + { + "__TYPE__": "GroupItemContent", + "value": [] + } + ] + } ] \ No newline at end of file diff --git a/slices/Markdown/model.json b/slices/Markdown/model.json index f6bf80584..8d4928c84 100644 --- a/slices/Markdown/model.json +++ b/slices/Markdown/model.json @@ -13,24 +13,15 @@ "primary": { "id_key": { "type": "Text", - "config": { - "label": "ID Key", - "placeholder": "" - } + "config": { "label": "ID Key", "placeholder": "" } }, "title": { "type": "Text", - "config": { - "label": "Title", - "placeholder": "" - } + "config": { "label": "Title", "placeholder": "" } }, "description": { "type": "Text", - "config": { - "label": "Description", - "placeholder": "" - } + "config": { "label": "Description", "placeholder": "" } }, "markdown": { "type": "StructuredText", @@ -59,9 +50,15 @@ }, "padding": { "type": "Text", + "config": { "label": "Padding", "placeholder": "" } + }, + "is_for_logged_in_users": { + "type": "Boolean", "config": { - "label": "Padding", - "placeholder": "" + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false } } }, @@ -69,4 +66,4 @@ "imageUrl": "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format" } ] -} \ No newline at end of file +} diff --git a/slices/SearchBar/index.js b/slices/SearchBar/index.js new file mode 100644 index 000000000..86db0f5be --- /dev/null +++ b/slices/SearchBar/index.js @@ -0,0 +1,30 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import MktSearchBar from '../../src/common/components/MktSearchBar'; + +/** + * @typedef {import("@prismicio/client").Content.SearchBarSlice} SearchBarSlice + * @typedef {import("@prismicio/react").SliceComponentProps} SearchBarProps + * @param {SearchBarProps} + */ + +const SearchBar = ({ slice }) => ( + +) + +SearchBar.propTypes = { + slice: PropTypes.objectOf(PropTypes.any), +}; + +SearchBar.defaultProps = { + slice: {}, +}; + +export default SearchBar; diff --git a/slices/SearchBar/mocks.json b/slices/SearchBar/mocks.json new file mode 100644 index 000000000..aa022cca5 --- /dev/null +++ b/slices/SearchBar/mocks.json @@ -0,0 +1,47 @@ +[ + { + "__TYPE__": "SharedSliceContent", + "variation": "default", + "primary": { + "heading_top": { + "__TYPE__": "FieldContent", + "value": "because", + "type": "Text" + }, + "heading_bottom": { + "__TYPE__": "FieldContent", + "value": "card", + "type": "Text" + }, + "subtitle": { + "__TYPE__": "FieldContent", + "value": "memory", + "type": "Text" + }, + "background": { + "__TYPE__": "FieldContent", + "value": "poem", + "type": "Text" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": false + } + }, + "items": [ + { + "__TYPE__": "GroupItemContent", + "value": [ + [ + "popular_searches", + { + "__TYPE__": "FieldContent", + "value": "one", + "type": "Text" + } + ] + ] + } + ] + } +] \ No newline at end of file diff --git a/slices/SearchBar/model.json b/slices/SearchBar/model.json new file mode 100644 index 000000000..e525aa44f --- /dev/null +++ b/slices/SearchBar/model.json @@ -0,0 +1,52 @@ +{ + "id": "search_bar", + "type": "SharedSlice", + "name": "SearchBar", + "description": "SearchBar", + "variations": [ + { + "id": "default", + "name": "Default", + "docURL": "...", + "version": "initial", + "description": "Default", + "imageUrl": "", + "primary": { + "heading_top": { + "type": "Text", + "config": { "label": "heading top", "placeholder": "" } + }, + "heading_bottom": { + "type": "Text", + "config": { "label": "heading bottom", "placeholder": "" } + }, + "subtitle": { + "type": "Text", + "config": { "label": "subtitle", "placeholder": "" } + }, + "background": { + "type": "Text", + "config": { "label": "background", "placeholder": "hex" } + }, + "is_for_logged_in_users": { + "type": "Boolean", + "config": { + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false + } + } + }, + "items": { + "popular_searches": { + "type": "Text", + "config": { + "label": "Popular Searches", + "placeholder": "Tecnology pills at the bottom" + } + } + } + } + ] +} diff --git a/slices/SearchBar/screenshot-default.png b/slices/SearchBar/screenshot-default.png new file mode 100644 index 0000000000000000000000000000000000000000..a4a2063b5cf3aad7e628648b71996f73398d67f5 GIT binary patch literal 33362 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 ( id={slice?.primary?.id_key} technologies={slice?.primary?.technologies} margin={slice?.primary?.margin || '15px 0 0 0'} + background={slice.primary.background} + paddingTop={slice.primary.padding_top} /> ); diff --git a/slices/TechnologiesPills/mocks.json b/slices/TechnologiesPills/mocks.json index 9e0ae06b2..682b85985 100644 --- a/slices/TechnologiesPills/mocks.json +++ b/slices/TechnologiesPills/mocks.json @@ -1,48 +1,62 @@ [ - { - "__TYPE__": "SharedSliceContent", - "variation": "default", - "primary": { - "id_key": { - "__TYPE__": "FieldContent", - "value": "worry", - "type": "Text" - }, - "technologies": { - "__TYPE__": "StructuredTextContent", - "value": [ - { - "type": "list-item", - "content": { - "text": "Javascript", - "spans": [] - }, - "direction": "ltr" - }, - { - "type": "list-item", - "content": { - "text": "Python", - "spans": [] - }, - "direction": "ltr" - }, - { - "type": "list-item", - "content": { - "text": "Django", - "spans": [] - }, - "direction": "ltr" - } - ] - } - }, - "items": [ - { - "__TYPE__": "GroupItemContent", - "value": [] - } - ] - } + { + "__TYPE__": "SharedSliceContent", + "variation": "default", + "primary": { + "id_key": { + "__TYPE__": "FieldContent", + "value": "worry", + "type": "Text" + }, + "technologies": { + "__TYPE__": "StructuredTextContent", + "value": [ + { + "type": "list-item", + "content": { + "text": "Javascript", + "spans": [] + }, + "direction": "ltr" + }, + { + "type": "list-item", + "content": { + "text": "Python", + "spans": [] + }, + "direction": "ltr" + }, + { + "type": "list-item", + "content": { + "text": "Django", + "spans": [] + }, + "direction": "ltr" + } + ] + }, + "background": { + "__TYPE__": "FieldContent", + "value": "theory", + "type": "Text" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": true + }, + "padding_top": { + "__TYPE__": "FieldContent", + "value": "keep", + "type": "Text" + } + }, + "items": [ + { + "__TYPE__": "GroupItemContent", + "value": [] + } + ] + } ] \ No newline at end of file diff --git a/slices/TechnologiesPills/model.json b/slices/TechnologiesPills/model.json index 425acced4..af2a9f9d4 100644 --- a/slices/TechnologiesPills/model.json +++ b/slices/TechnologiesPills/model.json @@ -13,10 +13,7 @@ "primary": { "id_key": { "type": "Text", - "config": { - "label": "id", - "placeholder": "" - } + "config": { "label": "id", "placeholder": "" } }, "technologies": { "type": "StructuredText", @@ -29,14 +26,28 @@ }, "margin": { "type": "Text", + "config": { "label": "margin", "placeholder": "" } + }, + "background": { + "type": "Text", + "config": { "label": "background", "placeholder": "" } + }, + "is_for_logged_in_users": { + "type": "Boolean", "config": { - "label": "margin", - "placeholder": "" + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false } + }, + "padding_top": { + "type": "Text", + "config": { "label": "padding top", "placeholder": "" } } }, "items": {}, "imageUrl": "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format" } ] -} \ No newline at end of file +} diff --git a/slices/TitleIntroduction/mocks.json b/slices/TitleIntroduction/mocks.json index b8e3d946e..003b10499 100644 --- a/slices/TitleIntroduction/mocks.json +++ b/slices/TitleIntroduction/mocks.json @@ -120,6 +120,10 @@ "__TYPE__": "FieldContent", "value": "whose", "type": "Text" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": false } }, "items": [ diff --git a/slices/TitleIntroduction/model.json b/slices/TitleIntroduction/model.json index 2e8e89645..96e62fcc4 100644 --- a/slices/TitleIntroduction/model.json +++ b/slices/TitleIntroduction/model.json @@ -113,6 +113,15 @@ "button_id": { "type": "Text", "config": { "label": "Button Id", "placeholder": "" } + }, + "is_for_logged_in_users": { + "type": "Boolean", + "config": { + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false + } } }, "items": {}, diff --git a/slices/TwoColumn/mocks.json b/slices/TwoColumn/mocks.json index 1dd64e7c0..7ef6249c9 100644 --- a/slices/TwoColumn/mocks.json +++ b/slices/TwoColumn/mocks.json @@ -135,6 +135,10 @@ "__TYPE__": "FieldContent", "value": "Lato", "type": "Select" + }, + "is_for_logged_in_users": { + "__TYPE__": "BooleanContent", + "value": false } }, "items": [ diff --git a/slices/TwoColumn/model.json b/slices/TwoColumn/model.json index 8d4d7aba3..fffdb6250 100644 --- a/slices/TwoColumn/model.json +++ b/slices/TwoColumn/model.json @@ -131,6 +131,15 @@ "options": ["Lato", "Space Grotesk Variable"], "default_value": "Lato" } + }, + "is_for_logged_in_users": { + "type": "Boolean", + "config": { + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false + } } }, "items": {}, diff --git a/slices/index.js b/slices/index.js index 5e212ca4a..3713d1609 100644 --- a/slices/index.js +++ b/slices/index.js @@ -10,6 +10,7 @@ export const components = { partners: dynamic(() => import("./Partners")), recommended_courses: dynamic(() => import("./RecommendedCourses")), road_map: dynamic(() => import("./RoadMap")), + search_bar: dynamic(() => import("./SearchBar")), show_prices: dynamic(() => import("./ShowPrices")), technologies: dynamic(() => import("./Technologies")), technologies_pills: dynamic(() => import("./TechnologiesPills")), diff --git a/src/common/components/MktEventCards.jsx b/src/common/components/MktEventCards.jsx index 9814fbf8f..677c20fc3 100644 --- a/src/common/components/MktEventCards.jsx +++ b/src/common/components/MktEventCards.jsx @@ -7,17 +7,19 @@ import GridContainer from './GridContainer'; import Heading from './Heading'; import Icon from './Icon'; import axios from '../../axios'; -import { sortToNearestTodayDate } from '../../utils'; +import { sortToNearestTodayDate, getQueryString } from '../../utils'; import DraggableContainer from './DraggableContainer'; import DynamicContentCard from './DynamicContentCard'; import { WHITE_LABEL_ACADEMY, BREATHECODE_HOST } from '../../utils/variables'; import { parseQuerys } from '../../utils/url'; -function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, hoursToLimit, endpoint, ...rest }) { - const [events, setEvents] = useState([]); +function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, hoursToLimit, endpoint, techFilter, searchSensitive, ...rest }) { + const [originalEvents, setOriginalEvents] = useState([]); + const [filteredEvents, setFilteredEvents] = useState([]); const { fontColor } = useStyle(); const router = useRouter(); const lang = router.locale; + const search = getQueryString('search'); const qsConnector = parseQuerys({ featured: true, academy: WHITE_LABEL_ACADEMY, @@ -30,27 +32,55 @@ function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, ho const maxEvents = 10; useEffect(() => { - if (externalEvents) { - setEvents(externalEvents); - } else { - axios.get(`${BREATHECODE_HOST}${endpointDefault}`) - .then((res) => { - const data = res?.data; - if (data && data.length > 0) { - const englishLang = lang === 'en' && 'us'; - const sortDateToLiveClass = sortToNearestTodayDate(data, hoursLimited); - const existentLiveClasses = sortDateToLiveClass?.filter((l) => l?.starting_at && (l?.ended_at || l?.ending_at) && l?.slug); - const isMoreThanAnyEvents = existentLiveClasses?.length > maxEvents; - const filteredByLang = existentLiveClasses?.filter((l) => l?.lang === englishLang || l?.lang === lang); - - const eventsFiltered = isMoreThanAnyEvents ? filteredByLang : existentLiveClasses; - setEvents(eventsFiltered); - } - }); + const fetchEvents = async () => { + try { + if (externalEvents) { + setOriginalEvents(externalEvents); + setFilteredEvents(externalEvents); + return; + } + const res = await axios.get(`${BREATHECODE_HOST}${endpointDefault}`); + const data = res?.data; + + if (data && data.length > 0) { + const englishLang = lang === 'en' && 'us'; + const sortDateToLiveClass = sortToNearestTodayDate(data, hoursLimited); + const existentLiveClasses = sortDateToLiveClass?.filter((l) => l?.starting_at && (l?.ended_at || l?.ending_at) && l?.slug); + const isMoreThanAnyEvents = existentLiveClasses?.length > maxEvents; + const filteredByLang = existentLiveClasses?.filter((l) => l?.lang === englishLang || l?.lang === lang); + + const eventsFilteredByLang = isMoreThanAnyEvents ? filteredByLang : existentLiveClasses; + + const eventsFilteredByTech = techFilter ? eventsFilteredByLang.filter((event) => event?.event_type?.technologies?.split(',').includes(techFilter.toLowerCase())) : eventsFilteredByLang; + console.log('filtro de', techFilter, eventsFilteredByTech); + + setOriginalEvents(eventsFilteredByTech); + setFilteredEvents(eventsFilteredByTech); + return; + } + } catch (error) { + console.error('Error fetching events:', error); + } + }; + + fetchEvents(); + }, [externalEvents, techFilter]); + + useEffect(() => { + if (!searchSensitive || techFilter) return; + + if (!search) { + setFilteredEvents(originalEvents); + return; } - }, [externalEvents]); - return events?.length > 0 && ( + const filteredBySearch = originalEvents.filter((event) => event?.title?.toLowerCase().includes(search.toLowerCase()) + || event?.event_type?.technologies?.includes(search.toLowerCase())); + + setFilteredEvents(filteredBySearch); + }, [search, searchSensitive, originalEvents]); + + return filteredEvents?.length > 0 && ( <> - {events.map((event) => ( + {filteredEvents.map((event) => ( { + const currentQuery = new URLSearchParams(router.query); + Object.entries(newParams).forEach(([key, value]) => { + if (value) { + currentQuery.set(key, value); + } else { + currentQuery.delete(key); + } + }); + + const queryString = currentQuery.toString(); + router.replace(`${router.pathname}?${queryString}`, undefined, { shallow: true }); + }; + + const handleInputChange = (e) => { + const { value } = e.target; + setSearch(value); + + updateQueryParams({ search: value }); + }; + + const handleSearchSubmit = (e) => { + e.preventDefault(); + updateQueryParams({ search }); + }; + + const handlePopularSearchClick = (term) => { + setSearch(term); + updateQueryParams({ search: term }); + }; + + return ( + + + + {headingTop} +
+ {headingBottom} +
+ + {subtitle} + + +
+ + + + + +
+ + + Popular searches: + + + {popularSearches.map((term) => ( + + ))} + + +
+
+
+ ); +} + +MktSearchBar.propTypes = { + headingTop: PropTypes.string.isRequired, + headingBottom: PropTypes.string.isRequired, + subtitle: PropTypes.string.isRequired, + popularSearches: PropTypes.arrayOf(PropTypes.string).isRequired, + background: PropTypes.string, + id: PropTypes.string, +}; + +MktSearchBar.defaultProps = { + background: 'auto', + id: '', +}; + +export default MktSearchBar; diff --git a/src/common/components/MktTechnologiesPills.jsx b/src/common/components/MktTechnologiesPills.jsx index 91b03a8c3..d2435959a 100644 --- a/src/common/components/MktTechnologiesPills.jsx +++ b/src/common/components/MktTechnologiesPills.jsx @@ -2,12 +2,12 @@ import { useState, useRef } from 'react'; import PropTypes from 'prop-types'; import { - Container, Box, + Container, Box, useColorModeValue, } from '@chakra-ui/react'; import Text from './Text'; import CustomTheme from '../../../styles/theme'; -function MktTechnologiesPills({ id, technologies, ...rest }) { +function MktTechnologiesPills({ id, technologies, background, ...rest }) { const ref = useRef(); const [isDown, setIsDown] = useState(false); const [startX, setStartX] = useState(0); @@ -46,12 +46,14 @@ function MktTechnologiesPills({ id, technologies, ...rest }) { }; return ( - + { + const isForLoggedInUsers = slice.primary?.is_for_logged_in_users || false; + if (isForLoggedInUsers === undefined) return true; + return isAuthenticated ? isForLoggedInUsers : !isForLoggedInUsers; + }); useEffect(() => { + console.log('SOY LOS PRIMEROS SLICES', page.data.slices); + if (!page?.id) { window.location.href = '/404'; } @@ -27,6 +37,8 @@ function Page({ page }) { } }, []); + console.log(page.data.slices); + const tryRigobot = () => { rigo.updateOptions({ showBubble: true, @@ -69,8 +81,8 @@ function Page({ page }) { )} - - + + ); diff --git a/src/pages/index.jsx b/src/pages/index.jsx index df3a300b5..5a76119a7 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -24,6 +24,7 @@ function Page({ page }) { router.push('/login'); } }, []); + return prismicRef && prismicApi && ( From 35d633d07c9e4135decbe04a24867880f2098605 Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Mon, 6 Jan 2025 14:30:27 -0400 Subject: [PATCH 02/11] adding checkInEvents --- prismicio-types.d.ts | 55 +++++++++++++++---------- slices/EventCards/index.jsx | 1 + slices/EventCards/mocks.json | 4 ++ slices/EventCards/model.json | 29 ++++++++----- slices/TechnologiesPills/model.json | 8 ++-- src/common/components/MktEventCards.jsx | 48 ++++++++++++++++++--- 6 files changed, 104 insertions(+), 41 deletions(-) diff --git a/prismicio-types.d.ts b/prismicio-types.d.ts index cf8ea5cec..55bff2145 100644 --- a/prismicio-types.d.ts +++ b/prismicio-types.d.ts @@ -152,36 +152,47 @@ export interface EventCardsSliceDefaultPrimary { margin: prismic.KeyTextField; /** - * Is for logged in users only field in *EventCards → Primary* + * Tech Filtered field in *EventCards → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: Auto filter the events by a technology + * - **API ID Path**: event_cards.primary.tech_filtered + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + tech_filtered: prismic.KeyTextField; + + /** + * Search Sensitive field in *EventCards → Primary* * * - **Field Type**: Boolean * - **Placeholder**: *None* * - **Default Value**: false - * - **API ID Path**: event_cards.primary.is_for_logged_in_users + * - **API ID Path**: event_cards.primary.search_sensitive * - **Documentation**: https://prismic.io/docs/field#boolean */ - is_for_logged_in_users: prismic.BooleanField; + search_sensitive: prismic.BooleanField; /** - * Search Sensitive field in *EventCards → Primary* + * Show checked in events field in *EventCards → Primary* * * - **Field Type**: Boolean * - **Placeholder**: *None* * - **Default Value**: false - * - **API ID Path**: event_cards.primary.search_sensitive + * - **API ID Path**: event_cards.primary.show_checked_in_events * - **Documentation**: https://prismic.io/docs/field#boolean */ - search_sensitive: prismic.BooleanField; + show_checked_in_events: prismic.BooleanField; /** - * Tech Filtered field in *EventCards → Primary* + * Is for logged in users only field in *EventCards → Primary* * - * - **Field Type**: Text - * - **Placeholder**: Auto filter the events by a technology - * - **API ID Path**: event_cards.primary.tech_filtered - * - **Documentation**: https://prismic.io/docs/field#key-text + * - **Field Type**: Boolean + * - **Placeholder**: *None* + * - **Default Value**: false + * - **API ID Path**: event_cards.primary.is_for_logged_in_users + * - **Documentation**: https://prismic.io/docs/field#boolean */ - tech_filtered: prismic.KeyTextField; + is_for_logged_in_users: prismic.BooleanField; } /** @@ -1374,6 +1385,16 @@ export interface TechnologiesPillsSliceDefaultPrimary { */ background: prismic.KeyTextField; + /** + * padding top field in *TechnologiesPills → Primary* + * + * - **Field Type**: Text + * - **Placeholder**: *None* + * - **API ID Path**: technologies_pills.primary.padding_top + * - **Documentation**: https://prismic.io/docs/field#key-text + */ + padding_top: prismic.KeyTextField; + /** * Is for logged in users only field in *TechnologiesPills → Primary* * @@ -1384,16 +1405,6 @@ export interface TechnologiesPillsSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#boolean */ is_for_logged_in_users: prismic.BooleanField; - - /** - * padding top field in *TechnologiesPills → Primary* - * - * - **Field Type**: Text - * - **Placeholder**: *None* - * - **API ID Path**: technologies_pills.primary.padding_top - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - padding_top: prismic.KeyTextField; } /** diff --git a/slices/EventCards/index.jsx b/slices/EventCards/index.jsx index 936e3cdfa..744455643 100644 --- a/slices/EventCards/index.jsx +++ b/slices/EventCards/index.jsx @@ -14,6 +14,7 @@ const EventCards = ({ slice }) => ( endpoint={slice?.primary?.endpoint} techFilter={slice?.primary?.tech_filtered} searchSensitive={slice?.primary?.search_sensitive} + showCheckedInEvents={slice?.primary?.show_checked_in_events} margin={slice?.primary?.margin || '40px auto'} /> ); diff --git a/slices/EventCards/mocks.json b/slices/EventCards/mocks.json index c5a7b25e0..c2c14030a 100644 --- a/slices/EventCards/mocks.json +++ b/slices/EventCards/mocks.json @@ -35,6 +35,10 @@ "__TYPE__": "FieldContent", "value": "swam", "type": "Text" + }, + "show_checked_in_events": { + "__TYPE__": "BooleanContent", + "value": true } }, "items": [ diff --git a/slices/EventCards/model.json b/slices/EventCards/model.json index 23fc745f2..93299e278 100644 --- a/slices/EventCards/model.json +++ b/slices/EventCards/model.json @@ -30,13 +30,11 @@ "placeholder": "top, right, bottom, left" } }, - "is_for_logged_in_users": { - "type": "Boolean", + "tech_filtered": { + "type": "Text", "config": { - "label": "Is for logged in users only", - "placeholder_false": "false", - "placeholder_true": "true", - "default_value": false + "label": "Tech Filtered", + "placeholder": "Auto filter the events by a technology" } }, "search_sensitive": { @@ -48,11 +46,22 @@ "default_value": false } }, - "tech_filtered": { - "type": "Text", + "show_checked_in_events": { + "type": "Boolean", "config": { - "label": "Tech Filtered", - "placeholder": "Auto filter the events by a technology" + "label": "Show checked in events", + "default_value": false, + "placeholder_true": "true", + "placeholder_false": "false" + } + }, + "is_for_logged_in_users": { + "type": "Boolean", + "config": { + "label": "Is for logged in users only", + "placeholder_false": "false", + "placeholder_true": "true", + "default_value": false } } }, diff --git a/slices/TechnologiesPills/model.json b/slices/TechnologiesPills/model.json index af2a9f9d4..cf8c2b513 100644 --- a/slices/TechnologiesPills/model.json +++ b/slices/TechnologiesPills/model.json @@ -32,6 +32,10 @@ "type": "Text", "config": { "label": "background", "placeholder": "" } }, + "padding_top": { + "type": "Text", + "config": { "label": "padding top", "placeholder": "" } + }, "is_for_logged_in_users": { "type": "Boolean", "config": { @@ -40,10 +44,6 @@ "placeholder_true": "true", "default_value": false } - }, - "padding_top": { - "type": "Text", - "config": { "label": "padding top", "placeholder": "" } } }, "items": {}, diff --git a/src/common/components/MktEventCards.jsx b/src/common/components/MktEventCards.jsx index 677c20fc3..c8a72e30f 100644 --- a/src/common/components/MktEventCards.jsx +++ b/src/common/components/MktEventCards.jsx @@ -11,11 +11,26 @@ import { sortToNearestTodayDate, getQueryString } from '../../utils'; import DraggableContainer from './DraggableContainer'; import DynamicContentCard from './DynamicContentCard'; import { WHITE_LABEL_ACADEMY, BREATHECODE_HOST } from '../../utils/variables'; +import useAuth from '../hooks/useAuth'; import { parseQuerys } from '../../utils/url'; -function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, hoursToLimit, endpoint, techFilter, searchSensitive, ...rest }) { +function MktEventCards({ + isSmall, + externalEvents, + hideDescription, + id, + title, + hoursToLimit, + endpoint, + techFilter, + searchSensitive, + showCheckedInEvents, + ...rest +}) { const [originalEvents, setOriginalEvents] = useState([]); const [filteredEvents, setFilteredEvents] = useState([]); + const [checkedInEvents, setCheckedInEvents] = useState([]); + const { user } = useAuth(); const { fontColor } = useStyle(); const router = useRouter(); const lang = router.locale; @@ -31,6 +46,22 @@ function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, ho const endpointDefault = `${choosenEndpoint}${qsConnector}`; const maxEvents = 10; + const fetchCheckedInEvents = async (eventsArray) => { + try { + const checkedIn = await Promise.all( + eventsArray.map(async (event) => { + const res = await axios.get(`${BREATHECODE_HOST}/v1/events/event/${event.id}/checkin`); + const reservations = res?.data || []; + const isUserAttendee = reservations.find((reservation) => reservation?.attendee?.id === user.id); + return isUserAttendee ? event : null; + }), + ); + setCheckedInEvents(checkedIn.filter(Boolean)); + } catch (error) { + console.error('Error fetching checked-in events:', error); + } + }; + useEffect(() => { const fetchEvents = async () => { try { @@ -52,11 +83,14 @@ function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, ho const eventsFilteredByLang = isMoreThanAnyEvents ? filteredByLang : existentLiveClasses; const eventsFilteredByTech = techFilter ? eventsFilteredByLang.filter((event) => event?.event_type?.technologies?.split(',').includes(techFilter.toLowerCase())) : eventsFilteredByLang; - console.log('filtro de', techFilter, eventsFilteredByTech); + + if (showCheckedInEvents && user?.id && eventsFilteredByTech.length > 0) { + fetchCheckedInEvents(eventsFilteredByTech); + return; + } setOriginalEvents(eventsFilteredByTech); setFilteredEvents(eventsFilteredByTech); - return; } } catch (error) { console.error('Error fetching events:', error); @@ -80,7 +114,9 @@ function MktEventCards({ isSmall, externalEvents, hideDescription, id, title, ho setFilteredEvents(filteredBySearch); }, [search, searchSensitive, originalEvents]); - return filteredEvents?.length > 0 && ( + const eventsToDisplay = showCheckedInEvents ? checkedInEvents : filteredEvents; + + return eventsToDisplay?.length > 0 && ( <> - {filteredEvents.map((event) => ( + {eventsToDisplay.map((event) => ( Date: Mon, 6 Jan 2025 14:38:18 -0400 Subject: [PATCH 03/11] remove logs --- src/pages/[uid]/index.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pages/[uid]/index.jsx b/src/pages/[uid]/index.jsx index f736aec21..8a91a06af 100644 --- a/src/pages/[uid]/index.jsx +++ b/src/pages/[uid]/index.jsx @@ -27,8 +27,6 @@ function Page({ page }) { }); useEffect(() => { - console.log('SOY LOS PRIMEROS SLICES', page.data.slices); - if (!page?.id) { window.location.href = '/404'; } @@ -37,8 +35,6 @@ function Page({ page }) { } }, []); - console.log(page.data.slices); - const tryRigobot = () => { rigo.updateOptions({ showBubble: true, From cc7024c440008afe8c8fc3b344b87f9b16226c50 Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Wed, 8 Jan 2025 12:14:47 -0400 Subject: [PATCH 04/11] applying changes to do the landing of workshops --- customtypes/page/index.json | 1 - i18n.js | 1 + prismicio-types.d.ts | 184 ------------------ public/locales/en/workshops.json | 6 + public/locales/es/workshops.json | 12 +- slices/EventCards/mocks.json | 8 - slices/EventCards/model.json | 18 -- slices/Markdown/mocks.json | 4 - slices/Markdown/model.json | 9 - slices/SearchBar/index.js | 30 --- slices/SearchBar/mocks.json | 47 ----- slices/SearchBar/model.json | 52 ----- slices/SearchBar/screenshot-default.png | Bin 33362 -> 0 bytes slices/Technologies/mocks.json | 4 - slices/Technologies/model.json | 9 - slices/TechnologiesPills/mocks.json | 4 - slices/TechnologiesPills/model.json | 9 - slices/TitleIntroduction/mocks.json | 4 - slices/TitleIntroduction/model.json | 9 - slices/TwoColumn/mocks.json | 4 - slices/TwoColumn/model.json | 9 - slices/index.js | 1 - src/common/components/MktSearchBar.jsx | 46 +++-- .../components/WorkshopsLoggedLanding.jsx | 23 +++ src/pages/[uid]/index.jsx | 24 +-- 25 files changed, 78 insertions(+), 440 deletions(-) delete mode 100644 slices/SearchBar/index.js delete mode 100644 slices/SearchBar/mocks.json delete mode 100644 slices/SearchBar/model.json delete mode 100644 slices/SearchBar/screenshot-default.png create mode 100644 src/common/components/WorkshopsLoggedLanding.jsx diff --git a/customtypes/page/index.json b/customtypes/page/index.json index 077339000..4d1264756 100644 --- a/customtypes/page/index.json +++ b/customtypes/page/index.json @@ -38,7 +38,6 @@ "fieldset": "Slice Zone", "config": { "choices": { - "search_bar": { "type": "SharedSlice" }, "info_cards": { "type": "SharedSlice" }, "trust_cards": { "type": "SharedSlice" }, "title_introduction": { "type": "SharedSlice" }, diff --git a/i18n.js b/i18n.js index baba9084f..d95f6c551 100644 --- a/i18n.js +++ b/i18n.js @@ -32,6 +32,7 @@ module.exports = { '/profile': ['profile'], '/profile/[slug]': ['profile'], '/thank-you': ['thank-you'], + '/workshops': ['workshops'], '/workshops/[event_slug]': ['workshops', 'signup'], '/join/cohort/[id]': ['dashboard', 'signup'], '/podcast': ['podcast'], diff --git a/prismicio-types.d.ts b/prismicio-types.d.ts index 55bff2145..1bc2d34b6 100644 --- a/prismicio-types.d.ts +++ b/prismicio-types.d.ts @@ -6,7 +6,6 @@ import type * as prismicClient from "@prismicio/client"; type Simplify = { [KeyType in keyof T]: T[KeyType] }; type PageDocumentDataSlicesSlice = - | SearchBarSlice | InfoCardsSlice | TrustCardsSlice | TitleIntroductionSlice @@ -161,17 +160,6 @@ export interface EventCardsSliceDefaultPrimary { */ tech_filtered: prismic.KeyTextField; - /** - * Search Sensitive field in *EventCards → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: event_cards.primary.search_sensitive - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - search_sensitive: prismic.BooleanField; - /** * Show checked in events field in *EventCards → Primary* * @@ -182,17 +170,6 @@ export interface EventCardsSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#boolean */ show_checked_in_events: prismic.BooleanField; - - /** - * Is for logged in users only field in *EventCards → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: event_cards.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -555,17 +532,6 @@ export interface MarkdownSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ padding: prismic.KeyTextField; - - /** - * Is for logged in users only field in *Markdown → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: markdown.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -1069,107 +1035,6 @@ export type RoadMapSlice = prismic.SharedSlice< RoadMapSliceVariation >; -/** - * Primary content in *SearchBar → Primary* - */ -export interface SearchBarSliceDefaultPrimary { - /** - * heading top field in *SearchBar → Primary* - * - * - **Field Type**: Text - * - **Placeholder**: *None* - * - **API ID Path**: search_bar.primary.heading_top - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - heading_top: prismic.KeyTextField; - - /** - * heading bottom field in *SearchBar → Primary* - * - * - **Field Type**: Text - * - **Placeholder**: *None* - * - **API ID Path**: search_bar.primary.heading_bottom - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - heading_bottom: prismic.KeyTextField; - - /** - * subtitle field in *SearchBar → Primary* - * - * - **Field Type**: Text - * - **Placeholder**: *None* - * - **API ID Path**: search_bar.primary.subtitle - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - subtitle: prismic.KeyTextField; - - /** - * background field in *SearchBar → Primary* - * - * - **Field Type**: Text - * - **Placeholder**: hex - * - **API ID Path**: search_bar.primary.background - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - background: prismic.KeyTextField; - - /** - * Is for logged in users only field in *SearchBar → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: search_bar.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; -} - -/** - * Primary content in *SearchBar → Items* - */ -export interface SearchBarSliceDefaultItem { - /** - * Popular Searches field in *SearchBar → Items* - * - * - **Field Type**: Text - * - **Placeholder**: Tecnology pills at the bottom - * - **API ID Path**: search_bar.items[].popular_searches - * - **Documentation**: https://prismic.io/docs/field#key-text - */ - popular_searches: prismic.KeyTextField; -} - -/** - * Default variation for SearchBar Slice - * - * - **API ID**: `default` - * - **Description**: Default - * - **Documentation**: https://prismic.io/docs/slice - */ -export type SearchBarSliceDefault = prismic.SharedSliceVariation< - "default", - Simplify, - Simplify ->; - -/** - * Slice variation for *SearchBar* - */ -type SearchBarSliceVariation = SearchBarSliceDefault; - -/** - * SearchBar Shared Slice - * - * - **API ID**: `search_bar` - * - **Description**: SearchBar - * - **Documentation**: https://prismic.io/docs/slice - */ -export type SearchBarSlice = prismic.SharedSlice< - "search_bar", - SearchBarSliceVariation ->; - /** * Primary content in *ShowPrices → Primary* */ @@ -1298,17 +1163,6 @@ export interface TechnologiesSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ margin: prismic.KeyTextField; - - /** - * Is for logged in users only field in *Technologies → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: technologies.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -1394,17 +1248,6 @@ export interface TechnologiesPillsSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ padding_top: prismic.KeyTextField; - - /** - * Is for logged in users only field in *TechnologiesPills → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: technologies_pills.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -1658,17 +1501,6 @@ export interface TitleIntroductionSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#key-text */ button_id: prismic.KeyTextField; - - /** - * Is for logged in users only field in *TitleIntroduction → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: title_introduction.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -1991,17 +1823,6 @@ export interface TwoColumnSliceDefaultPrimary { * - **Documentation**: https://prismic.io/docs/field#select */ fontFamily: prismic.SelectField<"Lato" | "Space Grotesk Variable", "filled">; - - /** - * Is for logged in users only field in *TwoColumn → Primary* - * - * - **Field Type**: Boolean - * - **Placeholder**: *None* - * - **Default Value**: false - * - **API ID Path**: two_column.primary.is_for_logged_in_users - * - **Documentation**: https://prismic.io/docs/field#boolean - */ - is_for_logged_in_users: prismic.BooleanField; } /** @@ -2076,11 +1897,6 @@ declare module "@prismicio/client" { RoadMapSliceDefaultPrimary, RoadMapSliceVariation, RoadMapSliceDefault, - SearchBarSlice, - SearchBarSliceDefaultPrimary, - SearchBarSliceDefaultItem, - SearchBarSliceVariation, - SearchBarSliceDefault, ShowPricesSlice, ShowPricesSliceDefaultPrimary, ShowPricesSliceVariation, diff --git a/public/locales/en/workshops.json b/public/locales/en/workshops.json index 7960726b3..d2f02d6c1 100644 --- a/public/locales/en/workshops.json +++ b/public/locales/en/workshops.json @@ -19,6 +19,11 @@ "button": "You don't have access to this event", "can-join": "can join" }, + "intro": { + "top-title": "Welcome to workshops", + "lower-title": "Learn live, dive into tech skills", + "subtitle": "Discover the future of code technology learning with live sessions! Join now to boost your skills." + }, "form": { "title": "Join this event", "description": "Sign in to join other coders live solving technical or career challenges.", @@ -31,6 +36,7 @@ "finished-title": "This event has ended", "finished-description": "Keep looking for new learning experiences and keep your passion for knowledge alive!" }, + "upcoming-events": "Upcoming events", "users-registered-count": "{{count}} people are already registered in this event. {{spot_count}} more spots available", "join-workshop": "Register for this Workshop", "join": "Join Now", diff --git a/public/locales/es/workshops.json b/public/locales/es/workshops.json index 1c8ccb3a3..ca65e5c7d 100644 --- a/public/locales/es/workshops.json +++ b/public/locales/es/workshops.json @@ -13,12 +13,17 @@ "in-person": "Evento en persona", "in-person-confirm": "Este es un evento presencial que se llevará a cabo en {{address}}. ¿Aún quieres confirmar tu asistencia?", "confirm-attendance": "Si, si asistiré", - "deny-attendance" : "No, no asistiré", - "denny-access":{ + "deny-attendance": "No, no asistiré", + "denny-access": { "description": "Esto es un evento privado, solo estudiantes con acceso a", "button": "No tienes acceso a este evento.", "can-join": "pueden entrar" }, + "intro": { + "top-title": "Bienvenido a los talleres", + "lower-title": "Aprende en vivo y sumergete en las nuevas tecnologías", + "subtitle": "Descubre el futuro del aprendizaje tecnológico con sesiones en vivo. ¡Únete y potencia tus habilidades!" + }, "form": { "title": "Únete a este evento", "description": "Inicia sesión para unirte a otros programadores en vivo resolviendo desafíos técnicos o profesionales.", @@ -31,6 +36,7 @@ "finished-title": "Este evento ha finalizado", "finished-description": "¡Sigue buscando nuevas experiencias de aprendizaje y mantén viva tu pasión por el conocimiento!" }, + "upcoming-events": "Próximos eventos", "users-registered-count": "{{count}} personas ya se han registrado a este evento. Quedan disponibles {{spot_count}} cupos más.", "join-workshop": "Regístrarse al taller", "join": "Unirse ahora", @@ -54,4 +60,4 @@ "get-more-workshops": "Obten más workshops" }, "back-to-workshops": "Regresar" -} +} \ No newline at end of file diff --git a/slices/EventCards/mocks.json b/slices/EventCards/mocks.json index c2c14030a..9cc207710 100644 --- a/slices/EventCards/mocks.json +++ b/slices/EventCards/mocks.json @@ -23,14 +23,6 @@ "value": "continent", "type": "Text" }, - "is_for_logged_in_users": { - "__TYPE__": "BooleanContent", - "value": false - }, - "search_sensitive": { - "__TYPE__": "BooleanContent", - "value": false - }, "tech_filtered": { "__TYPE__": "FieldContent", "value": "swam", diff --git a/slices/EventCards/model.json b/slices/EventCards/model.json index 93299e278..1192d782c 100644 --- a/slices/EventCards/model.json +++ b/slices/EventCards/model.json @@ -37,15 +37,6 @@ "placeholder": "Auto filter the events by a technology" } }, - "search_sensitive": { - "type": "Boolean", - "config": { - "label": "Search Sensitive", - "placeholder_false": "false", - "placeholder_true": "true", - "default_value": false - } - }, "show_checked_in_events": { "type": "Boolean", "config": { @@ -54,15 +45,6 @@ "placeholder_true": "true", "placeholder_false": "false" } - }, - "is_for_logged_in_users": { - "type": "Boolean", - "config": { - "label": "Is for logged in users only", - "placeholder_false": "false", - "placeholder_true": "true", - "default_value": false - } } }, "items": {}, diff --git a/slices/Markdown/mocks.json b/slices/Markdown/mocks.json index 8fefd9cae..02d42bc1e 100644 --- a/slices/Markdown/mocks.json +++ b/slices/Markdown/mocks.json @@ -42,10 +42,6 @@ "__TYPE__": "FieldContent", "value": "won", "type": "Text" - }, - "is_for_logged_in_users": { - "__TYPE__": "BooleanContent", - "value": false } }, "items": [ diff --git a/slices/Markdown/model.json b/slices/Markdown/model.json index 8d4928c84..83c09e754 100644 --- a/slices/Markdown/model.json +++ b/slices/Markdown/model.json @@ -51,15 +51,6 @@ "padding": { "type": "Text", "config": { "label": "Padding", "placeholder": "" } - }, - "is_for_logged_in_users": { - "type": "Boolean", - "config": { - "label": "Is for logged in users only", - "placeholder_false": "false", - "placeholder_true": "true", - "default_value": false - } } }, "items": {}, diff --git a/slices/SearchBar/index.js b/slices/SearchBar/index.js deleted file mode 100644 index 86db0f5be..000000000 --- a/slices/SearchBar/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import MktSearchBar from '../../src/common/components/MktSearchBar'; - -/** - * @typedef {import("@prismicio/client").Content.SearchBarSlice} SearchBarSlice - * @typedef {import("@prismicio/react").SliceComponentProps} SearchBarProps - * @param {SearchBarProps} - */ - -const SearchBar = ({ slice }) => ( - -) - -SearchBar.propTypes = { - slice: PropTypes.objectOf(PropTypes.any), -}; - -SearchBar.defaultProps = { - slice: {}, -}; - -export default SearchBar; diff --git a/slices/SearchBar/mocks.json b/slices/SearchBar/mocks.json deleted file mode 100644 index aa022cca5..000000000 --- a/slices/SearchBar/mocks.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - { - "__TYPE__": "SharedSliceContent", - "variation": "default", - "primary": { - "heading_top": { - "__TYPE__": "FieldContent", - "value": "because", - "type": "Text" - }, - "heading_bottom": { - "__TYPE__": "FieldContent", - "value": "card", - "type": "Text" - }, - "subtitle": { - "__TYPE__": "FieldContent", - "value": "memory", - "type": "Text" - }, - "background": { - "__TYPE__": "FieldContent", - "value": "poem", - "type": "Text" - }, - "is_for_logged_in_users": { - "__TYPE__": "BooleanContent", - "value": false - } - }, - "items": [ - { - "__TYPE__": "GroupItemContent", - "value": [ - [ - "popular_searches", - { - "__TYPE__": "FieldContent", - "value": "one", - "type": "Text" - } - ] - ] - } - ] - } -] \ No newline at end of file diff --git a/slices/SearchBar/model.json b/slices/SearchBar/model.json deleted file mode 100644 index e525aa44f..000000000 --- a/slices/SearchBar/model.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "id": "search_bar", - "type": "SharedSlice", - "name": "SearchBar", - "description": "SearchBar", - "variations": [ - { - "id": "default", - "name": "Default", - "docURL": "...", - "version": "initial", - "description": "Default", - "imageUrl": "", - "primary": { - "heading_top": { - "type": "Text", - "config": { "label": "heading top", "placeholder": "" } - }, - "heading_bottom": { - "type": "Text", - "config": { "label": "heading bottom", "placeholder": "" } - }, - "subtitle": { - "type": "Text", - "config": { "label": "subtitle", "placeholder": "" } - }, - "background": { - "type": "Text", - "config": { "label": "background", "placeholder": "hex" } - }, - "is_for_logged_in_users": { - "type": "Boolean", - "config": { - "label": "Is for logged in users only", - "placeholder_false": "false", - "placeholder_true": "true", - "default_value": false - } - } - }, - "items": { - "popular_searches": { - "type": "Text", - "config": { - "label": "Popular Searches", - "placeholder": "Tecnology pills at the bottom" - } - } - } - } - ] -} diff --git a/slices/SearchBar/screenshot-default.png b/slices/SearchBar/screenshot-default.png deleted file mode 100644 index a4a2063b5cf3aad7e628648b71996f73398d67f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33362 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 import("./Partners")), recommended_courses: dynamic(() => import("./RecommendedCourses")), road_map: dynamic(() => import("./RoadMap")), - search_bar: dynamic(() => import("./SearchBar")), show_prices: dynamic(() => import("./ShowPrices")), technologies: dynamic(() => import("./Technologies")), technologies_pills: dynamic(() => import("./TechnologiesPills")), diff --git a/src/common/components/MktSearchBar.jsx b/src/common/components/MktSearchBar.jsx index 3598e0107..16de174c9 100644 --- a/src/common/components/MktSearchBar.jsx +++ b/src/common/components/MktSearchBar.jsx @@ -76,26 +76,32 @@ function MktSearchBar({ id, headingTop, headingBottom, subtitle, popularSearches - - Popular searches: - - - {popularSearches.map((term) => ( - - ))} - + {popularSearches && ( + <> + + Popular searches: + {' '} + {/*TRADUCIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR*/} + + + {popularSearches.map((term) => ( + + ))} + + + )} diff --git a/src/common/components/WorkshopsLoggedLanding.jsx b/src/common/components/WorkshopsLoggedLanding.jsx new file mode 100644 index 000000000..f28791e53 --- /dev/null +++ b/src/common/components/WorkshopsLoggedLanding.jsx @@ -0,0 +1,23 @@ +import useTranslation from 'next-translate/useTranslation'; +import MktEventCards from './MktEventCards'; +import MktSearchBar from './MktSearchBar'; +import MktTechnologiesPills from './MktTechnologiesPills'; +import MktTechnologies from './MktTechnologies'; + +function WorkshopsLoggedLanding() { + const { t } = useTranslation('workshops'); + + return ( + <> + + + + + + + + + ); +} + +export default WorkshopsLoggedLanding; diff --git a/src/pages/[uid]/index.jsx b/src/pages/[uid]/index.jsx index 8a91a06af..96d2760a6 100644 --- a/src/pages/[uid]/index.jsx +++ b/src/pages/[uid]/index.jsx @@ -3,6 +3,7 @@ import { SliceZone } from '@prismicio/react'; import * as prismicH from '@prismicio/helpers'; import { Box } from '@chakra-ui/react'; import PropTypes from 'prop-types'; +import { useRouter } from 'next/router'; import Head from 'next/head'; import useRigo from '../../common/hooks/useRigo'; @@ -12,19 +13,16 @@ import { cleanObject, isDevMode } from '../../utils'; import { ORIGIN_HOST } from '../../utils/variables'; import completions from './completion-jobs.json'; import useAuth from '../../common/hooks/useAuth'; +import WorkshopsLoggedLanding from '../../common/components/WorkshopsLoggedLanding'; const usedPageId = ['home']; function Page({ page }) { - const landingUrl = page?.data?.landing_url; + const router = useRouter(); const { isRigoInitialized, rigo } = useRigo(); - const { isAuthenticated } = useAuth(); - - const filteredSlices = page.data.slices.filter((slice) => { - const isForLoggedInUsers = slice.primary?.is_for_logged_in_users || false; - if (isForLoggedInUsers === undefined) return true; - return isAuthenticated ? isForLoggedInUsers : !isForLoggedInUsers; - }); + const { isAuthenticated, isLoading } = useAuth(); + const landingUrl = page?.data?.landing_url; + const loggedInWorkshopsView = isAuthenticated === true && router.query.uid === 'workshops'; useEffect(() => { if (!page?.id) { @@ -77,9 +75,13 @@ function Page({ page }) { )} - - - + {!loggedInWorkshopsView && !isLoading ? ( + + + + ) : ( + + )} ); } From 644de9e08151a41433f0f44b62b47fd2f80bde2c Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Mon, 13 Jan 2025 14:10:47 -0400 Subject: [PATCH 05/11] workshops landing when logged in --- i18n.js | 2 +- public/locales/en/common.json | 1 + public/locales/en/workshops.json | 6 + public/locales/es/common.json | 1 + public/locales/es/workshops.json | 6 + src/common/components/MktEventCards.jsx | 158 +++++++++++++----- src/common/components/MktSearchBar.jsx | 8 +- .../components/WorkshopsLoggedLanding.jsx | 20 ++- src/pages/[uid]/index.jsx | 6 +- 9 files changed, 156 insertions(+), 52 deletions(-) diff --git a/i18n.js b/i18n.js index d95f6c551..1aeea5bde 100644 --- a/i18n.js +++ b/i18n.js @@ -3,6 +3,7 @@ module.exports = { // Enable translations for the following pages '*': ['common', 'navbar', 'footer', 'alert-message', 'share', 'live-event', 'call-to-action', 'code-viewer', 'program-card', 'final-project', 'profile', 'login', 'signup'], '/': ['home', 'social'], + '/[uid]': ['workshops'], '/login': ['login', 'signup'], '/example': ['counter'], '/cohort/[cohortSlug]/[slug]/[version]': ['dashboard', 'choose-program', 'projects', 'profile', 'assignments'], @@ -32,7 +33,6 @@ module.exports = { '/profile': ['profile'], '/profile/[slug]': ['profile'], '/thank-you': ['thank-you'], - '/workshops': ['workshops'], '/workshops/[event_slug]': ['workshops', 'signup'], '/join/cohort/[id]': ['dashboard', 'signup'], '/podcast': ['podcast'], diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 5bc6668b9..a12674877 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -96,6 +96,7 @@ "email": "Email", "confirm-email": "Confirm email", "phone": "Phone", + "popular-searches": "Popular searches", "password": "Password", "confirm-password": "Confirm password", "difficulty": "Difficulty", diff --git a/public/locales/en/workshops.json b/public/locales/en/workshops.json index d2f02d6c1..6684fe715 100644 --- a/public/locales/en/workshops.json +++ b/public/locales/en/workshops.json @@ -36,7 +36,13 @@ "finished-title": "This event has ended", "finished-description": "Keep looking for new learning experiences and keep your passion for knowledge alive!" }, + "search-your-fav-tech": "Search your favourite technology", "upcoming-events": "Upcoming events", + "events-joined": "Events you have joined", + "tech-event": "{{tech}} events", + "searching-for": "Searching events with {{search}}", + "search-not-found": "{{search}} events not found", + "search-found": "Events found with search '{{search}}'", "users-registered-count": "{{count}} people are already registered in this event. {{spot_count}} more spots available", "join-workshop": "Register for this Workshop", "join": "Join Now", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index afa189727..778f1c5ea 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -93,6 +93,7 @@ "email": "Correo electrónico", "confirm-email": "Confirmar correo electrónico", "phone": "Teléfono", + "popular-searches": "Busquedas populares", "password": "Contraseña", "confirm-password": "Confirmar contraseña", "difficulty": "Dificultad", diff --git a/public/locales/es/workshops.json b/public/locales/es/workshops.json index ca65e5c7d..da4812512 100644 --- a/public/locales/es/workshops.json +++ b/public/locales/es/workshops.json @@ -36,7 +36,13 @@ "finished-title": "Este evento ha finalizado", "finished-description": "¡Sigue buscando nuevas experiencias de aprendizaje y mantén viva tu pasión por el conocimiento!" }, + "search-your-fav-tech": "Busca tu teconología favorita", "upcoming-events": "Próximos eventos", + "events-joined": "Eventos a los que te has unido", + "tech-event": "Eventos de {{tech}}", + "searching-for": "Buscando eventos de '{{search}}'", + "search-not-found": "No se encontraron eventos de '{{search}}'", + "search-found": "Eventos encontrados de '{{search}}'", "users-registered-count": "{{count}} personas ya se han registrado a este evento. Quedan disponibles {{spot_count}} cupos más.", "join-workshop": "Regístrarse al taller", "join": "Unirse ahora", diff --git a/src/common/components/MktEventCards.jsx b/src/common/components/MktEventCards.jsx index c8a72e30f..4fe34f922 100644 --- a/src/common/components/MktEventCards.jsx +++ b/src/common/components/MktEventCards.jsx @@ -1,7 +1,8 @@ import { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; -import { Flex } from '@chakra-ui/react'; +import { Flex, Skeleton } from '@chakra-ui/react'; import { useRouter } from 'next/router'; +import useTranslation from 'next-translate/useTranslation'; import useStyle from '../hooks/useStyle'; import GridContainer from './GridContainer'; import Heading from './Heading'; @@ -30,6 +31,8 @@ function MktEventCards({ const [originalEvents, setOriginalEvents] = useState([]); const [filteredEvents, setFilteredEvents] = useState([]); const [checkedInEvents, setCheckedInEvents] = useState([]); + const [loading, setLoading] = useState(false); + const { t } = useTranslation('workshops'); const { user } = useAuth(); const { fontColor } = useStyle(); const router = useRouter(); @@ -64,10 +67,12 @@ function MktEventCards({ useEffect(() => { const fetchEvents = async () => { + setLoading(true); try { if (externalEvents) { setOriginalEvents(externalEvents); setFilteredEvents(externalEvents); + setLoading(false); return; } const res = await axios.get(`${BREATHECODE_HOST}${endpointDefault}`); @@ -90,10 +95,13 @@ function MktEventCards({ } setOriginalEvents(eventsFilteredByTech); + if (searchSensitive && !search) return; setFilteredEvents(eventsFilteredByTech); } } catch (error) { console.error('Error fetching events:', error); + } finally { + setLoading(false); } }; @@ -101,56 +109,128 @@ function MktEventCards({ }, [externalEvents, techFilter]); useEffect(() => { - if (!searchSensitive || techFilter) return; + if (!searchSensitive || techFilter) return undefined; + + if (searchSensitive && !search) { + setFilteredEvents([]); + setLoading(false); + return undefined; + } if (!search) { setFilteredEvents(originalEvents); - return; + return undefined; } - const filteredBySearch = originalEvents.filter((event) => event?.title?.toLowerCase().includes(search.toLowerCase()) - || event?.event_type?.technologies?.includes(search.toLowerCase())); + setLoading(true); + + const delay = setTimeout(() => { + const filteredBySearch = originalEvents.filter((event) => event?.title?.toLowerCase().includes(search.toLowerCase()) + || event?.event_type?.technologies?.includes(search.toLowerCase())); - setFilteredEvents(filteredBySearch); + setFilteredEvents(filteredBySearch); + setLoading(false); + }, 1000); + + return () => clearTimeout(delay); }, [search, searchSensitive, originalEvents]); + const renderTitle = () => { + if (searchSensitive && search && loading) return t('searching-for', { search }); + if (searchSensitive && search && !loading && filteredEvents.length === 0) return t('search-not-found', { search }); + if (searchSensitive && search && !loading && filteredEvents.length > 0) return t('search-found', { search }); + if (techFilter) return `${t('tech-event', { tech: techFilter })}`; + return title; + }; + const eventsToDisplay = showCheckedInEvents ? checkedInEvents : filteredEvents; - return eventsToDisplay?.length > 0 && ( + return ( <> - - - - {title} - - - - - - {eventsToDisplay.map((event) => ( - - ))} + {loading ? ( + + + + {renderTitle()} + + - - + + + + + + + + +
+ ) : ( + <> + {eventsToDisplay?.length > 0 && ( + + + + {renderTitle()} + + + + + + {eventsToDisplay.map((event) => ( + + ))} + + + + )} + {eventsToDisplay?.length === 0 && searchSensitive && search?.length > 0 && ( + + + + {renderTitle()} + + + + + )} + + )} ); } diff --git a/src/common/components/MktSearchBar.jsx b/src/common/components/MktSearchBar.jsx index 16de174c9..7a6f0f64f 100644 --- a/src/common/components/MktSearchBar.jsx +++ b/src/common/components/MktSearchBar.jsx @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import Icon from './Icon'; import Heading from './Heading'; -function MktSearchBar({ id, headingTop, headingBottom, subtitle, popularSearches, background, ...rest }) { +function MktSearchBar({ id, headingTop, headingBottom, subtitle, popularSearches, background, popularSearchesTitle, ...rest }) { const [search, setSearch] = useState(''); const router = useRouter(); @@ -79,9 +79,7 @@ function MktSearchBar({ id, headingTop, headingBottom, subtitle, popularSearches {popularSearches && ( <> - Popular searches: - {' '} - {/*TRADUCIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR*/} + {popularSearchesTitle} {popularSearches.map((term) => ( @@ -116,10 +114,12 @@ MktSearchBar.propTypes = { popularSearches: PropTypes.arrayOf(PropTypes.string).isRequired, background: PropTypes.string, id: PropTypes.string, + popularSearchesTitle: PropTypes.string, }; MktSearchBar.defaultProps = { background: 'auto', + popularSearchesTitle: 'Popular searches', id: '', }; diff --git a/src/common/components/WorkshopsLoggedLanding.jsx b/src/common/components/WorkshopsLoggedLanding.jsx index f28791e53..71547cd2c 100644 --- a/src/common/components/WorkshopsLoggedLanding.jsx +++ b/src/common/components/WorkshopsLoggedLanding.jsx @@ -3,6 +3,7 @@ import MktEventCards from './MktEventCards'; import MktSearchBar from './MktSearchBar'; import MktTechnologiesPills from './MktTechnologiesPills'; import MktTechnologies from './MktTechnologies'; +import Heading from './Heading'; function WorkshopsLoggedLanding() { const { t } = useTranslation('workshops'); @@ -10,12 +11,21 @@ function WorkshopsLoggedLanding() { return ( <> - - - + + + + + {t('search-your-fav-tech')} - - + + ); } diff --git a/src/pages/[uid]/index.jsx b/src/pages/[uid]/index.jsx index 96d2760a6..29965d3ec 100644 --- a/src/pages/[uid]/index.jsx +++ b/src/pages/[uid]/index.jsx @@ -75,12 +75,12 @@ function Page({ page }) { )} - {!loggedInWorkshopsView && !isLoading ? ( + {loggedInWorkshopsView && !isLoading ? ( + + ) : ( - ) : ( - )} ); From 95e30b23558d389c663b6eb020fdbd4ca582d548 Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Mon, 13 Jan 2025 19:50:54 -0400 Subject: [PATCH 06/11] small change to add past event --- src/common/components/MktEventCards.jsx | 6 ++++-- src/common/components/WorkshopsLoggedLanding.jsx | 2 +- src/utils/index.js | 11 ++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/common/components/MktEventCards.jsx b/src/common/components/MktEventCards.jsx index 4fe34f922..c787c83b7 100644 --- a/src/common/components/MktEventCards.jsx +++ b/src/common/components/MktEventCards.jsx @@ -42,6 +42,7 @@ function MktEventCards({ featured: true, academy: WHITE_LABEL_ACADEMY, is_public: true, + past: !!techFilter, }, (endpoint && endpoint?.includes('?'))); const hoursLimited = hoursToLimit * 60; @@ -75,14 +76,15 @@ function MktEventCards({ setLoading(false); return; } + console.log(endpointDefault); const res = await axios.get(`${BREATHECODE_HOST}${endpointDefault}`); const data = res?.data; if (data && data.length > 0) { const englishLang = lang === 'en' && 'us'; - const sortDateToLiveClass = sortToNearestTodayDate(data, hoursLimited); + const sortDateToLiveClass = techFilter ? sortToNearestTodayDate(data, hoursLimited, true) : sortToNearestTodayDate(data, hoursLimited); const existentLiveClasses = sortDateToLiveClass?.filter((l) => l?.starting_at && (l?.ended_at || l?.ending_at) && l?.slug); - const isMoreThanAnyEvents = existentLiveClasses?.length > maxEvents; + const isMoreThanAnyEvents = sortDateToLiveClass?.length > maxEvents; const filteredByLang = existentLiveClasses?.filter((l) => l?.lang === englishLang || l?.lang === lang); const eventsFilteredByLang = isMoreThanAnyEvents ? filteredByLang : existentLiveClasses; diff --git a/src/common/components/WorkshopsLoggedLanding.jsx b/src/common/components/WorkshopsLoggedLanding.jsx index 71547cd2c..934185790 100644 --- a/src/common/components/WorkshopsLoggedLanding.jsx +++ b/src/common/components/WorkshopsLoggedLanding.jsx @@ -24,7 +24,7 @@ function WorkshopsLoggedLanding() { {t('search-your-fav-tech')} - + ); diff --git a/src/utils/index.js b/src/utils/index.js index 64d269b2d..c15ea49a0 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -256,8 +256,7 @@ const calcSVGViewBox = (pathId) => { const number2DIgits = (number) => number.toString().padStart(2, '0'); -const sortToNearestTodayDate = (data, minutes = 30) => { - // sort date to the nearest today date and 30minutes after starting time +const sortToNearestTodayDate = (data, minutes = 30, includeExpired = false) => { const currentDate = new Date(); if (data === undefined || data?.length === 0) return []; @@ -272,11 +271,17 @@ const sortToNearestTodayDate = (data, minutes = 30) => { const isGoingToStartInAnyMin = (minutesDiff >= 0 && minutesDiff <= minutes) || hasStarted; const hasExpired = endingDate < currentDate; + if (includeExpired) { + return isGoingToStartInAnyMin || hasExpired; + } + return isGoingToStartInAnyMin && !hasExpired; }); + const sortedDates = filteredDates.sort((a, b) => new Date(a.starting_at) - new Date(b.starting_at)); + const sortedDatesIncludingExpired = filteredDates.sort((a, b) => new Date(b.starting_at) - new Date(a.starting_at)); - return sortedDates; + return includeExpired ? sortedDatesIncludingExpired : sortedDates; }; const isNumber = (value) => Number.isFinite(Number(value)); // number or string with number (without letters) From 2cb83f3b265c5e01ae4d1bb345c47093ba7ba4dd Mon Sep 17 00:00:00 2001 From: Tomas Gonzalez <56565994+tommygonzaleza@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:08:46 -0400 Subject: [PATCH 07/11] Update workshops.json --- public/locales/en/workshops.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en/workshops.json b/public/locales/en/workshops.json index 6684fe715..1a364cfd8 100644 --- a/public/locales/en/workshops.json +++ b/public/locales/en/workshops.json @@ -36,7 +36,7 @@ "finished-title": "This event has ended", "finished-description": "Keep looking for new learning experiences and keep your passion for knowledge alive!" }, - "search-your-fav-tech": "Search your favourite technology", + "search-your-fav-tech": "Search your favorite technology", "upcoming-events": "Upcoming events", "events-joined": "Events you have joined", "tech-event": "{{tech}} events", From 6640b27640a4cc955159cc902f3b78fbac16d91c Mon Sep 17 00:00:00 2001 From: Tomas Gonzalez <56565994+tommygonzaleza@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:10:01 -0400 Subject: [PATCH 08/11] Update workshops.json --- public/locales/en/workshops.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/en/workshops.json b/public/locales/en/workshops.json index 1a364cfd8..c6592be57 100644 --- a/public/locales/en/workshops.json +++ b/public/locales/en/workshops.json @@ -20,7 +20,7 @@ "can-join": "can join" }, "intro": { - "top-title": "Welcome to workshops", + "top-title": "Welcome to 4Geeks Workshops", "lower-title": "Learn live, dive into tech skills", "subtitle": "Discover the future of code technology learning with live sessions! Join now to boost your skills." }, From d23bf5545046c9a425b8f509252d6de07d7a0181 Mon Sep 17 00:00:00 2001 From: Tomas Gonzalez <56565994+tommygonzaleza@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:10:43 -0400 Subject: [PATCH 09/11] Update common.json --- public/locales/es/common.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 778f1c5ea..89c53d210 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -93,7 +93,7 @@ "email": "Correo electrónico", "confirm-email": "Confirmar correo electrónico", "phone": "Teléfono", - "popular-searches": "Busquedas populares", + "popular-searches": "Búsquedas populares", "password": "Contraseña", "confirm-password": "Confirmar contraseña", "difficulty": "Dificultad", From 38c0380c2ad56d4c0b3e87b426218f9a6a4f088e Mon Sep 17 00:00:00 2001 From: Tomas Gonzalez <56565994+tommygonzaleza@users.noreply.github.com> Date: Fri, 17 Jan 2025 15:11:42 -0400 Subject: [PATCH 10/11] Update workshops.json --- public/locales/es/workshops.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/public/locales/es/workshops.json b/public/locales/es/workshops.json index da4812512..3795292ea 100644 --- a/public/locales/es/workshops.json +++ b/public/locales/es/workshops.json @@ -20,7 +20,7 @@ "can-join": "pueden entrar" }, "intro": { - "top-title": "Bienvenido a los talleres", + "top-title": "Bienvenido a los Workshops de 4Geeks", "lower-title": "Aprende en vivo y sumergete en las nuevas tecnologías", "subtitle": "Descubre el futuro del aprendizaje tecnológico con sesiones en vivo. ¡Únete y potencia tus habilidades!" }, @@ -44,7 +44,7 @@ "search-not-found": "No se encontraron eventos de '{{search}}'", "search-found": "Eventos encontrados de '{{search}}'", "users-registered-count": "{{count}} personas ya se han registrado a este evento. Quedan disponibles {{spot_count}} cupos más.", - "join-workshop": "Regístrarse al taller", + "join-workshop": "Regístrarse al workshop", "join": "Unirse ahora", "event-finished": "Evento finalizado", "checkin-modal": { @@ -60,10 +60,10 @@ "conversation-link": "https://chat.whatsapp.com/K39ELB5TIK63r4INTBd7SG" }, "no-consumables": { - "description": "Te has quedado sin talleres, pero no te preocupes, puedes conseguir más con unos pocos clics.", + "description": "Te has quedado sin acceso a workshops, pero no te preocupes, puedes conseguir más con unos pocos clics.", "link-text": "Aprende más.", "link": "", "get-more-workshops": "Obten más workshops" }, "back-to-workshops": "Regresar" -} \ No newline at end of file +} From 279acf1a817b728f92af77b6d6fa9cce61514ec5 Mon Sep 17 00:00:00 2001 From: lumi-tip Date: Sun, 26 Jan 2025 21:59:44 -0400 Subject: [PATCH 11/11] apply new endpoint for user checkin --- src/common/components/MktEventCards.jsx | 18 ++++++------------ src/common/services/breathecode.js | 1 + 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/common/components/MktEventCards.jsx b/src/common/components/MktEventCards.jsx index c787c83b7..c1f05b877 100644 --- a/src/common/components/MktEventCards.jsx +++ b/src/common/components/MktEventCards.jsx @@ -12,6 +12,7 @@ import { sortToNearestTodayDate, getQueryString } from '../../utils'; import DraggableContainer from './DraggableContainer'; import DynamicContentCard from './DynamicContentCard'; import { WHITE_LABEL_ACADEMY, BREATHECODE_HOST } from '../../utils/variables'; +import bc from '../services/breathecode'; import useAuth from '../hooks/useAuth'; import { parseQuerys } from '../../utils/url'; @@ -50,17 +51,11 @@ function MktEventCards({ const endpointDefault = `${choosenEndpoint}${qsConnector}`; const maxEvents = 10; - const fetchCheckedInEvents = async (eventsArray) => { + const fetchCheckedInEvents = async () => { try { - const checkedIn = await Promise.all( - eventsArray.map(async (event) => { - const res = await axios.get(`${BREATHECODE_HOST}/v1/events/event/${event.id}/checkin`); - const reservations = res?.data || []; - const isUserAttendee = reservations.find((reservation) => reservation?.attendee?.id === user.id); - return isUserAttendee ? event : null; - }), - ); - setCheckedInEvents(checkedIn.filter(Boolean)); + const res = await bc.events({ past: true, upcoming: true }).meCheckin(); + const userEvents = res?.data || []; + setCheckedInEvents(userEvents); } catch (error) { console.error('Error fetching checked-in events:', error); } @@ -76,7 +71,6 @@ function MktEventCards({ setLoading(false); return; } - console.log(endpointDefault); const res = await axios.get(`${BREATHECODE_HOST}${endpointDefault}`); const data = res?.data; @@ -92,7 +86,7 @@ function MktEventCards({ const eventsFilteredByTech = techFilter ? eventsFilteredByLang.filter((event) => event?.event_type?.technologies?.split(',').includes(techFilter.toLowerCase())) : eventsFilteredByLang; if (showCheckedInEvents && user?.id && eventsFilteredByTech.length > 0) { - fetchCheckedInEvents(eventsFilteredByTech); + fetchCheckedInEvents(); return; } diff --git a/src/common/services/breathecode.js b/src/common/services/breathecode.js index a997f5a61..b8a639c59 100644 --- a/src/common/services/breathecode.js +++ b/src/common/services/breathecode.js @@ -383,6 +383,7 @@ const breathecode = { const qs = parseQuerys(query); return { // get: () => axios.get(`${url}/event${qs}`), + meCheckin: () => axios.get(`${url}/checkin/event${qs}`), liveClass: () => axios.get(`${url}/event/liveclass${qs}`), joinLiveClass: (liveClassHash) => axios.get(`${url}/event/liveclass/join/${liveClassHash}${qs}`), joinLiveClass2: (liveClassHash) => axios.get(`${host}/me/event/liveclass/join/${liveClassHash}${qs}`),