From f558e93bb55a2d15db5f584cfbefecb678445c4c Mon Sep 17 00:00:00 2001 From: Muhammed Mustafa Date: Tue, 7 Feb 2023 11:17:49 +0200 Subject: [PATCH 01/52] refactor(tools): fix selector type error in the footer.ts (#49259) --- .../e2e/default/learn/common-components/footer.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cypress/e2e/default/learn/common-components/footer.ts b/cypress/e2e/default/learn/common-components/footer.ts index e191e8d9a14..137a2ff70dc 100644 --- a/cypress/e2e/default/learn/common-components/footer.ts +++ b/cypress/e2e/default/learn/common-components/footer.ts @@ -1,29 +1,27 @@ -const selectors = { - footer: '.site-footer' -}; +const footer = '.site-footer'; describe('Footer', () => { it('Should render on landing page', () => { cy.visit('/'); - cy.get(selectors.footer).should('be.visible'); + cy.get(footer).should('be.visible'); }); it('Should render on learn page', () => { cy.visit('/learn'); - cy.get(selectors.footer).should('be.visible'); + cy.get(footer).should('be.visible'); cy.visit('/learn/'); - cy.get(selectors.footer).should('be.visible'); + cy.get(footer).should('be.visible'); }); it('Should render on superblock page', () => { cy.visit('/learn/responsive-web-design/'); - cy.get(selectors.footer).should('be.visible'); + cy.get(footer).should('be.visible'); }); it('Should not render on challenge page', () => { cy.visit( '/learn/responsive-web-design/basic-html-and-html5/say-hello-to-html-elements' ); - cy.get(selectors.footer).should('not.exist'); + cy.get(footer).should('not.exist'); }); }); From c3855d011e433a6884367fceb672f80e14239180 Mon Sep 17 00:00:00 2001 From: Sriparno Roy <89148144+Sriparno08@users.noreply.github.com> Date: Tue, 7 Feb 2023 21:23:55 +0530 Subject: [PATCH 02/52] fix(curriculum): make step 43 of learn typography project easier to read (#49250) --- .../615f6b2d164f81809efd9bdc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 0d8c69723b0..c843342439d 100644 --- a/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -After your last `.divider` element, create a `p` element and give it the text `Total Fat 8g 10%`. Wrap `Total Fat` in a `span` element with the `class` set to `bold`. Wrap `10%` in another `span` element with the `class` set to `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. +After your last `.divider` element, create a `p` element and give it the text `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. # --hints-- From 0e538a926d6f0fb5ba9ca15fa135f032ca06d36b Mon Sep 17 00:00:00 2001 From: "@DiegoCascavita" <72409256+DiegoCascavita@users.noreply.github.com> Date: Wed, 8 Feb 2023 02:08:06 -0500 Subject: [PATCH 03/52] fix(curriculum): renaming tabs for uniformity in responsive design (#49286) renaming tabs for uniformity in responsive design --- client/src/templates/Challenges/classic/mobile-layout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/templates/Challenges/classic/mobile-layout.tsx b/client/src/templates/Challenges/classic/mobile-layout.tsx index efa5a2c2c8f..c79b86f9871 100644 --- a/client/src/templates/Challenges/classic/mobile-layout.tsx +++ b/client/src/templates/Challenges/classic/mobile-layout.tsx @@ -87,7 +87,7 @@ class MobileLayout extends Component { {!hasEditableBoundaries && ( {instructions} @@ -103,7 +103,7 @@ class MobileLayout extends Component { {testOutput} From 94f48cc587fe32e0317ddc39e92bdfcdbaa87efa Mon Sep 17 00:00:00 2001 From: camperbot Date: Wed, 8 Feb 2023 13:23:51 +0530 Subject: [PATCH 04/52] chore(i18n,learn): processed translations (#49280) --- .../data-visualization-certification.yml | 2 +- ...egacy-data-visualization-certification.yml | 2 +- ...ges-for-visually-impaired-accessibility.md | 2 +- .../add-an-accessible-date-picker.md | 10 +++---- ...choosing-colors-that-convey-information.md | 2 +- ...ess-issues-by-using-sufficient-contrast.md | 2 +- ...-meaning-by-using-descriptive-link-text.md | 2 +- ...of-audio-content-with-the-audio-element.md | 2 +- ...t-accessibility-with-the-figure-element.md | 2 +- ...ld-accessibility-with-the-label-element.md | 2 +- ...ove-readability-with-high-contrast-text.md | 2 +- ...t-to-the-content-using-the-main-element.md | 2 +- ...know-when-alt-text-should-be-left-blank.md | 2 +- ...-to-a-screen-reader-by-using-custom-css.md | 2 +- ...e-links-navigable-with-html-access-keys.md | 2 +- ...igation-easier-with-the-footer-landmark.md | 2 +- ...igation-easier-with-the-header-landmark.md | 8 +++--- ...navigation-easier-with-the-nav-landmark.md | 2 +- ...times-with-the-html5-datetime-attribute.md | 2 +- ...w-hierarchical-relationships-of-content.md | 2 +- ...dex-to-add-keyboard-focus-to-an-element.md | 2 +- .../wrap-content-in-the-article-element.md | 8 +++--- ...eldset-element-for-better-accessibility.md | 22 +++++++-------- .../create-a-set-of-checkboxes.md | 2 +- ...-to-external-pages-with-anchor-elements.md | 10 +++---- ...he-flex-shrink-property-to-shrink-items.md | 6 ++-- .../create-decimal-numbers-with-javascript.md | 6 ++-- .../decrement-a-number-with-javascript.md | 2 +- .../increment-a-number-with-javascript.md | 2 +- ...ap-method-to-extract-data-from-an-array.md | 2 +- .../use-the-reduce-method-to-analyze-data.md | 2 +- .../visualize-data-with-a-bar-chart.md | 10 +++---- ...visualize-data-with-a-scatterplot-graph.md | 28 +++++++++---------- .../add-a-hover-effect-to-a-d3-element.md | 4 +-- .../add-attributes-to-the-circle-elements.md | 10 +++---- .../add-document-elements-with-d3.md | 4 +-- .../change-the-presentation-of-a-bar-chart.md | 12 ++++---- .../create-a-linear-scale-with-d3.md | 16 +++++------ ...ically-set-the-coordinates-for-each-bar.md | 16 +++++------ ...h-javascript-using-the-onclick-property.md | 8 +++--- .../budget-app.md | 4 +-- .../5dfa30b9eacea3f48c6300ad.md | 20 ++++++------- .../5ef9b03c81a63668521804d2.md | 2 +- .../5ef9b03c81a63668521804e5.md | 2 +- .../5efc4f528d6a74d05e68af74.md | 2 +- .../615f7de4487b64919bb4aa5e.md | 2 +- ...project-with-external-packages-from-npm.md | 2 +- ...e-of-any-node.js-project-or-npm-package.md | 8 +++--- ...he-latest-minor-version-of-a-dependency.md | 4 +-- ...he-latest-patch-version-of-a-dependency.md | 4 +-- .../6148da157cc0bd0d06df5c0a.md | 2 +- .../5dfa30b9eacea3f48c6300ad.md | 20 ++++++------- .../5ef9b03c81a63668521804d2.md | 2 +- .../5ef9b03c81a63668521804e5.md | 2 +- .../5efc4f528d6a74d05e68af74.md | 2 +- .../615f7de4487b64919bb4aa5e.md | 2 +- .../check-for-mixed-grouping-of-characters.md | 2 +- .../using-the-test-method.md | 4 +-- 58 files changed, 156 insertions(+), 156 deletions(-) diff --git a/curriculum/challenges/arabic/00-certifications/data-visualization-certification/data-visualization-certification.yml b/curriculum/challenges/arabic/00-certifications/data-visualization-certification/data-visualization-certification.yml index 1a22cbbd33d..d77cefc4226 100644 --- a/curriculum/challenges/arabic/00-certifications/data-visualization-certification/data-visualization-certification.yml +++ b/curriculum/challenges/arabic/00-certifications/data-visualization-certification/data-visualization-certification.yml @@ -7,7 +7,7 @@ isPrivate: true tests: - id: bd7168d8c242eddfaeb5bd13 - title: التصوير المرئي للبيانات باستخدام مخطط بياني للأعمدة + title: التصوير المرئي للبيانات باستخدام مخطط الأعمدة - id: bd7178d8c242eddfaeb5bd13 title: التصوير المرئي للبيانات باستخدام مخطط التشتت diff --git a/curriculum/challenges/arabic/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml b/curriculum/challenges/arabic/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml index 04ac3369a4f..19885830ef3 100644 --- a/curriculum/challenges/arabic/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml +++ b/curriculum/challenges/arabic/00-certifications/legacy-data-visualization-certification/legacy-data-visualization-certification.yml @@ -22,7 +22,7 @@ tests: title: بناء لعبة Roguelike Dungeon Crawler - id: bd7168d8c242eddfaeb5bd13 - title: التصوير المرئي للبيانات باستخدام مخطط بياني للأعمدة + title: التصوير المرئي للبيانات باستخدام مخطط الأعمدة - id: bd7178d8c242eddfaeb5bd13 title: التصوير المرئي للبيانات باستخدام مخطط التشتت diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md index 27f9c91bb75..a957e919b1a 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-a-text-alternative-to-images-for-visually-impaired-accessibility.md @@ -21,7 +21,7 @@ dashedName: add-a-text-alternative-to-images-for-visually-impaired-accessibility # --instructions-- -كامبر القط هو نينجا في البرمجة وهو أيضا نينجا حقيقي، يقوم ببناء صفحة ويب لمشاركة معرفتة. الصورة الشخصية التي يريد استخدامها تظهر مهاراته ويجب أن تحظي بتقدير جميع زوار الموقع. أضف خاصية (attribute) `alt` في الوسم (tag) `img` لتظهر أن كامبر القط يجيد لعبة الكاراتية. (خاصية الصورة `src` لا ترتبط بملف فعلي، لذا يجب أن ترى نص `alt` في العرض.) +Camper Cat هو نينجا في البرمجة وهو أيضا نينجا حقيقي، يقوم ببناء صفحة ويب لمشاركة معرفتة. الصورة الشخصية التي يريد استخدامها تظهر مهاراته ويجب أن تحظي بتقدير جميع زوار الموقع. أضف خاصية (attribute) `alt` في الوسم (tag) `img` لتظهر أن Camper Cat يجيد لعبة الكاراتية. (خاصية الصورة `src` لا ترتبط بملف فعلي، لذا يجب أن ترى نص `alt` في العرض.) # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md index f54b40bdd31..e434da4f1de 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/add-an-accessible-date-picker.md @@ -24,29 +24,29 @@ dashedName: add-an-accessible-date-picker # --instructions-- -يقوم Camper Cat بإعداد بطولة Mortal Kombat ويريد أن يطلب من منافسيه معرفة التاريخ الأفضل. أضف وسم `input` مع سمة `type` من نوع `date` ، وسمة `id` بقيمة `pickdate`، و سمة `name` بقيمة `date`. +يقوم Camper Cat بإعداد بطولة Mortal Kombat ويريد أن يطلب من منافسيه معرفة التاريخ الأفضل. أضف علامة `input` مع سمة `type` من نوع `date`، و مع سمة `id` بقيمة `pickdate`، و أيضا سمة `name` بقيمة `date`. # --hints-- -يجب أن يحتوي الكود علي وسم `input` واحد لحقل محدد التاريخ. +يجب أن يحتوي الكود علي علامة `input` واحد لخانة محدد التاريخ. ```js assert($('input').length == 2); ``` -يجب أن يحتوي وسم `input` على سمة `type` بقيمة `date`. +يجب أن يحتوي علامة `input` على سمة `type` بقيمة `date`. ```js assert($('input').attr('type') == 'date'); ``` -يجب أن يحتوي وسم `input` على سمة `id` بقيمة `pickdate`. +يجب أن يحتوي علامة `input` على سمة `id` بقيمة `pickdate`. ```js assert($('input').attr('id') == 'pickdate'); ``` -يجب أن يحتوي وسم `input` على سمة `name` بقيمة `date`. +يجب أن يحتوي علامة `input` على سمة `name` بقيمة `date`. ```js assert($('input').attr('name') == 'date'); diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md index 2f21941dc92..ee510da38e3 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-carefully-choosing-colors-that-convey-information.md @@ -19,7 +19,7 @@ dashedName: >- # --instructions-- -تختبر Camper Cat أنماطًا مختلفة لزر مهم ، ولكن اللون الأصفر للخلفة (`#FFFF33`) `background-color` و الاخضر (`#33FF33`) `color`لون النص هي درجات مجاورة على عجلة الألوان ولا يمكن تمييزها فعليًا عند بعض المصابين بعمى الألوان. (خفتهم المتشابهة تفشل أيضًا في فحص نسبة التباين). غيّر لون النص `color` إلى اللون الأزرق المظلم (`#003366`) لحل كلتا المشكلتين. +يختبر Camper Cat أنماطًا مختلفة لزر مهم، ولكن اللون الأصفر (`#FFFF33`) للخلفية (`background-color`) و الاخضر (`#33FF33`) للون النص (`color`) هي درجات مجاورة على عجلة الألوان ولا يمكن لبعض المصابين بعمى الألوان التمييز ببنهم. (خفتهم المتشابهة تفشل أيضًا في فحص نسبة التباين). غيّر لون النص `color` إلى اللون الأزرق المظلم (`#003366`) لحل كلتا المشكلتين. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md index 133f49e990f..afad525b088 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/avoid-colorblindness-issues-by-using-sufficient-contrast.md @@ -19,7 +19,7 @@ dashedName: avoid-colorblindness-issues-by-using-sufficient-contrast # --instructions-- -يقوم Camper Cat بتجربة استخدام الألوان لنص مدونته وخلفيتها ، ولكن دمجة الحالي لللون الأخضر للخلفية `background-color` مع لون النص الماروني `color` له نسبة تباين 2.5:1. يمكنك بسهولة ضبط إضاءة الألوان بما اته عرفها، باستخدام خاصية في الـ CSS و هي `hsl()` (التي تمثل hue بمعني التدرج و saturation بمعني التشبع و lightness بمعني الخفة) بتغيير الوسيطة (argument) الثالثة. زيادة قيمة الخفة lightness للون الخلفية `background-color` من 35% إلى 55%، وتقليل قيمة الخفة لـ `color` من 20% إلى 15%. وهذا ما يحسّن التباين إلى 5.9:1. +يقوم Camper Cat بتجربة استخدام الألوان لنص مدونته وخلفيتها، ولكن دمجة لألون الأخضر للخلفية `background-color` مع لون النص الماروني (maroon) الحالي `color` له نسبة تباين 2.5:1. يمكنك بسهولة ضبط إضاءة الألوان بما اته عرفها، باستخدام خاصية في الـ CSS و هي `hsl()` (التي تمثل hue بمعني التدرج و saturation بمعني التشبع و lightness بمعني الخفة) بتغيير الوسيطة (argument) الثالثة. زيادة قيمة الخفة lightness للون الخلفية `background-color` من 35% إلى 55%، وتقليل قيمة الخفة لـ `color` من 20% إلى 15%. وهذا ما يحسّن التباين إلى 5.9:1. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md index f282a55ad02..6da59306862 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/give-links-meaning-by-using-descriptive-link-text.md @@ -15,7 +15,7 @@ Screen reader users have various options for what type of content their device r # --instructions-- -The link text that Camper Cat is using is not very descriptive without the surrounding context. انقل علامات الرابط (`a`) بحيث تلتف حول النص `information about batteries` بدلاً من `Click here`. +نص الرابط الذي يستخدمه Camper Cat ليس وصفياً جداً بدون السياق المحيط. انقل علامات الرابط (`a`) بحيث تلتف حول النص `information about batteries` بدلاً من `Click here`. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md index 8e5ff50fc46..0a9674923a4 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-accessibility-of-audio-content-with-the-audio-element.md @@ -26,7 +26,7 @@ Here's an example: # --instructions-- -Time to take a break from Camper Cat and meet fellow camper Zersiax (@zersiax), a champion of accessibility and a screen reader user. To hear a clip of his screen reader in action, add an `audio` element after the `p`. Include the `controls` attribute. Then place a `source` tag inside the `audio` tags with the `src` attribute set to `https://s3.amazonaws.com/freecodecamp/screen-reader.mp3` and `type` attribute set to `"audio/mpeg"`. +حان الوقت لأخذ استراحة من Camper Cat و مقابلة الزميل camper Zersiax (@zersiax), بطل ال accessibility و مستخدم لتقنية قارئ الشاشة (screen reader). To hear a clip of his screen reader in action, add an `audio` element after the `p`. Include the `controls` attribute. Then place a `source` tag inside the `audio` tags with the `src` attribute set to `https://s3.amazonaws.com/freecodecamp/screen-reader.mp3` and `type` attribute set to `"audio/mpeg"`. **Note:** The audio clip may sound fast and be difficult to understand, but that is a normal speed for screen reader users. diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md index d677e66b940..168b6351e7e 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-chart-accessibility-with-the-figure-element.md @@ -27,7 +27,7 @@ Here's an example - note that the `figcaption` goes inside the `figure` tags and # --instructions-- -Camper Cat is hard at work creating a stacked bar chart showing the amount of time per week to spend training in stealth, combat, and weapons. Help him structure his page better by changing the `div` tag he used to a `figure` tag, and the `p` tag that surrounds the caption to a `figcaption` tag. +Camper Cat شاق في العمل لإنشاء مخطط أعمدة مكدسة يبين مقدار الوقت في الأسبوع لقضاء التدريب على السرقة، القتال والأسلحة. Help him structure his page better by changing the `div` tag he used to a `figure` tag, and the `p` tag that surrounds the caption to a `figcaption` tag. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md index 55492a9a50e..8348eb4e910 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-form-field-accessibility-with-the-label-element.md @@ -26,7 +26,7 @@ The value of the `for` attribute must be the same as the value of the `id` attri # --instructions-- -Camper Cat expects a lot of interest in his thoughtful blog posts and wants to include an email sign up form. Add a `for` attribute on the email `label` that matches the `id` on its `input` field. +تنتظر Camper Cat الكثير من الاهتمام في مشاركاته المدونة المدروسة وترغب في تضمين نموذج تسجيل البريد الإلكتروني. Add a `for` attribute on the email `label` that matches the `id` on its `input` field. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md index 8bf9b62cf57..b3d9a57f918 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/improve-readability-with-high-contrast-text.md @@ -15,7 +15,7 @@ The Web Content Accessibility Guidelines (WCAG) recommend at least a 4.5 to 1 co # --instructions-- -Camper Cat's choice of light gray text on a white background for his recent blog post has a 1.5:1 contrast ratio, making it hard to read. Change the `color` of the text from the current gray (`#D3D3D3`) to a darker gray (`#636363`) to improve the contrast ratio to 6:1. +اختيار Camper Cat للنص الرمادي الخفيف على خلفية بيضاء لمشاركته الأخيرة يحتوي على 1.5:1 نسبة التباين، مما يجعل من الصعب قراءتها. Change the `color` of the text from the current gray (`#D3D3D3`) to a darker gray (`#636363`) to improve the contrast ratio to 6:1. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md index 83031edde59..02ebc2ac766 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/jump-straight-to-the-content-using-the-main-element.md @@ -19,7 +19,7 @@ The `main` tag also has an embedded landmark feature that assistive technology c # --instructions-- -Camper Cat has some big ideas for his ninja weapons page. Help him set up his markup by adding opening and closing `main` tags between the `header` and `footer` (covered in other challenges). Keep the `main` tags empty for now. +Camper Cat لديه بعض الأفكار الكبيرة لصفحة أسلحة النينجا. Help him set up his markup by adding opening and closing `main` tags between the `header` and `footer` (covered in other challenges). Keep the `main` tags empty for now. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md index 695445ea37e..7b46cb25d31 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/know-when-alt-text-should-be-left-blank.md @@ -23,7 +23,7 @@ Background images usually fall under the 'decorative' label as well. However, th # --instructions-- -Camper Cat has coded a skeleton page for the blog part of his website. He's planning to add a visual break between his two articles with a decorative image of a samurai sword. Add an `alt` attribute to the `img` tag and set it to an empty string. (Note that the image `src` doesn't link to an actual file - don't worry that there are no swords showing in the display.) +قام Camper Cat ببرمجة هيكل الصفحة لمدونة موقعه. He's planning to add a visual break between his two articles with a decorative image of a samurai sword. Add an `alt` attribute to the `img` tag and set it to an empty string. (Note that the image `src` doesn't link to an actual file - don't worry that there are no swords showing in the display.) # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md index 63bfea4b75c..f3c52234204 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-elements-only-visible-to-a-screen-reader-by-using-custom-css.md @@ -35,7 +35,7 @@ Here's an example of the CSS rules that accomplish this: # --instructions-- -Camper Cat created a really cool stacked bar chart for his training page, and put the data into a table for his visually impaired users. The table already has an `sr-only` class, but the CSS rules aren't filled in yet. Give the `position` an `absolute` value, the `left` a `-10000px` value, and the `width` and `height` both `1px` values. +أنشأ Camper Cat مخطط أعمدة مكدسة رائع جدا لصفحة التدريب، و وضع البيانات في جدول لمستخدميه ذوي الإعاقة البصرية. The table already has an `sr-only` class, but the CSS rules aren't filled in yet. Give the `position` an `absolute` value, the `left` a `-10000px` value, and the `width` and `height` both `1px` values. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md index ba72f6d7976..a738ee9f87e 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-links-navigable-with-html-access-keys.md @@ -21,7 +21,7 @@ Here's an example: # --instructions-- -Camper Cat wants the links around the two blog article titles to have keyboard shortcuts so his site's users can quickly navigate to the full story. Add an `accesskey` attribute to both links and set the first one to `g` (for Garfield) and the second one to `c` (for Chuck Norris). +يريد Camper Cat أن يكون للرابطان حول عنوان مقالات المدونة اختصارات لوحة المفاتيح (keyboard shortcuts) حتى يتمكن مستخدمو موقعه من الانتقال بسرعة إلى القصة الكاملة. Add an `accesskey` attribute to both links and set the first one to `g` (for Garfield) and the second one to `c` (for Chuck Norris). # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md index 3330ea186d7..f536b53a165 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-footer-landmark.md @@ -13,7 +13,7 @@ Similar to `header` and `nav`, the `footer` element has a built-in landmark feat # --instructions-- -Camper Cat's training page is making good progress. Change the `div` he used to wrap his copyright information at the bottom of the page to a `footer` element. +صفحة تدريب Camper Cat تحرز تقدما جيدا. Change the `div` he used to wrap his copyright information at the bottom of the page to a `footer` element. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md index babce017089..5c4b0840354 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-header-landmark.md @@ -9,11 +9,11 @@ dashedName: make-screen-reader-navigation-easier-with-the-header-landmark # --description-- -عنصر الـ HTML5 التالي الذي يضيف المعنى الدلالي ويحسن إمكانية الوصول هو عنصر الـ `header`. يستخدم لإحتواء المعلومات التمهيدية أو روابط التنقل لعنصره الاساسي ويعمل بشكل جيد مع المحتوى المتكرر في الأعلى على الصفحات متعددة. +عنصر الـ HTML5 التالي الذي يضيف المعنى الدلالي ويحسن إمكانية الوصول هو عنصر `header`. يستخدم لاحتواء المعلومات التمهيدية أو روابط التنقل لعنصره آلأساسي ويعمل بشكل جيد مع المحتوى المتكرر في الأعلى على الصفحات متعددة. `header` يشاركك الميزة البارزة المدمجة التي رأيتها مع `main`، مما يسمح للتكنولوجيات المساعدة بالانتقال بسرعة إلى ذلك المحتوى. -**ملاحظة:** عنصر الـ `header` يستخدم في عنصر `body` بمستند HTML الخاص بك. وهذا يختلف عن عن عنصر الـ `head` الذي يحتوي على عنوان الصفحة، معلومات تعريفية، و الخ. +**ملاحظة:** عنصر `header` يستخدم في عنصر `body` بمستند HTML الخاص بك. وهذا يختلف عن عن عنصر الـ `head` الذي يحتوي على عنوان الصفحة، معلومات تعريفية، و الخ. # --instructions-- @@ -21,13 +21,13 @@ dashedName: make-screen-reader-navigation-easier-with-the-header-landmark # --hints-- -يجب أن يحتوي الكود الخاص بك على `header` واحد فقط. +يجب أن يحتوي الكود الخاص بك على علامة `header` واحدة فقط. ```js assert($('header').length == 1); ``` -يجب أن يحتوي عنصر `header` عنصر الـ `h1`. +يجب أن يحتوي عنصر `header` على عنصر `h1`. ```js assert($('header').children('h1').length == 1); diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md index 906d7dd5c83..f7386921714 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/make-screen-reader-navigation-easier-with-the-nav-landmark.md @@ -15,7 +15,7 @@ If there are repeated site links at the bottom of the page, it isn't necessary t # --instructions-- -Camper Cat included navigation links at the top of his training page, but wrapped them in a `div`. Change the `div` to a `nav` tag to improve the accessibility on his page. +تضمن Camper Cat وصلات تنقل من الجزء العلوي من صفحة التدريب، لكنه لفها في `div`. Change the `div` to a `nav` tag to improve the accessibility on his page. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/standardize-times-with-the-html5-datetime-attribute.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/standardize-times-with-the-html5-datetime-attribute.md index d9318d50f7b..3892d3ff1bc 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/standardize-times-with-the-html5-datetime-attribute.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/standardize-times-with-the-html5-datetime-attribute.md @@ -19,7 +19,7 @@ Here's an example: # --instructions-- -Camper Cat's Mortal Kombat survey results are in! Wrap a `time` tag around the text `Thursday, September 15th` and add a `datetime` attribute to it set to `2016-09-15`. +صدرت نتائج استقصاء Camper Cat في Mortal Kombat! Wrap a `time` tag around the text `Thursday, September 15th` and add a `datetime` attribute to it set to `2016-09-15`. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-headings-to-show-hierarchical-relationships-of-content.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-headings-to-show-hierarchical-relationships-of-content.md index fbb95eaf6b1..4feaf983881 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-headings-to-show-hierarchical-relationships-of-content.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-headings-to-show-hierarchical-relationships-of-content.md @@ -23,7 +23,7 @@ One final point, each page should always have one (and only one) `h1` element, w # --instructions-- -Camper Cat wants a page on his site dedicated to becoming a ninja. Help him fix the headings so his markup gives semantic meaning to the content, and shows the proper parent-child relationships of his sections. Change all the `h5` tags to the proper heading level to indicate they are subsections of the `h2` ones. Use `h3` tags for the purpose. +يريد Camper Cat صفحة مخصصة على موقعه الإلكتروني لتعليم النينجا. Help him fix the headings so his markup gives semantic meaning to the content, and shows the proper parent-child relationships of his sections. Change all the `h5` tags to the proper heading level to indicate they are subsections of the `h2` ones. Use `h3` tags for the purpose. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-tabindex-to-add-keyboard-focus-to-an-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-tabindex-to-add-keyboard-focus-to-an-element.md index 0ae730fc94b..cfd48fbd829 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-tabindex-to-add-keyboard-focus-to-an-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/use-tabindex-to-add-keyboard-focus-to-an-element.md @@ -21,7 +21,7 @@ Certain elements, such as links and form controls, automatically receive keyboar # --instructions-- -Camper Cat created a new survey to collect information about his users. He knows input fields automatically get keyboard focus, but he wants to make sure his keyboard users pause at the instructions while tabbing through the items. Add a `tabindex` attribute to the `p` tag and set its value to `0`. Bonus - using `tabindex` also enables the CSS pseudo-class `:focus` to work on the `p` tag. +أنشأ Camper Cat استبيانا جديدا لجمع المعلومات عن مستخدمي موقعه. He knows input fields automatically get keyboard focus, but he wants to make sure his keyboard users pause at the instructions while tabbing through the items. Add a `tabindex` attribute to the `p` tag and set its value to `0`. Bonus - using `tabindex` also enables the CSS pseudo-class `:focus` to work on the `p` tag. # --hints-- diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-content-in-the-article-element.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-content-in-the-article-element.md index f6eaf6e3697..0ec49e8d271 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-content-in-the-article-element.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-content-in-the-article-element.md @@ -9,7 +9,7 @@ dashedName: wrap-content-in-the-article-element # --description-- -`article` هو عنصر آخر من عناصر HTML5 الجديدة التي تضيف المعنى الدلالي الي الـ markup. `article` هو عنصر تقسيم ويستخدم لتغليف المحتوي القائم بذاته. يعمل الوسم بشكل جيد مع إدخالات المدونة أو مشاركات المنتدى أو المقالات الإخبارية. +`article` هو عنصر آخر من عناصر HTML5 الجديدة التي تضيف المعنى الدلالي الي الـ markup. `article` هو عنصر تقسيم ويستخدم لتغليف المحتوي القائم بذاته. يعمل العلامة بشكل جيد مع إدخالات المدونة أو مشاركات المنتدى أو المقالات الإخبارية. تحديد فيما إذا كان المحتوى يستطيع أن يكون مستقلا هو عادة حكم شخصي، ولكن هناك عدة اختبارات بسيطة يمكنك استخدامها. اسأل نفسك إذا كنت قد قمت بإزالة كل السياق المحيط، هل سيظل المحتوى منطقياً؟ وبالمثل بالنسبة للنص، هل سيظل المحتوى صحيحا إذا كان في RSS feed ؟ @@ -21,17 +21,17 @@ dashedName: wrap-content-in-the-article-element # --instructions-- -استخدم Camper Cat وسوم `article` لتغليف المشاركات على صفحة مدونته، لكنه نسي استخدامها حول المشاركة العلوية. قم بتغيير وسم `div` لاستخدام وسم `article` بدلاً منه. +استخدم Camper Cat علامات `article` لتغليف المشاركات على صفحة مدونته، لكنه نسي استخدامها حول المشاركة العلوية. قم بتغيير علامة `div` لاستخدام علامة `article` بدلاً منه. # --hints-- -الكود الخاص بك يجب أن يحتوي على ثلاث وسوم `article`. +الكود الخاص بك يجب أن يحتوي على ثلاث علامات `article`. ```js assert($('article').length == 3); ``` -يجب ألا يحتوي الكود الخاص بك علي اي وسوم `div`. +يجب ألا يحتوي الكود الخاص بك على أي علامة `div`. ```js assert($('div').length == 0); diff --git a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-radio-buttons-in-a-fieldset-element-for-better-accessibility.md b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-radio-buttons-in-a-fieldset-element-for-better-accessibility.md index dab2077c235..794a8db4a3d 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-radio-buttons-in-a-fieldset-element-for-better-accessibility.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/applied-accessibility/wrap-radio-buttons-in-a-fieldset-element-for-better-accessibility.md @@ -1,6 +1,6 @@ --- id: 587d778b367417b2b2512aa7 -title: Wrap Radio Buttons in a fieldset Element for Better Accessibility +title: تغليف Radio Buttons داخل fieldset لتحسينا لإمكانيه الوصول challengeType: 0 videoUrl: 'https://scrimba.com/c/cVJVefw' forumTopicId: 301030 @@ -9,13 +9,13 @@ dashedName: wrap-radio-buttons-in-a-fieldset-element-for-better-accessibility # --description-- -The next form topic covers the accessibility of radio buttons. Each choice is given a `label` with a `for` attribute tying to the `id` of the corresponding item as covered in the last challenge. Since radio buttons often come in a group where the user must choose one, there's a way to semantically show the choices are part of a set. +يغطي الموضوع التالي إمكانية الوصول إلى أزرار الاختيار في النموذج. كل اختيار يعطى `label` وله سمة `for` مرتبطة بـسمة `id` في العنصر المقابل, كما هو مشمول في التحدي الأخير. نظرًا لأن أزرار الراديو (radio buttons) غالبا ما تأتي في مجموعات حيث يجب على المستخدم أن يختار زر واحد فقط من المجموعة، هناك طريقة لإظهار الخيارات بشكل لُغَوي أنها فعلا جزء من نفس المجموعة. -The `fieldset` tag surrounds the entire grouping of radio buttons to achieve this. It often uses a `legend` tag to provide a description for the grouping, which screen readers read for each choice in the `fieldset` element. +يحيط علامة (tag) `fieldset` بكامل مجموعة الأزرار الراديو ( radio buttons) لتحقيق ذلك. غالبا ما تستخدم علامة (tag) `legend` لتقديم وصف للمجموعة، أي قارئ الشاشة (screen readers) سيقرأ كل اختيار في عنصر `fieldset`. -The `fieldset` wrapper and `legend` tag are not necessary when the choices are self-explanatory, like a gender selection. Using a `label` with the `for` attribute for each radio button is sufficient. +العلامة `fieldset` و `legend` ليست ضرورية عندما تكون الاختيارات غنية عن التفسير، مثل اختيار نوع الجنس. استخدام `label` مع سمة `for` لكل زر راديو هو كاف. -Here's an example: +إليك مثال: ```html
@@ -33,17 +33,17 @@ Here's an example: # --instructions-- -Camper Cat wants information about the ninja level of his users when they sign up for his email list. He's added a set of radio buttons and learned from our last lesson to use `label` tags with `for` attributes for each choice. Go Camper Cat! However, his code still needs some help. Change the `div` tag surrounding the radio buttons to a `fieldset` tag, and change the `p` tag inside it to a `legend`. +يريد Camper Cat معلومات عن مستوى النينجا لمستخدميه عند تسجيلهم لقائمة بريده الإلكتروني. لقد أضاف مجموعة من أزرار الراديو وتعلمنا من درسنا الأخير استخدام علامات `label` مع سمات `for` لكل اختيار. اذهب يا Camper Cat! However, his code still needs some help. تغيير علامة `div` الذي يحيط بأزرار الراديو إلى علامة `fieldset`، و قم بتغيير علامة `p` بداخلها إلى `legend`. # --hints-- -Your code should have a `fieldset` tag around the radio button set. +يجب أن يكون الكود الخاص بك فيه علامة `fieldset` حول مجموعة أزرار الراديو. ```js assert($('fieldset').length == 1); ``` -The `fieldset` element should have a closing tag. +يجب أن يكون لعلامة `fieldset` علامة اغلاق أيضا. ```js assert( @@ -52,19 +52,19 @@ assert( ); ``` -Your code should have a `legend` tag around the text asking what level ninja a user is. +يجب أن يحتوي الكود الخاصة بك على علامة `legend` حول النص الذي يسأل عن مستوى النينجا للمستخدم. ```js assert($('legend').length == 1); ``` -Your code should not have any `div` tags. +يجب ألا يحتوي الكود الخاص بك على أي علامة `div`. ```js assert($('div').length == 0); ``` -Your code should no longer have a `p` tag around the text asking what level ninja a user is. +يجب ألا يحتوي الكود الخاصة بك على علامة `p` حول النص الذي يسأل عن مستوى النينجا للمستخدم. ```js assert($('p').length == 4); diff --git a/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/create-a-set-of-checkboxes.md b/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/create-a-set-of-checkboxes.md index 43bc88a6169..6c0f2f8caeb 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/create-a-set-of-checkboxes.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/create-a-set-of-checkboxes.md @@ -43,7 +43,7 @@ Each of your three checkbox elements should be nested in its own `label` element assert($('label > input[type="checkbox"]:only-child').length > 2); ``` -Make sure each of your `label` elements has a closing tag. +تأكد أن كل `label` له علامة إغلاق. ```js assert( diff --git a/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/link-to-external-pages-with-anchor-elements.md b/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/link-to-external-pages-with-anchor-elements.md index b9d927d2707..80bdf98afd4 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/link-to-external-pages-with-anchor-elements.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/basic-html-and-html5/link-to-external-pages-with-anchor-elements.md @@ -17,27 +17,27 @@ You can use `a` (*anchor*) elements to link to content outside of your web page. this links to freecodecamp.org ``` -Then your browser will display the text `this links to freecodecamp.org` as a link you can click. And that link will take you to the web address `https://www.freecodecamp.org`. +ثم يعرض متصفّحك نص: `this links to freecodecamp.org` على هيئة رابط يمكنك النقر عليه. And that link will take you to the web address `https://www.freecodecamp.org`. # --instructions-- -قم بإنشاء عنصر `a` الذي يربط بـ `https://www.freecatphotoapp.com` والذي يحتوي على "صور قطط" كنص الرابط. +Create an `a` element that links to `https://www.freecatphotoapp.com` and has "cat photos" as its anchor text. # --hints-- -يجب أن يحتوي عنصر `a` الخاص بك على نص الرابط `cat photos`. +Your `a` element should have the anchor text of `cat photos`. ```js assert(/cat photos/gi.test($('a').text())); ``` -You need an `a` element that links to `https://www.freecatphotoapp.com` +تحتاج إلى عنصر `a` يربط بـعنوان `https://www.freecatphotoapp.com` ```js assert(/^https?:\/\/(www\.)?freecatphotoapp\.com\/?$/i.test($('a').attr('href'))); ``` -Your `a` element should have a closing tag. +عنصر `a` الخاص بك لا بد أن يكون له علامة إغلاق (closing tag). ```js assert( diff --git a/curriculum/challenges/arabic/01-responsive-web-design/css-flexbox/use-the-flex-shrink-property-to-shrink-items.md b/curriculum/challenges/arabic/01-responsive-web-design/css-flexbox/use-the-flex-shrink-property-to-shrink-items.md index fc9b59ab23f..5541b9cc8fe 100644 --- a/curriculum/challenges/arabic/01-responsive-web-design/css-flexbox/use-the-flex-shrink-property-to-shrink-items.md +++ b/curriculum/challenges/arabic/01-responsive-web-design/css-flexbox/use-the-flex-shrink-property-to-shrink-items.md @@ -1,6 +1,6 @@ --- id: 587d78ad367417b2b2512afb -title: Use the flex-shrink Property to Shrink Items +title: استعمال خاصية flex-shrink لتقليص الأصناف challengeType: 0 videoUrl: 'https://scrimba.com/p/pVaDAv/cd3PBfr' forumTopicId: 301113 @@ -9,11 +9,11 @@ dashedName: use-the-flex-shrink-property-to-shrink-items # --description-- -So far, all the properties in the challenges apply to the flex container (the parent of the flex items). However, there are several useful properties for the flex items. +وتنطبق حتى الآن جميع الخواص في التحديات على الحاوية المرنة ( flex container وهو أصل الأصناف المرنة). غير أن هناك عدة خصائص مفيدة للأصناف المرنة (flex items). The first is the `flex-shrink` property. When it's used, it allows an item to shrink if the flex container is too small. Items shrink when the width of the parent container is smaller than the combined widths of all the flex items within it. -The `flex-shrink` property takes numbers as values. The higher the number, the more it will shrink compared to the other items in the container. For example, if one item has a `flex-shrink` value of `1` and the other has a `flex-shrink` value of `3`, the one with the value of `3` will shrink three times as much as the other. +الخاصية `flex-shrink` تأخذ الأرقام كقيم. وكلما ارتفع العدد، سيتقلص العدد مقارنة بالاصناف الأخرى في الحاوية. For example, if one item has a `flex-shrink` value of `1` and the other has a `flex-shrink` value of `3`, the one with the value of `3` will shrink three times as much as the other. # --instructions-- diff --git a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/create-decimal-numbers-with-javascript.md b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/create-decimal-numbers-with-javascript.md index aa074aa8881..20160798630 100644 --- a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/create-decimal-numbers-with-javascript.md +++ b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/create-decimal-numbers-with-javascript.md @@ -11,11 +11,11 @@ dashedName: create-decimal-numbers-with-javascript يمكننا تخزين أرقام عشرية في المتغيرات أيضا. يشار أحياناً إلى الأرقام العشرية على أنها أرقام نُقَط عائمة (floating point) أو عائمات (floats). -**ملاحظة:** عندما حساب الأرقام، يتم حسابها بدقة محدودة. وقد تؤدي العمليات التي تستخدم نُقَط عائمة إلى نتائج مختلفة عن النتائج المرجوة. إذا حصلت على واحدة من هذه النتائج، أفتح موضوع في منتدى freeCodeCamp. +**ملاحظة:** عندما تحسب الأرقام، يتم حسابها بدقة محدودة. وقد تؤدي العمليات التي تستخدم نُقَط عائمة إلى نتائج مختلفة عن النتائج المرغوبة. إذا حصلت على واحدة من هذه النتائج، أفتح موضوع في منتدى freeCodeCamp. # --instructions-- -أنشئ متغير `myDecimal` وإعطائه قيمة عشرية بجزء كسري (على سبيل المثال `5.7`). +أنشئ متغير `myDecimal` واعطه قيمة عشرية بجزء كسري (على سبيل المثال `5.7`). # --hints-- @@ -25,7 +25,7 @@ dashedName: create-decimal-numbers-with-javascript assert(typeof myDecimal === 'number'); ``` -يجب أن يحتوي `myDecimal` على نقطة عشرية +يجب أن يحتوي `myDecimal` على نقطة عشرية (decimal point) ```js assert(myDecimal % 1 != 0); diff --git a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md index ea0af524bf3..b17352c4795 100644 --- a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md +++ b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md @@ -21,7 +21,7 @@ i--; i = i - 1; ``` -**ملاحظة:** السطر بِرُمَّته يصبح `i--;`، وإلغاء الحاجة إلى علامة المساواة. +**ملاحظة:** السطر بكامله يصبح `i--;`، مما يزيل الحاجة إلى علامة المساواة. # --instructions-- diff --git a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/increment-a-number-with-javascript.md b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/increment-a-number-with-javascript.md index cc741af7a36..d5cea9e9c23 100644 --- a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/increment-a-number-with-javascript.md +++ b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/basic-javascript/increment-a-number-with-javascript.md @@ -21,7 +21,7 @@ i++; i = i + 1; ``` -**ملاحظة:** السطر بأكمله يصبح `i++;`، مما يزيل الحاجة إلى علامة المساواة (equal sign). +**ملاحظة:** السطر بالأكمل يصبح `i++;`، مما يزيل الحاجة إلى علامة المساواة (equal sign). # --instructions-- diff --git a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-map-method-to-extract-data-from-an-array.md b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-map-method-to-extract-data-from-an-array.md index 82e08157c9b..788d4ee7593 100644 --- a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-map-method-to-extract-data-from-an-array.md +++ b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-map-method-to-extract-data-from-an-array.md @@ -33,7 +33,7 @@ const names = users.map(user => user.name); console.log(names); ``` -ستعرض وحدة التحكم القيمة `[ 'John', 'Amy', 'camperCat' ]`. +سيعرض الكونسول القيمة `[ 'John', 'Amy', 'camperCat' ]`. # --instructions-- diff --git a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-reduce-method-to-analyze-data.md b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-reduce-method-to-analyze-data.md index 048e3aae50c..7d563d8038c 100644 --- a/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-reduce-method-to-analyze-data.md +++ b/curriculum/challenges/arabic/02-javascript-algorithms-and-data-structures/functional-programming/use-the-reduce-method-to-analyze-data.md @@ -47,7 +47,7 @@ const usersObj = users.reduce((obj, user) => { console.log(usersObj); ``` -ستعرض وحدة التحكم القيمة `{ John: 34, Amy: 20, camperCat: 10 }`. +سيعرض الكونسول القيمة `{ John: 34, Amy: 20, camperCat: 10 }`. # --instructions-- diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md index 4e648ec9b72..2c19676c986 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md @@ -1,6 +1,6 @@ --- id: bd7168d8c242eddfaeb5bd13 -title: Visualize Data with a Bar Chart +title: التمثيل البياني باستخدام مخطط الأعمدة challengeType: 3 forumTopicId: 301464 dashedName: visualize-data-with-a-bar-chart @@ -8,7 +8,7 @@ dashedName: visualize-data-with-a-bar-chart # --description-- -**Objective:** Build an app that is functionally similar to this: https://bar-chart.freecodecamp.rocks. +**متطلبات:** قم ببناء تطبيق يُشبه في وظيفته https://bar-chart.freecodecamp.rocks. Fulfill the below user stories and get all of the tests to pass. Use whichever libraries or APIs you need. Give it your own personal style. @@ -16,13 +16,13 @@ You can use HTML, JavaScript, CSS, and the D3 svg-based visualization library. T **User Story #1:** My chart should have a title with a corresponding `id="title"`. -**User Story #2:** My chart should have a `g` element x-axis with a corresponding `id="x-axis"`. +**قصة المستخدم الثانية 2#:**: يجب أن يحتوي المخطط علي عنصر `g` علي المحور x (الأفقي) مع `id="x-axis"`. -**User Story #3:** My chart should have a `g` element y-axis with a corresponding `id="y-axis"`. +**قصة المُستخدم الثالثة 3#:** يجب أن يحتوى المخطط علي عُنصر `g` علي المحور y (العمودي) مع `id="y-axis"`. **User Story #4:** Both axes should contain multiple tick labels, each with a corresponding `class="tick"`. -**User Story #5:** My chart should have a `rect` element for each data point with a corresponding `class="bar"` displaying the data. +**قصة المٌستخدم الخامسة 5#:** يَجب أن يحتوي المخطط على عُنصر من نوع `rect` لكل معلومة مع عرض للبيانات بواسطة سمة `class="bar"`. **User Story #6:** Each bar should have the properties `data-date` and `data-gdp` containing `date` and `GDP` values. diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-scatterplot-graph.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-scatterplot-graph.md index 7f1d00bb3d0..b6dbb4fad07 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-scatterplot-graph.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-projects/visualize-data-with-a-scatterplot-graph.md @@ -8,19 +8,19 @@ dashedName: visualize-data-with-a-scatterplot-graph # --description-- -**Objective:** Build an app that is functionally similar to this: https://scatterplot-graph.freecodecamp.rocks. +**متطلبات:** كم ببناء تطبيق يشبه في وظيفته https://scatterplot-graph.freecodecamp.rocks. Fulfill the below user stories and get all of the tests to pass. Use whichever libraries or APIs you need. Give it your own personal style. -يمكنك استخدام HTML و JavaScript و CSS و مكتبة التصوير المستندة D3. تطلب الاختبارات إنشاء محاور (axes) باستخدام خاصية المحور في D3، الذي يؤدي تِلْقائيًا إلى وضع علامات على طول المحور. وهذه العلامات لازمة لاجتياز اختبارات D3, لأن تُستخدم مواقعها لتحديد محاذاة العناصر المرسومة بيانيٍ. ستجد معلومات حول إنشاء محاور في . يتم الاستفسار عن العناصر المطلوبة DOM (غير متغيرة) في لحظة إجراء كل اختبار. إذا كنت تستخدم framework (مثل Vue على سبيل المثال)، قد تكون نتائج الاختبار غير دقيقة للمحتوى الديناميكي. ونأمل أن نستوعبها في المستقبل، ولكن هذه frameworks غير مدعومة حاليا لمشاريع D3. +يمكنك استخدام HTML و JavaScript و CSS و مكتبة التصوير المستندة D3. تطلب الاختبارات إنشاء المحاور (axes) باستخدام خاصية axis في D3، الذي يؤدي تِلْقائيًا إلى وضع علامات (ticks) على طول المحور. وهذه العلامات لازمة لاجتياز اختبارات D3, لأن مواقعها تُستخدم لتحديد محاذاة العناصر المرسومة بيانيٍ. ستجد معلومات حول إنشاء المحاور في . يتم الاستفسار عن العناصر المطلوبة DOM (non-virtual) في لحظة إجراء كل اختبار. إذا كنت تستخدم framework (مثل Vue على سبيل المثال)، قد تكون نتائج الاختبار غير دقيقة للمحتوى الديناميكي. ونأمل أن نستوعبها في المستقبل، ولكن هذه frameworks غير مدعومة حاليا لمشاريع D3. **قصة المستخدم 1:** يمكنني أن أرى عنصر title مع موافقه `id="title"`. -**قصة المستخدم 2:** يمكنني رؤية محور أفقي (x-axis) يوافق بمتغير يحتوي على `id="x-axis"`. +**قصة المستخدم 2:** يمكنني رؤية محور أفقي (x-axis) يحتوي على سمة `id="x-axis"`. -**قصة المستخدم 3:** يمكنني رؤية محور رئسي (y-axis) يوافق بمتغير يحتوي على `id="y-axis"`. +**قصة المستخدم 3:** يمكنني رؤية محور رئسي (y-axis) يحتوي على `id="y-axis"`. -**قصة المستخدم 4:** يمكنني أن أرى نقاط (dots) ولكل منها فئة (class) يسمى `dot`، التي تمثل البيانات التي يتم تخطيطها. +**قصة المستخدم 4:** يمكنني أن أرى نقاط (dots) ولكل منها فئة (class) `dot`، التي تمثل البيانات التي يتم رسمها. **قصة المستخدم 5:** كل نقطة يجب أن تحتوي على الخصائص `data-xvalue` و `data-yvalue` التي توافق القيم `x` و `y`. @@ -30,25 +30,25 @@ Fulfill the below user stories and get all of the tests to pass. Use whichever l **قصة المستخدم 8:** يجب أن توافق `data-yvalue` ونقطتها الموافقة مع النقطة/القيمة الموافقة على محور أفقي (y-axis). -**قصة المستخدم 9:** يمكننك رأيه تسميات علامة (tick) متعددة على المحور الرأسي (y-axis) مع تنسيق الوقت `%M:%S`. +**قصة المستخدم 9:** يمكننك رؤية تسميات علامة (tick) متعددة على المحور الرأسي (y-axis) مع تنسيق الوقت `%M:%S`. -**قصة المستخدم 10:** يمكننك رأيه تسميات علامة (tick) متعددة على المحور الأفقي (x-axis) الذي يظهر السنة. +**قصة المستخدم 10:** يمكننك رؤية تسميات علامة (tick) متعددة على المحور الأفقي (x-axis) الذي يظهر السنة. -**قصة المستخدم 11:** يمكننك رأيه نطاق (range) تسميات (labels) المحور الأفقي (x-axis) يقع ضمن نطاق بيانات المحور الأفقي (x-axis) فعلاً. +**قصة المستخدم 11:** يمكننك رؤية نطاق (range) تسميات (labels) المحور الأفقي (x-axis) يقع ضمن نطاق بيانات المحور الأفقي (x-axis) فعلاً. -**قصة المستخدم 12:** يمكننك رأيه نطاق (range) تسميات (labels) المحور الرأسي (y-axis) تقع ضمن نطاق بيانات المحور الرأسي (y-axis) فعلاً. +**قصة المستخدم 12:** يمكننك رؤية نطاق (range) تسميات (labels) المحور الرأسي (y-axis) تقع ضمن نطاق بيانات المحور الرأسي (y-axis) فعلاً. -**قصة المستخدم 13:** يمكننك رؤية legend تحتوي على نص وصفي يحتوي على `id="legend"`. +**قصة المستخدم 13:** يمكننك رؤية legend تحتوي على نص وصفي وله سمة `id="legend"`. -**قصة المستخدم 14:** يمكننك تحريك الفأرة (mouse) فوق منطقة ورأيه أدوات نصيحة (tooltip) موافق `id="tooltip"`، التي تعرض المزيد من المعلومات حول المنطقة. +**قصة المستخدم 14:** عند تحريك الفأر (mouse) فوق منطقة سترى أدوات نصيحة (tooltip) لها سمة `id="tooltip"`، وهي تعرض المزيد من المعلومات عن المنطقة. **قصة المستخدم 15:** يجب أن تحتوي تلميح أدواتك (tooltip) على خاصية `data-year` التي تتوافق مع `data-xvalue` في المنطقة النشطة. -إليك مجموعة البيانات التي ستحتاج إلى إكمال هذا المشروع: `https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json` +إليك مجموعة البيانات التي ستحتاج لإكمال هذا المشروع: `https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json` -You can build your project by using this CodePen template and clicking `Save` to create your own pen. Or you can use this CDN link to run the tests in any environment you like: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` +يمكنك بناء مشروعك عن طريق استخدام هذا نموذج CodePen والنقر على `Save` لإنشاء pen خاص بك. Or you can use this CDN link to run the tests in any environment you like: `https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js` -Once you're done, submit the URL to your working project with all its tests passing. +بمجرد أن تنتهي، ارسل عنوان URL لمشروعك مع اجتياز جميع الاختبارات. # --solutions-- diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-hover-effect-to-a-d3-element.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-hover-effect-to-a-d3-element.md index 5e51c08ff03..2162ce83531 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-hover-effect-to-a-d3-element.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-hover-effect-to-a-d3-element.md @@ -1,6 +1,6 @@ --- id: 587d7faa367417b2b2512bd4 -title: أضف تأثير عند تحرك المستخدم فوق عنصر (Hover Effect) إلى عنصر D3 +title: أضف تأثير عندما يحوم الماوس فوق عنصر (Hover Effect) D3 challengeType: 6 forumTopicId: 301469 dashedName: add-a-hover-effect-to-a-d3-element @@ -8,7 +8,7 @@ dashedName: add-a-hover-effect-to-a-d3-element # --description-- -من الممكن إضافة التأثيرات (effects) التي توضح العمود (bar) عندما يتحرك المستخدم فوقه (hovers) بالفأرة. حتى الآن، طبقت تصميم (style) لمستطيلات بواسطة طرق (methods) في D3 و SVG الموجودة داخلهم، ولكن يمكنك استعمال CSS أيضا. +من الممكن إضافة التأثيرات (effects) التي توضح العمود (bar) عندما يحوم الماوس فوقه (hovers). حتى الآن، طبقت تصميم (style) المستطيلات بواسطة طرق مدمجة (built-in methods) في D3 و SVG، ولكن يمكنك استعمال CSS أيضا. يمكنك تعيين فئة (class) من CSS إلى عناصر SVG مع طريقة (method) تسمى `attr()`. ثم تحتوي فئة الزائفة (pseudo-class) المسمى `:hover` على قواعد التصميم (style) الجديدة لأي تأثيرات عند تحرك المستخدم فوق عنصر (hover). diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md index 0412b2cc619..458f8ae61cd 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md @@ -8,17 +8,17 @@ dashedName: add-attributes-to-the-circle-elements # --description-- -أنشئت في التحدي السابق عناصر `circle` لكل نقطة في `dataset`، وربطهم بلوحة (canvas) في SVG. لكن D3 يحتاج إلى مزيد من المعلومات حول موضع (position) وحجم (size) كل `circle` لعرضها بشكل صحيح. +أنشئت في التحدي السابق عناصر `circle` لكل نقطة في `dataset`، وربطهم بلوحة (canvas) SVG. لكن D3 يحتاج إلى مزيد من المعلومات حول موقع (position) وحجم (size) كل `circle` لعرضها بشكل صحيح. -لدي `circle` في SVG ثلاث سمات (attributes) رئيسية. تكون السمات (attributes) المسمى `cx` و `cy` إحداثيات. ويخبروا D3 أين يضع (position) *مركز (center)* للشكل على اللوحة (canvas) من SVG. تغير سمة (attribute) نصف قطر (radius) (تكتب مثل: `r`) يأثر على حجم `circle`. +لدي `circle` في SVG ثلاث سمات (attributes) رئيسية. تكون السمات (attributes) المسمى `cx` و `cy` إحداثيات. ويخبروا D3 أين موقع (position) *مركز (center)* للشكل على لوحة (canvas) SVG. تغير سمة (attribute) نصف قطر (radius) (تكتب مثل: `r`) يأثر على حجم `circle`. -مثل مقياس الإحداثيات `y` داخل `rect`، تقاس `cy` داخل `circle` من الجزء العلوي للوحة (canvas) في SVG، ليس من الأسفل. +مثل مقياس الإحداثيات `rect` داخل `y`، تقاس `cy` داخل `circle` من الجزء العلوي للوحة (canvas) SVG، ليس من الأسفل. -تقدر السمات (attributes) الثلاث جميعها استخدام وظيفة تعيد تفعيل (callback function) لتحديد قيمها بشكل ديناميكي. تذكر أن جميع الطرق (methods) مرتبطة بوظيفة `data(dataset)` تفعّل مرة واحدة لكل عنصر في `dataset`. The `d` parameter in the callback function refers to the current item in `dataset`, which is an array for each point. You use bracket notation, like `d[0]`, to access the values in that array. +تستطيع جميع السمات (attributes) الثلاث باستخدام وظيفة لإعادة التفعيل (callback function) لتحديد قيمها بشكل ديناميكي. تذكر أن جميع الطرق (methods) المسلسلة بعد وظيفة `data(dataset)` تفعّل مرة واحدة لكل عنصر في `dataset`. تشير `d` في وظيفة إعادة التفعيل إلى العنصر الحالي في `dataset`، وهو قائمة لكل نقطة. استخدم رمز الأقواس، مثل `d[0]`، للوصول إلى القيم في تلك القائمة. # --instructions-- -Add `cx`, `cy`, and `r` attributes to the `circle` elements. The `cx` value should be the first number in the array for each item in `dataset`. The `cy` value should be based off the second number in the array, but make sure to show the chart right-side-up and not inverted. The `r` value should be `5` for all circles. +أضف السمات `cx` و `cy` و `r` إلى العناصر المسمى `circle`. The `cx` value should be the first number in the array for each item in `dataset`. The `cy` value should be based off the second number in the array, but make sure to show the chart right-side-up and not inverted. The `r` value should be `5` for all circles. # --hints-- diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md index 56bcac531c5..3b425d7ffd5 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md @@ -10,13 +10,13 @@ dashedName: add-document-elements-with-d3 يحتوي D3 على عدة طرق (methods) التي تسمح لك بإضافة وتغيير العناصر في وثيقتك. -تختار طريقة (method) تسمى `select()` عنصراً واحداً من الوثيقة. إنها تأخذ وسيط (argument) كاسم العنصر الذي تريده وتنتج نقطة لتواصل (node) من HTML للعنصر الأول في المستند الذي يطابق الاسم. Here's an example: +تختار طريقة (method) `select()` عنصراً واحداً من الوثيقة. إنها تأخذ اسم العنصر الذي تريده كمعطى (argument)، وتنتج node HTML لأول عنصر في المستند يطابق الاسم. Here's an example: ```js const anchor = d3.select("a"); ``` -يجد المثال السابق أول علامة رابط (anchor) في الصفحة ويحفظ نقطتها لتواصل (node) من HTML في المتغير `anchor`. يمكنك استخدام طريقة الاختيار (select) مع الطرق (methods) أخرى. The `d3` part of the example is a reference to the D3 object, which is how you access D3 methods. +يجد المثال السابق أول علامة رابط (anchor) في الصفحة ويحفظ HTML node لها في المتغير `anchor`. يمكنك استخدام طريقة الاختيار (selection) مع طرق (methods) أخرى. The `d3` part of the example is a reference to the D3 object, which is how you access D3 methods. Two other useful methods are `append()` and `text()`. diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/change-the-presentation-of-a-bar-chart.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/change-the-presentation-of-a-bar-chart.md index dd3fa7ae7aa..28e459bccdf 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/change-the-presentation-of-a-bar-chart.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/change-the-presentation-of-a-bar-chart.md @@ -1,6 +1,6 @@ --- id: 587d7fa8367417b2b2512bca -title: تغيير مخطط بياني شريطي (Bar Chart) +title: تغيير التقديم لمخطط الأعمدة (Bar Chart) challengeType: 6 forumTopicId: 301481 dashedName: change-the-presentation-of-a-bar-chart @@ -8,17 +8,17 @@ dashedName: change-the-presentation-of-a-bar-chart # --description-- -وأنشأ التحدي السابق مخطط بياني شريطي (bar chart)، ولكن هناك بعض التغييرات في التنسيق الذي يمكن أن تحسن: +وأنشأ التحدي السابق مخطط أعمدة (bar chart)، ولكن هناك بعض التغييرات في التنسيق الذي يمكن أن تحسنه: -1) إضافة مساحة بين كل شريط لفصله بصرياً، عن طريق إضافة هامش (margin) إلى CSS لفئة تسمى `bar` +1) إضافة مساحة بين كل عمود لفصله بصرياً، عن طريق إضافة هامش (margin) إلى CSS لفئة `bar` -2) زيادة ارتفاع (height) الأشرطة لإظهار الفرق في القيم بشكل أفضل، عن طريق ضرب (multiplying) القيمة في عدد لزيادة الارتفاع +2) زيادة ارتفاع (height) الأعمدة لإظهار الفرق في القيم بشكل أفضل، عن طريق ضرب (multiplying) القيمة في عدد لزيادة الارتفاع # --instructions-- -أولاً، أضف `margin` بقيمة `2px` إلى قئة `bar` في علامة `style`. بعد ذلك، غيّر وظيفة تعيد تفعيل في `style()` بحيث تنتج `10` أضعاف قيمة البيانات الأصلية (بالإضافة إلى `px`). +أولاً، أضف `margin` بقيمة `2px` إلى فئة `bar` في علامة `style`. بعد ذلك، غيّر وظيفة إعادة التفعيل في طريقة `style()` بحيث تنتج `10` أضعاف قيمة البيانات الأصلية (بالإضافة إلى نص `px`). -**ملاحظة:** ضرب كل نقطة بيانات *بنفس* الثابت فقط يغيّر الحجم. إنه مثل تكبير الصورة، الذي لا يغير المقصود من البيانات الأساسية. +**ملاحظة:** ضرب كل نقطة بيانات *بنفس* الرَّقَم الثابت يغيّر المقياس فقط. إنه مثل تكبير الصورة، الذي لا يغير المقصود من البيانات الأساسية. # --hints-- diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/create-a-linear-scale-with-d3.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/create-a-linear-scale-with-d3.md index a5f0ad3b674..8430009c519 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/create-a-linear-scale-with-d3.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/create-a-linear-scale-with-d3.md @@ -8,13 +8,13 @@ dashedName: create-a-linear-scale-with-d3 # --description-- -يملأ البيانات المرسومة كل من مخطط بياني شريطي وانسياب (النِّقَاط المبعثرة) على لوحة SVG قاصدًا. بيد أنه إذا كان ارتفاع الشريط أو إحدى نِقَاط البيانات أكبر من الارتفاع أو العرض SVG، ستذهب خارج نطاق SVG. +رَسَم البيانات كلا من المخطوطان, أعمدة وانسياب (النِّقَاط المبعثرة), مباشرا على لوحة SVG. ولكن إذا كان ارتفاع العمود أو إحدى نِقَاط البيانات أكبر من ارتفاع أو عرض مساحة SVG، سيقع خارج نطاق منطقة SVG. -في D3، هناك مقاييس للمساعدة في ملأ البيانات. تكون `scales` وظائف (functions) تخبر البرنامَج كيفية ملأ مجموعة من نِقَاط البيانات الخام على البكسلات (px) في لوحة SVG. +في D3، هناك مقاييس (scales) للمساعدة في تخطيط البيانات. تكون `scales` وظائف (functions) تخبر البرنامَج كيفية ملأ مجموعة من نِقَاط البيانات الخام على عدد البكسلس (pixels) في لوحة SVG. -على سبيل المثال، قل أن لديك لوحة SVG بحجم 100x500، وأنت تريد ملأ الناتج إجمال المحلي (Gross Domestic Product) لعدد من الدول. ومجموعة الأعداد ستكون في حدود المليار أو تريليون دولار. يمكنك توفير D3 من المقياس لمعرفة كيفية وضع قيم الناتج المحلي الإجمالي الكبيرة في تلك المساحة 100x500. +على سبيل المثال، قل أن لديك لوحة SVG بحجم 100x500، وتريد رسم الناتج المحلي الإجمالي (Gross Domestic Product) لعدد من الدول. ومجموعة الأعداد ستكون في حدود المليار أو تريليون دولار. يمكنك توفير D3 من مقياس (scale) لمعرفة كيف توضع قيم الناتج المحلي الإجمالي (GDP) الكبيرة في تلك المساحة 100x500. -من غير المحتمل أن تملأ البيانات الخام كما هي. قبل الملأ، عيّن المقياس لكامل مجموعتك للبيانات. بحيث أن قيم `x` و `y` تتناسب مع عرض وطول اللوحة. +من غير المحتمل أن ترسم البيانات الخام كما هي. قبل الرسم، عيّن المقياس لكامل مجموعة البيانات. بحيث أن قيم `x` و `y` تتناسب مع عرض وطول اللوحة. ولدى D3 عدة أنواع من المقاييس. للحصول على مقياس خطي (linear scale) (يستخدم عادة مع البيانات الكمية (quantitative data))، هناك طريقة في D3 تسمى `scaleLinear()`: @@ -22,11 +22,11 @@ dashedName: create-a-linear-scale-with-d3 const scale = d3.scaleLinear() ``` -بشكل افتراضي، يستخدم المقياس عَلاقة الهُوِيَّة (identity relationship). تطابق قيمة المدخل (Input) قيمة المخرج (output). يشمل تحد أخر كيفية تغيير ذلك. +بشكل افتراضي، يستخدم المقياس عَلاقة الهُوِيَّة (identity relationship). تطابق قيمة المدخل (input) قيمة المخرج (output). يشمل تحدي أخر كيفية تغيير ذلك. # --instructions-- -تغيير متغير (variable) مسمى `scale` لإنشاء مقياس خطي (linear scale). ثم عيّن متغير (variable) مسمى `output` إلى scale, الذي فعلته بالإدخال وسيط بقيمة `50`. +غيّر المتغير `scale` لإنشاء مقياس خطي (linear scale). ثم عيّن متغير `output` إلى وظيفة scale, الذي فعَِلت بإدخال معطى بقيمة `50`. # --hints-- @@ -36,13 +36,13 @@ const scale = d3.scaleLinear() assert($('h2').text() == '50'); ``` -يجب أن يستخدم كودك طريقة (method) تسمى `scaleLinear()`. +يجب أن يستخدم كودك طريقة `scaleLinear()`. ```js assert(code.match(/\.scaleLinear/g)); ``` -يجب أن يُفاعِل متغير `output` وظيفة `scale` مع وسيط `50`. +يجب أن يُفعَِل متغير `output` وظيفة `scale` مع معطى `50`. ```js assert(output == 50 && code.match(/scale\(\s*?50\s*?\)/g)); diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.md index 01bdb04afa2..aea916fbe20 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/dynamically-set-the-coordinates-for-each-bar.md @@ -1,6 +1,6 @@ --- id: 587d7fa9367417b2b2512bce -title: تعيين الإحداثيات ديناميكيا لكل شريط +title: تعيين الإحداثيات ديناميكيا لكل عمود challengeType: 6 forumTopicId: 301487 dashedName: dynamically-set-the-coordinates-for-each-bar @@ -8,13 +8,13 @@ dashedName: dynamically-set-the-coordinates-for-each-bar # --description-- -التحدي السابق أنشئت وألحقت مستطيل بعنصر `svg` لكل نقطة في `dataset` لتستعرض شريط. لسوء الحظ، كانوا مكدسين بعضَهم فوق بعض. +The last challenge created and appended a rectangle to the `svg` element for each point in `dataset` to represent a bar. لسوء الحظ، كانوا مكدسين بعضَهم فوق بعض. -يمكنك تحكم في موضع المستطيل بواسطة أستخدام سمات (attributes) تسمى `x` و `y`. لتخبر D3 أين يبدأ في رسم الشكل في منطقة `svg`. قام التحدي السابق بتحديدهم إلى صفر، لذلك تم وضع كل عمود (bar) في الزاوية العلوية اليسرى. +التحكم في موقع المستطيل يكون بواسطة سمات (attributes) `x` و `y`. فانهم يخبرون D3 أين يبدأ في رسم الشكل في منطقة `svg`. قام التحدي السابق بتحديدهم إلى صفر، لذلك تم وضع كل عمود (bar) في الزاوية العلوية اليسرى. -للحصول على مخطط بياني شريطي (bar chart)، يجب أن تجلس جميع الشريط على نفس المستوى العمودي، مما يعني أن قيمة `y` تبقى هي نفسها (عند 0) لجميع الأشرطة. ومع ذلك، تحتاج قيمة `x` إلى التغيير عند إضافة الشريط جديد. تذكر أن أكبر قيم من `x` تدفع العناصر إلى أقصى اليمين. عندما تمر عبر عناصر القائمة في `dataset`، يجب أن تزيد قيمة `x`. +للحصول على مخطط أعمدة (bar chart)، يجب أن تجلس جميع الأعمدة على نفس المستوى العمودي، مما يعني أن قيمة `y` تبقى هي نفسها (عند 0) لجميع الأعمدة. أما قيمة `x` عليها أن نتغير عندما تضيف أعمدة جديدة. تذكر أن القيم الأكبر في `x` تدفع العناصر أبعد إلى اليمين. عندما تمر عبر عناصر القائمة في `dataset`، يجب أن تزيد قيمة `x`. -تقبل طريقة (method) تسمى `attr()` في D3 الوظيفة تعيد تفعيل (callback functon) التي تعيين تلك السمة ديناميكيا. وظيفة تعيد تفعيل (callback functon) تأخذ حجيتين (arguments)، واحد لنقطة البيانات نفسها (عادة `d`) وواحد لترتيب نقطة البيانات في القائمة (array). أما الحِجَّة (argument) الثانية تدل على الترتيب فهي حِجَّة اختيارية. إليك التنسيق: +تقبل طريقة (method) `attr()` في D3 وظيفة إعادة التفعيل (callback functon) التي تعيين تلك السمة ديناميكيا. تأخذ وظيفة إعادة التفعيل (callback functon) معطيين (arguments)، واحد لنقطة البيانات نفسها (عادة `d`) وواحد لرقم ترتيب (index) نقطة البيانات في القائمة (array). أما المعطى (argument) الثاني لرقم الترتيب فهو معطى اختياري. إليك التنسيق: ```js selection.attr("property", (d, i) => { @@ -22,13 +22,13 @@ selection.attr("property", (d, i) => { }) ``` -من المهم مُراعاةٌ أنك لا تحتاج إلى كتابة حلقة (loop) نوعها `for` أو استخدام `forEach()` لتكرار العناصر في مجموعة البيانات (data set). تذكر أن طريقة `data()` تحلل مجموعة البيانات (data set), وأي طريقة تتبع `data()` يتم تشغيلها مرة واحدة لكل عنصر في مجموعة البيانات. +من المهم ملاحظة أنك لن تحتاج إلى كتابة حلقة (loop) نوعها `for` أو `forEach()` لتعيد على العناصر في مجموعة البيانات (data set). تذكر أن طريقة `data()` تحلل مجموعة البيانات (data set), وأي طريقة مسلسة تتبع `data()` سيتم تشغيلها مرة واحدة لكل عنصر في مجموعة البيانات. # --instructions-- -غيّر سمة `x` في وظيفة تعيد تفعيل بحيث ترجع الترتيب 30 مرة. +غيّر وظيفة إعادة التفعيل لسمة `x` بحيث تنتج رَقَم الترتيب 30 مرة. -**ملاحظة:** كل عمود له عرض (width) بقيمة 25، لذا زيادة كل قيمة `x` بمقدار 30 تضيف بعض المساحة بين الأشرطة. أي قيمة أكبر من 25 ستنجح في هذا المثال. +**ملاحظة:** كل عمود له عرض (width) بقيمة 25، لذا زيادة كل قيمة `x` بمقدار 30 ستضيف بعض المساحة بين الأشرطة. أي قيمة أكبر من 25 ستنجح في هذا المثال. # --hints-- diff --git a/curriculum/challenges/arabic/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.md b/curriculum/challenges/arabic/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.md index b2bf1b3f2de..479f3844675 100644 --- a/curriculum/challenges/arabic/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.md +++ b/curriculum/challenges/arabic/04-data-visualization/json-apis-and-ajax/handle-click-events-with-javascript-using-the-onclick-property.md @@ -1,6 +1,6 @@ --- id: 587d7fad367417b2b2512be1 -title: التعامل مع أحداث النقر (Handle Click Events) مع JavaScript باستخدام خاصية عند النقر (onclick) +title: التعامل مع أحداث النقر (Handle Click Events) مع JavaScript باستخدام خاصية onclick عند النقر challengeType: 6 forumTopicId: 301503 dashedName: handle-click-events-with-javascript-using-the-onclick-property @@ -8,7 +8,7 @@ dashedName: handle-click-events-with-javascript-using-the-onclick-property # --description-- -تريد تنفذ كودك بمجرد الانتهاء من تحميل الصفحة, مرة واحدة فقط. لهذا الغرض، يمكنك إرفاق حدث (event) من JavaScript لمستند مسمى `DOMContentLoaded`. إليك كود الذي يفعل ذلك: +تريد أن ينفذ كودك فقط عندما ينتهي تحميل الصفحة. لهذا الغرض، يمكنك إرفاق حدث (event) من JavaScript لمستند مسمى `DOMContentLoaded`. إليك الكود الذي يفعل ذلك: ```js document.addEventListener('DOMContentLoaded', function() { @@ -24,11 +24,11 @@ document.getElementById('getMessage').onclick = function(){}; # --instructions-- -أضف معالج أحداث النقر داخل وظيفة `DOMContentLoaded` للعنصر مع معرف `getMessage`. +أضف معالج الأحداث (event handler) داخل وظيفة `DOMContentLoaded` للعنصر الذي له id قيمته `getMessage`. # --hints-- -يجب أن تستخدم كودك طريقة `document.getElementById` لتحديد عنصر `getMessage`. +يجب أن يستخدم كودك طريقة `document.getElementById` لتحديد عنصر `getMessage`. ```js assert(code.match(/document\s*\.getElementById\(\s*?('|")getMessage\1\s*?\)/g)); diff --git a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md index 85a86b395a9..a233fad342e 100644 --- a/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md +++ b/curriculum/challenges/arabic/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md @@ -42,9 +42,9 @@ Transfer to Clothing -50.00 Total: 923.96 ``` -Besides the `Category` class, create a function (outside of the class) called `create_spend_chart` that takes a list of categories as an argument. يجب أن تنتج مخطط بياني للأعمدة بصيغة string. +Besides the `Category` class, create a function (outside of the class) called `create_spend_chart` that takes a list of categories as an argument. يجب أن تنتج مخطط أعمدة بصيغة string. -The chart should show the percentage spent in each category passed in to the function. The percentage spent should be calculated only with withdrawals and not with deposits. Down the left side of the chart should be labels 0 - 100. كل عمود من مخطط بياني للأعمدة يتكون من رمز " o". The height of each bar should be rounded down to the nearest 10. The horizontal line below the bars should go two spaces past the final bar. Each category name should be written vertically below the bar. There should be a title at the top that says "Percentage spent by category". +The chart should show the percentage spent in each category passed in to the function. The percentage spent should be calculated only with withdrawals and not with deposits. Down the left side of the chart should be labels 0 - 100. يتكون كل عمود من مخطط ألأعمدة من الحرف " o". The height of each bar should be rounded down to the nearest 10. The horizontal line below the bars should go two spaces past the final bar. Each category name should be written vertically below the bar. There should be a title at the top that says "Percentage spent by category". This function will be tested with up to four categories. diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md index dc1c868f2ae..07e756d1788 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md @@ -7,13 +7,13 @@ dashedName: step-15 # --description-- -In previous steps you used an anchor element to turn text into a link. Other types of content can also be turned into a link by wrapping it in anchor tags. +في الخطوات السابقة كنت تستخدم عنصر الرابط لتحويل النص إلى رابط. ويمكن أيضا تحويل أنواع أخرى من المحتوى إلى رابط عن طريق وضعه بداخل عنصر الرابط. -Turn the image into a link by surrounding it with necessary element tags. Use `https://freecatphotoapp.com` as the anchor's `href` attribute value. +حول الصورة إلى رابط عن طريق إحاطتها بعلامات العنصر المناسب. استخدم `https://freecatphotoapp.com` كقيمة السمة `href`. # --hints-- -You should have an `img` element with an `src` value of `https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`. You may have accidentally deleted it. +يجب أن يكون لديك عنصر `img` بقيمة `src` من `https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`. ربما حذفتها عن طريق الخطأ. ```js assert( @@ -23,37 +23,37 @@ assert( ); ``` -Your anchor (`a`) element should have an opening tag. Opening tags have this syntax: ``. +يجب أن يحتوي العنصر (`a`) على علامة الفتح. تكتب علامات الفتح هكذا: ``. ```js assert(document.querySelectorAll('a').length >= 2); ``` -You should only add one opening anchor (`a`) tag. Please remove any extras. +يجب عليك إضافة علامة فتح واحد فقط لـ (`a`). الرجاء إزالة أي زيادات. ```js assert(document.querySelectorAll('a').length === 2); ``` -Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character. +يجب أن يحتوي العنصر (`a`) على علامة غلق. يجب أن تأتي علامات الغلق بـ `/` بعد رمز `<` مباشرة. ```js assert(code.match(/<\/a>/g).length >= 2); ``` -You should only add one closing anchor (`a`) tag. Please remove any extras. +يجب عليك إضافة علامة غلق واحد فقط لـ (`a`). الرجاء إزالة أي زيادات. ```js assert(code.match(/<\/a>/g).length === 2); ``` -Your anchor (`a`) element does not have an `href` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names. +ليس لدي عنصرك (`a`) سمة `href`. تيقن من وجود مسافة بعد اسم علامة الفتح و/أو أن هناك مسافات قبل جميع أسماء السمات. ```js assert(document.querySelector('a').hasAttribute('href')); ``` -Your anchor (`a`) element should link to `https://freecatphotoapp.com`. You have either omitted the URL or have a typo. +يجب أن يربط عنصرك (`a`) إلى `https://freecatphotoapp.com`. إما أنك حذفت الرابط (URL) أو لديك خطأ إملائي. ```js assert( @@ -62,7 +62,7 @@ assert( ); ``` -Your `img` element should be nested within the anchor (`a`) element. The entire `img` element should be inside the opening and closing tags of the anchor (`a`) element. +يجب أن يدخل عنصرك `img` داخل عنصر الرابط (`a`). يجب أن يكون عنصر `img` كله داخل العلامات فتح و العلامات غلق لعنصر الرابط (`a`). ```js assert(document.querySelector('img').parentNode.nodeName === 'A'); diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md index d55f677627d..e43c148527e 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md @@ -55,7 +55,7 @@ assert.deepStrictEqual( ); ``` -You should only have one `ol` element. +يجب أن يكون لديك عنصر `ol` واحد فقط. ```js assert([...document.querySelectorAll('ol')].length == 1); diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md index d8ddc5519a8..f648de78ef9 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md @@ -22,7 +22,7 @@ assert( ); ``` -Your first radio button, with the `id` set to `indoor`, should have the `checked` attribute. +زرك الراديو الأول، مع `id` بقيمة `indoor`، يجب أن يكون `checked`. ```js assert($('input[type="radio"]')[0].hasAttribute('checked')); diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md index d36e2c1257a..7042c4ca854 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md @@ -9,7 +9,7 @@ dashedName: step-56 هناك طريقة أخرى لربط نص عنصر `input` بالعنصر نفسه. يمكنك دمج النص ضمن عنصر `label` وإضافة سمة `for` بنفس القيمة كسمة `id` لعنصر `input`. -Associate the text `Loving` with the checkbox by nesting only the text `Loving` in a `label` element and giving it an appropriate `for` attribute. +اربط النص `Loving` مع checkbox بواسطة إدخال النص `Loving` فقط في عنصر `label` وإعطائه السمة `for`. # --hints-- diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md index bbafe28bd97..dc8634ecfa5 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md @@ -7,7 +7,7 @@ dashedName: step-53 # --description-- -بعد آخر `.divider`، قم بإنشاء عنصر `p` آخر مع النص `Cholesterol 0mg 0%`. قم بتغليف النص `Cholesterol` في عنصر `span`، واعطي عنصر `span` هذا السمة `class` بقيمة `bold`. غلف نص `0%` داخل `span` أخرى، مع `class` بقيمة `bold`. Finally, nest the `Cholesterol` and `0mg` `span` elements inside an additional `span` element for alignment. +بعد آخر `.divider`، قم بإنشاء عنصر `p` آخر مع النص `Cholesterol 0mg 0%`. قم بتغليف النص `Cholesterol` في عنصر `span`، واعطي عنصر `span` هذا السمة `class` بقيمة `bold`. غلف نص `0%` داخل `span` أخرى، مع `class` بقيمة `bold`. أخيرا، أدخل عناصر `span` التي تحتوي على `Cholesterol` و `0mg` داخل عنصر `span` إضافي للمحاذاة. # --hints-- diff --git a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/expand-your-project-with-external-packages-from-npm.md b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/expand-your-project-with-external-packages-from-npm.md index 3edd72d2910..cf503cd449a 100644 --- a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/expand-your-project-with-external-packages-from-npm.md +++ b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/expand-your-project-with-external-packages-from-npm.md @@ -22,7 +22,7 @@ In questa sezione, i pacchetti richiesti dal progetto vengono memorizzati nel se # --instructions-- -Add version `1.1.0` of the `@freecodecamp/example` package to the `dependencies` field of your `package.json` file. +Aggiungi la versione `1.1.0` del pacchetto `@freecodecamp/example` al campo `dependencies` del tuo file `package.json`. **Nota:** `@freecodecamp/example` è un pacchetto fasullo utilizzato come strumento di apprendimento. diff --git a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/how-to-use-package.json-the-core-of-any-node.js-project-or-npm-package.md b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/how-to-use-package.json-the-core-of-any-node.js-project-or-npm-package.md index 2899eb8daae..2bad1871a58 100644 --- a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/how-to-use-package.json-the-core-of-any-node.js-project-or-npm-package.md +++ b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/how-to-use-package.json-the-core-of-any-node.js-project-or-npm-package.md @@ -22,9 +22,9 @@ Se utilizzi Replit, segui questi passaggi per impostare il progetto: Quando hai finito, assicurati che una demo funzionante del tuo progetto sia ospitata in qualche percorso pubblico. Quindi invia l'URL nel campo Link alla soluzione. -Il file `package.json` è il centro di qualsiasi progetto Node.js o pacchetto npm. It stores information about your project, similar to how the `head` section of an HTML document describes the content of a webpage. Consiste di un singolo oggetto JSON dove le informazioni sono memorizzate in coppie chiave-valore. There are only two required fields; `name` and `version`, but it’s good practice to provide additional information about your project that could be useful to future users or maintainers. +Il file `package.json` è il centro di qualsiasi progetto Node.js o pacchetto npm. Memorizza informazioni sul tuo progetto, in modo simile a come la sezione `head` di un documento HTML descrive il contenuto di una pagina web. Consiste di un singolo oggetto JSON dove le informazioni sono memorizzate in coppie chiave-valore. Ci sono solo due campi obbligatori: `name` e `version`, ma è buona pratica fornire ulteriori informazioni sul tuo progetto che potrebbero essere utili per futuri utenti o manutentori. -If you look at the file tree of your project, you will find the `package.json` file on the top level of the tree. Questo è il file che andremo a migliorare nelle prossime due sfide. +Se guardi l'albero dei file del tuo progetto, troverai il file `package.json` al livello superiore dell'albero. Questo è il file che andremo a migliorare nelle prossime due sfide. Una delle informazioni più comuni in questo file è il campo `author`. Specifica chi ha creato il progetto e può consistere in una stringa o un oggetto con informazioni di contatto o altri dettagli. Un oggetto è consigliato per progetti più grandi, ma una semplice stringa come l'esempio seguente farà al caso nostro per questo progetto. @@ -34,13 +34,13 @@ Una delle informazioni più comuni in questo file è il campo `author`. Specific # --instructions-- -Add your name as the `author` of the project in the `package.json` file. +Aggiungi il tuo nome come `author` del progetto nel file `package.json`. **Nota:** Ricorda che stai scrivendo JSON, quindi tutti i nomi dei campi devono usare virgolette doppie (") ed essere separati con una virgola (,). # --hints-- -`package.json` should have a valid "author" key +`package.json` dovrebbe avere una chiave "author" valida ```js (getUserInput) => diff --git a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-caret-character-to-use-the-latest-minor-version-of-a-dependency.md b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-caret-character-to-use-the-latest-minor-version-of-a-dependency.md index 134353fd9f9..8cab45a2940 100644 --- a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-caret-character-to-use-the-latest-minor-version-of-a-dependency.md +++ b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-caret-character-to-use-the-latest-minor-version-of-a-dependency.md @@ -10,13 +10,13 @@ dashedName: use-the-caret-character-to-use-the-latest-minor-version-of-a-depende Simile a come la tilde vista nell'ultima sfida permette a npm di installare l'ultima PATCH per una dipendenza, l'accento circonflesso (caret, `^`) permette a npm di installare anche aggiornamenti futuri. La differenza è che l'accento circonflesso permette sia aggiornamenti di versione minore che di Patch. -Your current version of `@freecodecamp/example` should be `~1.2.13` which allows npm to install to the latest `1.2.x` version. If you were to use the caret (^) as a version prefix instead, npm would be allowed to update to any `1.x.x` version. +La versione attuale di `@freecodecamp/example` dovrebbe essere `~1.2.13` che permette a npm di installare l'ultima versione `1.2.x`. Se invece dovessi usare il caret (^) come prefisso di versione, npm avrebbe il permesso di aggiornare a qualsiasi versione `1.x.x`. ```json "package": "^1.3.8" ``` -This would allow updates to any `1.x.x` version of the package. +Questo permetterebbe di aggiornare qualsiasi versione `1.x.x` del pacchetto. # --instructions-- diff --git a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-dependency.md b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-dependency.md index b326de9d8ed..51a321b5d06 100644 --- a/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-dependency.md +++ b/curriculum/challenges/italian/05-back-end-development-and-apis/managing-packages-with-npm/use-the-tilde-character-to-always-use-the-latest-patch-version-of-a-dependency.md @@ -10,7 +10,7 @@ dashedName: use-the-tilde-character-to-always-use-the-latest-patch-version-of-a- Nell'ultima sfida, hai detto a npm di includere solo una versione specifica di un pacchetto. Questo è un modo utile per congelare le tue dipendenze, se hai bisogno di assicurarti che diverse parti del tuo progetto rimangano compatibili tra loro. Ma nella maggior parte dei casi d'uso, non vuoi perdere le correzioni di bug dal momento che spesso includono importanti patch di sicurezza e (si spera) non rompono le cose nel farlo. -Per consentire a una dipendenza npm di aggiornare all'ultima versione PATCH, è possibile prefissare la versione della dipendenza con il carattere tilde (`~`). Here's an example of how to allow updates to any `1.3.x` version. +Per consentire a una dipendenza npm di aggiornare all'ultima versione PATCH, è possibile prefissare la versione della dipendenza con il carattere tilde (`~`). Ecco un esempio di come consentire gli aggiornamenti di qualsiasi versione `1.3.x`. ```json "package": "~1.3.8" @@ -18,7 +18,7 @@ Per consentire a una dipendenza npm di aggiornare all'ultima versione PATCH, è # --instructions-- -In the package.json file, your current rule for how npm may upgrade `@freecodecamp/example` is to use a specific version (`1.2.13`). But now, you want to allow the latest `1.2.x` version. +Nel file package.json, la regola con cui npm aggiorna `@freecodecamp/example` si basa su una specifica versione (`1.2.13`). Ma ora desideriamo consentire l'ultima versione `1.2.x`. Usa il carattere tilde (`~`) come prefisso di versione per `@freecodecamp/example` nelle tue dipendenze e permetti ad npm di aggiornare ad ogni nuova versione di _patch_. diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md index 54659e23189..c70339a5a7c 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/6148da157cc0bd0d06df5c0a.md @@ -7,7 +7,7 @@ dashedName: step-57 # --description-- -To align the input boxes with each other, create a new ruleset that targets all `input` and `label` elements within an `.info` element and set the `display` property to `inline-block`. +Per allineare le caselle di input tra loro, crea un nuovo set di regole che seleziona tutti gli elementi `input` e `label` all'interno di un elemento `.info` e imposta la proprietà `display` su `inline-block`. Inoltre allinea il testo dell'elemento `label` sulla destra. diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md index 0bc192c1cbc..4ddf50cc08f 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5dfa30b9eacea3f48c6300ad.md @@ -7,13 +7,13 @@ dashedName: step-15 # --description-- -In previous steps you used an anchor element to turn text into a link. Other types of content can also be turned into a link by wrapping it in anchor tags. +Nei passaggi precedenti hai usato un elemento di ancoraggio per trasformare il testo in un link. Anche altri tipi di contenuto possono essere trasformati in un link racchiudendoli in tag di ancoraggio. -Turn the image into a link by surrounding it with necessary element tags. Use `https://freecatphotoapp.com` as the anchor's `href` attribute value. +Trasforma l'immagine in un link circondandola con i tag necessari. Usa `https://freecatphotoapp.com` come valore dell'attributo dell'elemento di ancoraggio `href`. # --hints-- -You should have an `img` element with an `src` value of `https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`. You may have accidentally deleted it. +Dovresti avere un elemento `img` con un valore `src` di `https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg`. Potresti averlo eliminato accidentalmente. ```js assert( @@ -23,37 +23,37 @@ assert( ); ``` -Your anchor (`a`) element should have an opening tag. Opening tags have this syntax: ``. +L'elemento di ancoraggio (`a`) dovrebbe avere un tag di apertura. I tag di apertura hanno questa sintassi: ``. ```js assert(document.querySelectorAll('a').length >= 2); ``` -You should only add one opening anchor (`a`) tag. Please remove any extras. +Dovresti aggiungere un solo tag di apertura di ancoraggio (`a`). Rimuovi quelli di troppo. ```js assert(document.querySelectorAll('a').length === 2); ``` -Your anchor (`a`) element should have a closing tag. Closing tags have a `/` just after the `<` character. +L'elemento di ancoraggio (`a`) dovrebbe avere un tag di chiusura. I tag di chiusura hanno un carattere `/` subito dopo il carattere `<`. ```js assert(code.match(/<\/a>/g).length >= 2); ``` -You should only add one closing anchor (`a`) tag. Please remove any extras. +Dovresti aggiungere un solo tag di chiusura di ancoraggio (`a`). Rimuovi quelli di troppo. ```js assert(code.match(/<\/a>/g).length === 2); ``` -Your anchor (`a`) element does not have an `href` attribute. Check that there is a space after the opening tag's name and/or there are spaces before all attribute names. +L'elemento di ancoraggio (`a`) non ha un attributo `href`. Verifica che ci sia uno spazio dopo il nome del tag di apertura e/o che ci siano spazi prima di tutti i nomi degli attributi. ```js assert(document.querySelector('a').hasAttribute('href')); ``` -Your anchor (`a`) element should link to `https://freecatphotoapp.com`. You have either omitted the URL or have a typo. +L'elemento di ancoraggio (`a`) dovrebbe contenere il link `https://freecatphotoapp.com`. Hai omesso l'URL o hai un refuso. ```js assert( @@ -62,7 +62,7 @@ assert( ); ``` -Your `img` element should be nested within the anchor (`a`) element. The entire `img` element should be inside the opening and closing tags of the anchor (`a`) element. +L'elemento `img` dovrebbe essere annidato all'interno dell'elemento di ancoraggio (`a`). L'intero elemento `img` dovrebbe essere all'interno dei tag di apertura e chiusura dell'elemento di ancoraggio (`a`). ```js assert(document.querySelector('img').parentNode.nodeName === 'A'); diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md index 1a1508836a3..8db73986b49 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804d2.md @@ -55,7 +55,7 @@ assert.deepStrictEqual( ); ``` -You should only have one `ol` element. +Dovresti avere un solo elemento `ol`. ```js assert([...document.querySelectorAll('ol')].length == 1); diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md index d9704e6be8f..39cb3d81e86 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5ef9b03c81a63668521804e5.md @@ -22,7 +22,7 @@ assert( ); ``` -Your first radio button, with the `id` set to `indoor`, should have the `checked` attribute. +Il primo pulsante di opzione con l'`id` impostato su `indoor` dovrebbe avere l'attributo `checked`. ```js assert($('input[type="radio"]')[0].hasAttribute('checked')); diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md index a55d67d8d15..3eb264c5838 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-html-by-building-a-cat-photo-app/5efc4f528d6a74d05e68af74.md @@ -9,7 +9,7 @@ dashedName: step-56 C'è un altro modo per associare il testo di un elemento `input` con l'elemento stesso. Puoi annidare il testo all'interno di un elemento `label` e aggiungere un attributo `for` con lo stesso valore dell'attributo `id` dell'elemento `input`. -Associate the text `Loving` with the checkbox by nesting only the text `Loving` in a `label` element and giving it an appropriate `for` attribute. +Associa il testo `Loving` alla casella di spunta annidando solo il testo `Loving` in un elemento `label` e dandogli un attributo `for` appropriato. # --hints-- diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md index 897c5bc84bb..815e839e1f3 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f7de4487b64919bb4aa5e.md @@ -7,7 +7,7 @@ dashedName: step-53 # --description-- -Dopo l'ultimo elemento `.divider`, crea un elemento `p` e dagli il testo `Cholesterol 0mg 0%`. Inserisci il testo `Cholesterol` in un elemento `span` e assegna a quest'elemento `span` un attributo `class` con il valore `bold`. Annida il testo `0%` in un altro elemento `span` con l'attributo `class` impostato su `bold`. Finally, nest the `Cholesterol` and `0mg` `span` elements inside an additional `span` element for alignment. +Dopo l'ultimo elemento `.divider`, crea un elemento `p` e dagli il testo `Cholesterol 0mg 0%`. Inserisci il testo `Cholesterol` in un elemento `span` e assegna a quest'elemento `span` un attributo `class` con il valore `bold`. Annida il testo `0%` in un altro elemento `span` con l'attributo `class` impostato su `bold`. Infine annida gli elementi `span` `Cholesterol` e `0mg` all'interno di un altro elemento `span` per l'allineamento. # --hints-- diff --git a/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/check-for-mixed-grouping-of-characters.md b/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/check-for-mixed-grouping-of-characters.md index a052410c3b6..e3dce1b3584 100644 --- a/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/check-for-mixed-grouping-of-characters.md +++ b/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/check-for-mixed-grouping-of-characters.md @@ -78,7 +78,7 @@ You should use `.test()` to test the regex. assert(code.match(/myRegex.test\(\s*myString\s*\)/)); ``` -Your result should return `true`. +У результаті ви повинні отримати `true`. ```js assert(result === true); diff --git a/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/using-the-test-method.md b/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/using-the-test-method.md index 90808dbfbff..1f5e81b2198 100644 --- a/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/using-the-test-method.md +++ b/curriculum/challenges/ukrainian/02-javascript-algorithms-and-data-structures/regular-expressions/using-the-test-method.md @@ -12,7 +12,7 @@ dashedName: using-the-test-method Якщо ви хочете знайти слово `the` у рядку `The dog chased the cat`, то можете використати наступний регулярний вираз: `/the/`. Зверніть увагу на те, що лапки в регулярному виразі не потрібні. -JavaScript має декілька способів використання регулярних виразів. Один із способів тестування регулярного виразу - це використання методу `.test()`. Метод `.test()` приймає регулярний вираз, застосовує його до рядка (який розміщений всередині дужок), і видає `true` чи `false`, якщо ваш шаблон знаходить щось або ні. +JavaScript має декілька способів використання регулярних виразів. Один зі способів тестування регулярного виразу – це використання методу `.test()`. Метод `.test()` приймає регулярний вираз, застосовує його до рядка (який розміщений всередині дужок), і видає `true` чи `false`, якщо ваш шаблон знаходить щось або ні. ```js let testStr = "freeCodeCamp"; @@ -24,7 +24,7 @@ testRegex.test(testStr); # --instructions-- -Застосуйте регулярний вираз `myRegex` до рядка `myString` за допомогою методу `.test()` method. +Застосуйте регулярний вираз `myRegex` до рядка `myString`, використавши метод `.test()`. # --hints-- From 919c1d8c206cf6e98e0c39263365fd23c67244fd Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Wed, 8 Feb 2023 14:53:04 +0100 Subject: [PATCH 05/52] chore: remove info key (#49290) --- client/i18n/locales/english/translations.json | 1 - 1 file changed, 1 deletion(-) diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index aba33f47e8e..ce97b267a1f 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -302,7 +302,6 @@ "certs": "{{title}} Certification" }, "editor-tabs": { - "info": "Info", "code": "Code", "tests": "Tests", "restart": "Restart", From 928dcbe08c547f02f4b8e516c823014eb21fe822 Mon Sep 17 00:00:00 2001 From: Sem Bauke Date: Wed, 8 Feb 2023 15:21:03 +0100 Subject: [PATCH 06/52] feat: transfer The Odin Project to its own superblock (#49202) * feat: the odin-project superblock * feat: break everything * fix: correct meta names * fix: meta again * fix: tests * fix: help category and external curriculum test * fix: file names again * fix: help category * fix: remove console log --------- Co-authored-by: Oliver Eyton-Williams --- client/i18n/locales/english/intro.json | 26 ++++++--- client/src/assets/icons/index.tsx | 4 +- client/src/assets/icons/viking-helmet.tsx | 17 ++++++ .../src/pages/learn/the-odin-project/index.md | 9 ++++ .../top-build-a-recipe-page-project/index.md | 9 ++++ .../top-learn-html-foundations/index.md | 9 ++++ .../Introduction/super-block-intro.tsx | 21 ++++---- client/src/utils/superblock-map-titles.ts | 5 +- client/utils/help-category-map.json | 4 +- config/certification-settings.ts | 3 +- config/superblock-order.test.ts | 4 +- config/superblock-order.ts | 53 +++++++++++++++---- .../meta.json | 7 ++- .../meta.json | 7 ++- .../top-build-a-recipe-project.md} | 2 +- .../elements-and-tags-question-a.md | 0 .../elements-and-tags-question-b.md | 0 .../html-boilerplate-question-a.md | 0 .../html-boilerplate-question-b.md | 0 .../html-boilerplate-question-c.md | 0 .../html-boilerplate-question-d.md | 0 .../introduction-to-html-css-question-a.md | 0 .../introduction-to-html-css-question-b.md | 0 .../introduction-to-html-css-question-c.md | 0 .../introduction-to-html-css-question-d.md | 0 .../links-and-images-question-a.md | 0 .../links-and-images-question-b.md | 0 .../links-and-images-question-c.md | 0 .../links-and-images-question-d.md | 0 .../links-and-images-question-e.md | 0 .../links-and-images-question-f.md | 0 .../links-and-images-question-g.md | 0 .../links-and-images-question-h.md | 0 ...d-ordered-and-unordered-list-question-a.md | 0 ...d-ordered-and-unordered-list-question-b.md | 0 ...d-ordered-and-unordered-list-question-c.md | 0 .../working-with-text-question-a.md | 0 .../working-with-text-question-b.md | 0 .../working-with-text-question-c.md | 0 .../working-with-text-question-d.md | 0 .../working-with-text-question-e.md | 0 .../working-with-text-question-f.md | 0 .../working-with-text-question-g.md | 0 curriculum/utils.js | 3 +- curriculum/utils.test.ts | 12 +++-- tools/challenge-auditor/index.ts | 3 +- .../api/configs/super-block-list.ts | 4 ++ tools/challenge-helper-scripts/fs-utils.ts | 3 +- .../build-external-curricula-data.test.ts | 8 ++- 49 files changed, 160 insertions(+), 53 deletions(-) create mode 100644 client/src/assets/icons/viking-helmet.tsx create mode 100644 client/src/pages/learn/the-odin-project/index.md create mode 100644 client/src/pages/learn/the-odin-project/top-build-a-recipe-page-project/index.md create mode 100644 client/src/pages/learn/the-odin-project/top-learn-html-foundations/index.md rename curriculum/challenges/_meta/{the-odin-project-projects => top-build-a-recipe-project}/meta.json (60%) rename curriculum/challenges/_meta/{the-odin-project => top-learn-html-foundations}/meta.json (95%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md => 16-the-odin-project/top-build-a-recipe-project/top-build-a-recipe-project.md} (99%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/elements-and-tags-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/elements-and-tags-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/html-boilerplate-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/html-boilerplate-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/html-boilerplate-question-c.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/html-boilerplate-question-d.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/introduction-to-html-css-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/introduction-to-html-css-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/introduction-to-html-css-question-c.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/introduction-to-html-css-question-d.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-c.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-d.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-e.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-f.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-g.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/links-and-images-question-h.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/understand-ordered-and-unordered-list-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/understand-ordered-and-unordered-list-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/understand-ordered-and-unordered-list-question-c.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-a.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-b.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-c.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-d.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-e.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-f.md (100%) rename curriculum/challenges/english/{10-coding-interview-prep/the-odin-project => 16-the-odin-project/top-learn-html-foundations}/working-with-text-question-g.md (100%) diff --git a/client/i18n/locales/english/intro.json b/client/i18n/locales/english/intro.json index 17926a60efb..c1d679e160e 100644 --- a/client/i18n/locales/english/intro.json +++ b/client/i18n/locales/english/intro.json @@ -778,14 +778,6 @@ "Attribute: Rosetta Code" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "Project Euler", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "{{cert}} Certification", "browse-other": "Browse our other free certifications\n(we recommend doing these in order)", diff --git a/client/src/assets/icons/index.tsx b/client/src/assets/icons/index.tsx index 4adcec517a3..ae851d8eeb7 100644 --- a/client/src/assets/icons/index.tsx +++ b/client/src/assets/icons/index.tsx @@ -12,6 +12,7 @@ import Clipboard from './clipboard'; import PythonIcon from './python-icon'; import ResponsiveDesign from './responsive-design'; import Shield from './shield'; +import VikingHelmet from './viking-helmet'; const iconMap = { [SuperBlocks.RespWebDesignNew]: ResponsiveDesign, @@ -27,7 +28,8 @@ const iconMap = { [SuperBlocks.DataAnalysisPy]: Analytics, [SuperBlocks.InfoSec]: Shield, [SuperBlocks.MachineLearningPy]: TensorflowIcon, - [SuperBlocks.CodingInterviewPrep]: Algorithm + [SuperBlocks.CodingInterviewPrep]: Algorithm, + [SuperBlocks.TheOdinProject]: VikingHelmet }; const generateIconComponent = ( diff --git a/client/src/assets/icons/viking-helmet.tsx b/client/src/assets/icons/viking-helmet.tsx new file mode 100644 index 00000000000..ab29caa29f3 --- /dev/null +++ b/client/src/assets/icons/viking-helmet.tsx @@ -0,0 +1,17 @@ +import React from 'react'; + +function VikingHelmet( + props: JSX.IntrinsicAttributes & React.SVGProps +): JSX.Element { + return ( + <> + + + + + ); +} + +VikingHelmet.displayName = 'VikingHelmet'; + +export default VikingHelmet; diff --git a/client/src/pages/learn/the-odin-project/index.md b/client/src/pages/learn/the-odin-project/index.md new file mode 100644 index 00000000000..e600d4a7334 --- /dev/null +++ b/client/src/pages/learn/the-odin-project/index.md @@ -0,0 +1,9 @@ +--- +title: The Odin Project +superBlock: the-odin-project +certification: the-odin-project +--- + +## The Odin project + +The Odin Project is one of those "What I wish I had when I was learning" resources. Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway. This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education. diff --git a/client/src/pages/learn/the-odin-project/top-build-a-recipe-page-project/index.md b/client/src/pages/learn/the-odin-project/top-build-a-recipe-page-project/index.md new file mode 100644 index 00000000000..39bc4dc70b8 --- /dev/null +++ b/client/src/pages/learn/the-odin-project/top-build-a-recipe-page-project/index.md @@ -0,0 +1,9 @@ +--- +title: The Odin Project +superBlock: the-odin-project +certification: the-odin-project +--- + +## The Odin project + +Description is to be determined diff --git a/client/src/pages/learn/the-odin-project/top-learn-html-foundations/index.md b/client/src/pages/learn/the-odin-project/top-learn-html-foundations/index.md new file mode 100644 index 00000000000..39bc4dc70b8 --- /dev/null +++ b/client/src/pages/learn/the-odin-project/top-learn-html-foundations/index.md @@ -0,0 +1,9 @@ +--- +title: The Odin Project +superBlock: the-odin-project +certification: the-odin-project +--- + +## The Odin project + +Description is to be determined diff --git a/client/src/templates/Introduction/super-block-intro.tsx b/client/src/templates/Introduction/super-block-intro.tsx index e48882d03ad..e9ecc075298 100644 --- a/client/src/templates/Introduction/super-block-intro.tsx +++ b/client/src/templates/Introduction/super-block-intro.tsx @@ -210,16 +210,17 @@ const SuperBlockIntroductionPage = (props: SuperBlockProp) => { /> ))} - {superBlock !== SuperBlocks.CodingInterviewPrep && ( -
- -
- )} + {superBlock !== SuperBlocks.CodingInterviewPrep && + superBlock !== SuperBlocks.TheOdinProject && ( +
+ +
+ )} {!isSignedIn && !signInLoading && (
diff --git a/client/src/utils/superblock-map-titles.ts b/client/src/utils/superblock-map-titles.ts index fa2ec32c994..1615bc2f5e8 100644 --- a/client/src/utils/superblock-map-titles.ts +++ b/client/src/utils/superblock-map-titles.ts @@ -9,7 +9,10 @@ enum SuperBlockI18nKeys { // the key above is used to create the last word for superBlock titles used on // the map and window. e.g. 'Certification' in Responsive Web Design // Certification -const superBlocksWithoutLastWord = [SuperBlocks.CodingInterviewPrep]; +const superBlocksWithoutLastWord = [ + SuperBlocks.CodingInterviewPrep, + SuperBlocks.TheOdinProject +]; export function getSuperBlockTitleForMap(superBlock: SuperBlocks) { const i18nSuperBlock = i18next.t(`intro:${superBlock}.title`); diff --git a/client/utils/help-category-map.json b/client/utils/help-category-map.json index f4f141c7b83..40ea39ab04e 100644 --- a/client/utils/help-category-map.json +++ b/client/utils/help-category-map.json @@ -42,8 +42,8 @@ "algorithms": "JavaScript", "data-structures": "JavaScript", "take-home-projects": "JavaScript", - "the-odin-project": "HTML-CSS", - "the-odin-project-projects": "HTML-CSS", + "top-learn-html-foundations": "HTML-CSS", + "top-build-a-recipe-project": "HTML-CSS", "rosetta-code": "JavaScript", "project-euler": "JavaScript", "scientific-computing-with-python": "Python", diff --git a/config/certification-settings.ts b/config/certification-settings.ts index aea15811b79..dd7f943c707 100644 --- a/config/certification-settings.ts +++ b/config/certification-settings.ts @@ -31,7 +31,8 @@ export enum SuperBlocks { DataAnalysisPy = 'data-analysis-with-python', InfoSec = 'information-security', MachineLearningPy = 'machine-learning-with-python', - CodingInterviewPrep = 'coding-interview-prep' + CodingInterviewPrep = 'coding-interview-prep', + TheOdinProject = 'the-odin-project' } export const certIds = { diff --git a/config/superblock-order.test.ts b/config/superblock-order.test.ts index 233f7c4d60c..cf21825a48b 100644 --- a/config/superblock-order.test.ts +++ b/config/superblock-order.test.ts @@ -150,6 +150,7 @@ describe("'superBlockOrder' helper functions", () => { SuperBlocks.MachineLearningPy, SuperBlocks.CodingInterviewPrep, SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject, SuperBlocks.RespWebDesign ]; expect(learnSuperBlocks).toStrictEqual(test); @@ -188,7 +189,8 @@ describe("'superBlockOrder' helper functions", () => { SuperBlocks.InfoSec, SuperBlocks.MachineLearningPy, SuperBlocks.CodingInterviewPrep, - SuperBlocks.JsAlgoDataStructNew + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject ]; expect(notAuditedSuperBlocks).toStrictEqual(test); expect(notAuditedSuperBlocks.length).toEqual(test.length); diff --git a/config/superblock-order.ts b/config/superblock-order.ts index 8be124ca9e5..a7ba0346a0a 100644 --- a/config/superblock-order.ts +++ b/config/superblock-order.ts @@ -78,7 +78,8 @@ export const defaultSuperBlockOrder: SuperBlocks[] = [ SuperBlocks.DataAnalysisPy, SuperBlocks.InfoSec, SuperBlocks.MachineLearningPy, - SuperBlocks.CodingInterviewPrep + SuperBlocks.CodingInterviewPrep, + SuperBlocks.TheOdinProject ]; /* @@ -124,7 +125,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [SuperBlocks.RespWebDesign] }, [TranslationStates.NotAudited]: { @@ -173,7 +177,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -216,7 +223,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -259,7 +269,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -301,7 +314,10 @@ export const superBlockOrder: SuperBlockOrder = { [TranslationStates.NotAudited]: { [SuperBlockStates.Current]: [], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -343,7 +359,10 @@ export const superBlockOrder: SuperBlockOrder = { [TranslationStates.NotAudited]: { [SuperBlockStates.Current]: [], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -384,7 +403,10 @@ export const superBlockOrder: SuperBlockOrder = { [TranslationStates.NotAudited]: { [SuperBlockStates.Current]: [SuperBlocks.CodingInterviewPrep], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -427,7 +449,10 @@ export const superBlockOrder: SuperBlockOrder = { [TranslationStates.NotAudited]: { [SuperBlockStates.Current]: [], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -471,7 +496,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [] } } @@ -514,7 +542,10 @@ export const superBlockOrder: SuperBlockOrder = { SuperBlocks.CodingInterviewPrep ], [SuperBlockStates.New]: [], - [SuperBlockStates.Upcoming]: [SuperBlocks.JsAlgoDataStructNew], + [SuperBlockStates.Upcoming]: [ + SuperBlocks.JsAlgoDataStructNew, + SuperBlocks.TheOdinProject + ], [SuperBlockStates.Legacy]: [SuperBlocks.RespWebDesign] } } diff --git a/curriculum/challenges/_meta/the-odin-project-projects/meta.json b/curriculum/challenges/_meta/top-build-a-recipe-project/meta.json similarity index 60% rename from curriculum/challenges/_meta/the-odin-project-projects/meta.json rename to curriculum/challenges/_meta/top-build-a-recipe-project/meta.json index edd3de40ae3..df2b93d2096 100644 --- a/curriculum/challenges/_meta/the-odin-project-projects/meta.json +++ b/curriculum/challenges/_meta/top-build-a-recipe-project/meta.json @@ -1,12 +1,11 @@ { - "name": "The Odin Project Projects", + "name": "TOP build a recipe project", "isUpcomingChange": true, - "dashedName": "the-odin-project-projects", - "order": 6, + "order": 1, "time": "", "template": "", "required": [], - "superBlock": "coding-interview-prep", + "superBlock": "the-odin-project", "challengeOrder": [ [ "6391d1a4f7ac71efd0621380", diff --git a/curriculum/challenges/_meta/the-odin-project/meta.json b/curriculum/challenges/_meta/top-learn-html-foundations/meta.json similarity index 95% rename from curriculum/challenges/_meta/the-odin-project/meta.json rename to curriculum/challenges/_meta/top-learn-html-foundations/meta.json index 44d7f47d50b..b15490e569c 100644 --- a/curriculum/challenges/_meta/the-odin-project/meta.json +++ b/curriculum/challenges/_meta/top-learn-html-foundations/meta.json @@ -1,12 +1,11 @@ { - "name": "The Odin Project", + "name": "TOP Learn HTML Foundations", "isUpcomingChange": true, - "dashedName": "the-odin-project", - "order": 5, + "order": 0, "time": "", "template": "", "required": [], - "superBlock": "coding-interview-prep", + "superBlock": "the-odin-project", "challengeOrder": [ [ "6374f208de18c50e48ba767b", diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md b/curriculum/challenges/english/16-the-odin-project/top-build-a-recipe-project/top-build-a-recipe-project.md similarity index 99% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md rename to curriculum/challenges/english/16-the-odin-project/top-build-a-recipe-project/top-build-a-recipe-project.md index 7f7926e3df6..d810de57171 100644 --- a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md +++ b/curriculum/challenges/english/16-the-odin-project/top-build-a-recipe-project/top-build-a-recipe-project.md @@ -2,7 +2,7 @@ id: 6391d1a4f7ac71efd0621380 title: Build a Recipe Page Project challengeType: 14 -dashedName: project-create-a-recipe-page +dashedName: top-build-a-recipe-project --- # --description-- diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/elements-and-tags-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/elements-and-tags-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/elements-and-tags-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/elements-and-tags-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/elements-and-tags-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/elements-and-tags-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/elements-and-tags-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/elements-and-tags-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-c.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-c.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-c.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-c.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-d.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-d.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/html-boilerplate-question-d.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/html-boilerplate-question-d.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-c.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-c.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-c.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-c.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-d.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-d.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/introduction-to-html-css-question-d.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/introduction-to-html-css-question-d.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-c.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-c.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-c.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-c.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-d.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-d.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-d.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-d.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-e.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-e.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-e.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-e.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-f.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-f.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-f.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-f.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-g.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-g.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-g.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-g.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-h.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-h.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/links-and-images-question-h.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/links-and-images-question-h.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-c.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-c.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/understand-ordered-and-unordered-list-question-c.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/understand-ordered-and-unordered-list-question-c.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-a.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-a.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-a.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-a.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-b.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-b.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-b.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-b.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-c.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-c.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-c.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-c.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-d.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-d.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-d.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-d.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-e.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-e.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-e.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-e.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-f.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-f.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-f.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-f.md diff --git a/curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-g.md b/curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-g.md similarity index 100% rename from curriculum/challenges/english/10-coding-interview-prep/the-odin-project/working-with-text-question-g.md rename to curriculum/challenges/english/16-the-odin-project/top-learn-html-foundations/working-with-text-question-g.md diff --git a/curriculum/utils.js b/curriculum/utils.js index 16b0beba57f..c9f18d45ee8 100644 --- a/curriculum/utils.js +++ b/curriculum/utils.js @@ -120,7 +120,8 @@ const directoryToSuperblock = { '13-relational-databases': 'relational-database', '14-responsive-web-design-22': '2022/responsive-web-design', '15-javascript-algorithms-and-data-structures-22': - '2022/javascript-algorithms-and-data-structures' + '2022/javascript-algorithms-and-data-structures', + '16-the-odin-project': 'the-odin-project' }; function getSuperBlockFromDir(dir) { diff --git a/curriculum/utils.test.ts b/curriculum/utils.test.ts index 28a817a688c..8f27689c9ac 100644 --- a/curriculum/utils.test.ts +++ b/curriculum/utils.test.ts @@ -39,7 +39,8 @@ const upcomingTest = { [SuperBlocks.MachineLearningPy]: 10, [SuperBlocks.CodingInterviewPrep]: 11, [SuperBlocks.JsAlgoDataStructNew]: 12, - [SuperBlocks.RespWebDesign]: 13 + [SuperBlocks.TheOdinProject]: 13, + [SuperBlocks.RespWebDesign]: 14 }; const espanolTest = { @@ -144,7 +145,7 @@ describe('getSuperOrder', () => { if (process.env.SHOW_UPCOMING_CHANGES !== 'true') { expect.assertions(13); } else { - expect.assertions(14); + expect.assertions(15); } expect(getSuperOrder(SuperBlocks.RespWebDesignNew)).toBe(0); @@ -162,7 +163,8 @@ describe('getSuperOrder', () => { if (process.env.SHOW_UPCOMING_CHANGES === 'true') { expect(getSuperOrder(SuperBlocks.JsAlgoDataStructNew)).toBe(12); - expect(getSuperOrder(SuperBlocks.RespWebDesign)).toBe(13); + expect(getSuperOrder(SuperBlocks.TheOdinProject)).toBe(13); + expect(getSuperOrder(SuperBlocks.RespWebDesign)).toBe(14); } else { expect(getSuperOrder(SuperBlocks.RespWebDesign)).toBe(12); } @@ -175,7 +177,7 @@ describe('getSuperBlockFromPath', () => { ); it('handles all the directories in ./challenges/english', () => { - expect.assertions(15); + expect.assertions(16); for (const directory of directories) { expect(() => getSuperBlockFromDir(directory)).not.toThrow(); @@ -183,7 +185,7 @@ describe('getSuperBlockFromPath', () => { }); it("returns valid superblocks (or 'certifications') for all valid arguments", () => { - expect.assertions(15); + expect.assertions(16); const superBlockPaths = directories.filter(x => x !== '00-certifications'); diff --git a/tools/challenge-auditor/index.ts b/tools/challenge-auditor/index.ts index 564deb5a72a..4fa66ce5936 100644 --- a/tools/challenge-auditor/index.ts +++ b/tools/challenge-auditor/index.ts @@ -29,7 +29,8 @@ const superBlockFolderMap = { 'relational-database': '13-relational-database', '2022/responsive-web-design': '14-responsive-web-design-22', '2022/javascript-algorithms-and-data-structures': - '15-javascript-algorithms-and-data-structures-22' + '15-javascript-algorithms-and-data-structures-22', + 'the-odin-project': '16-the-odin-project' }; // These blocks are in the incorrect superblock. They should be moved but, for diff --git a/tools/challenge-editor/api/configs/super-block-list.ts b/tools/challenge-editor/api/configs/super-block-list.ts index 28b0d6eb7ad..d5655f8f9a4 100644 --- a/tools/challenge-editor/api/configs/super-block-list.ts +++ b/tools/challenge-editor/api/configs/super-block-list.ts @@ -54,5 +54,9 @@ export const superBlockList = [ { name: 'JavaScript Algorithms and Data Structures (Beta)', path: '15-javascript-algorithms-and-data-structures-22' + }, + { + name: 'The Odin Project', + path: '16-the-odin-project' } ]; diff --git a/tools/challenge-helper-scripts/fs-utils.ts b/tools/challenge-helper-scripts/fs-utils.ts index 410f98deb5f..ad479a27177 100644 --- a/tools/challenge-helper-scripts/fs-utils.ts +++ b/tools/challenge-helper-scripts/fs-utils.ts @@ -17,7 +17,8 @@ export function getSuperBlockSubPath(superBlock: SuperBlocks): string { [SuperBlocks.RelationalDb]: '13-relational-databases', [SuperBlocks.RespWebDesignNew]: '14-responsive-web-design-22', [SuperBlocks.JsAlgoDataStructNew]: - '15-javascript-algorithms-and-data-structures-22' + '15-javascript-algorithms-and-data-structures-22', + [SuperBlocks.TheOdinProject]: '16-the-odin-project' }; return pathMap[superBlock]; } diff --git a/tools/scripts/build/build-external-curricula-data.test.ts b/tools/scripts/build/build-external-curricula-data.test.ts index 9ff08d2e8a7..737260af2e6 100644 --- a/tools/scripts/build/build-external-curricula-data.test.ts +++ b/tools/scripts/build/build-external-curricula-data.test.ts @@ -82,10 +82,16 @@ if (envData.clientLocale == 'english' && !envData.showUpcomingChanges) { const dashedNames = orderedSuperBlockInfo.map( ({ dashedName }) => dashedName ); + + const isUpcoming = [ + '2022/javascript-algorithms-and-data-structures', + 'the-odin-project' + ]; + // TODO: this is a hack, we should have a single source of truth for the // list of superblocks that are available. const publicSuperBlockNames = Object.values(SuperBlocks).filter( - x => x !== '2022/javascript-algorithms-and-data-structures' + x => !isUpcoming.includes(x) ); expect(dashedNames).toEqual( From 9472a8c912982f525cb6e4bef088a2adc1230880 Mon Sep 17 00:00:00 2001 From: Sriparno Roy <89148144+Sriparno08@users.noreply.github.com> Date: Wed, 8 Feb 2023 21:45:45 +0530 Subject: [PATCH 07/52] fix(curriculum): make step 16 of learn accessibility project easier to read (#49251) * Fix sentence construction * Fix sentence construction --- .../614202874ca576084fca625f.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/curriculum/challenges/english/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md b/curriculum/challenges/english/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md index 98425cf93a9..1c61c6f1a5b 100644 --- a/curriculum/challenges/english/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md +++ b/curriculum/challenges/english/14-responsive-web-design-22/learn-accessibility-by-building-a-quiz/614202874ca576084fca625f.md @@ -7,9 +7,9 @@ dashedName: step-16 # --description-- -Every `region` role requires a visible label, which should be referenced by the `aria-labelledby` attribute. +Every `region` role requires a label, which helps screen reader users understand the purpose of the region. One method for adding a label is to add a heading element inside the region and then reference it with the `aria-labelledby` attribute. -To the `section` elements, give the following `aria-labelledby` attributes: +Add the following `aria-labelledby` attributes to the `section` elements: - `student-info` - `html-questions` From a9f292f5dabd9b44848c503bae0d80c7b4c77f51 Mon Sep 17 00:00:00 2001 From: camperbot Date: Thu, 9 Feb 2023 02:49:30 +0530 Subject: [PATCH 08/52] chore(i18n,learn): processed translations (#49292) --- .../render-a-class-component-to-the-dom.md | 2 +- .../react/render-html-elements-to-the-dom.md | 6 +- .../add-a-tooltip-to-a-d3-element.md | 22 +++---- .../add-attributes-to-the-circle-elements.md | 4 +- .../add-document-elements-with-d3.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- .../project-create-a-recipe-page.md | 62 +++++++++---------- .../615f6b2d164f81809efd9bdc.md | 2 +- .../615f6b2d164f81809efd9bdc.md | 2 +- 15 files changed, 58 insertions(+), 58 deletions(-) diff --git a/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-a-class-component-to-the-dom.md b/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-a-class-component-to-the-dom.md index d34c6fdd953..5a74017ecd3 100644 --- a/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-a-class-component-to-the-dom.md +++ b/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-a-class-component-to-the-dom.md @@ -10,7 +10,7 @@ dashedName: render-a-class-component-to-the-dom يمكنك تذكر استخدام API ReactDOM في تحدي سابق لإضافة عناصر JSX إلى DOM. وستبدو عملية تقديم مكونات React متشابهة جدا. لقد ركزت التحديات القليلة الماضية على المكونات (components) والتكوين (composition)، لذلك تم التقديم لك خلف الكواليس. ومع ذلك، لن يقدم أي من رمز React الذي تكتبه إلى DOM دون أستدعاء API ReactDOM. -إليك تذكير بكفية كتابة الصيغة: `ReactDOM.render(componentToRender, targetNode)`. الحَجَّة الأولى هي عنصر React الذي تريد أنتاجه. الحجة الثانية هي نقطة التواصل DOM التي تريد أن تجعل ذلك المكون داخلها. +إليك تذكير بكفية كتابة الصيغة: `ReactDOM.render(componentToRender, targetNode)`. الحَجَّة الأولى هي عنصر React الذي تريد أنتاجه. الحجة الثانية هي DOM node التي تريد أن تجعل ذلك المكون داخلها. يتم تمرير مكونات React إلى `ReactDOM.render()` بشكل مختلف قليلا عن عناصر JSX. بالنسبة لعناصر JSX ، يمكنك تمرير اسم العنصر الذي تريد أنتاجه. لكن، بالنسبة لمكونات React، تحتاج إلى استخدام نفس الجملة كما لو كنت تقدم مكوناً متداخلاً، على سبيل المثال `ReactDOM.render(, targetNode)`. أنت تستخدم هذه الجملة لكل من مكونات فئة ES6 والمكونات الوظيفية ES6. diff --git a/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-html-elements-to-the-dom.md b/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-html-elements-to-the-dom.md index 092b3ab7208..80f52e03146 100644 --- a/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-html-elements-to-the-dom.md +++ b/curriculum/challenges/arabic/03-front-end-development-libraries/react/render-html-elements-to-the-dom.md @@ -10,13 +10,13 @@ dashedName: render-html-elements-to-the-dom حتى الآن، تعلمت أن JSX أداة مناسبة لكتابة HTML مقروءة داخل JavaScript. مع React، يمكننا تقديم JSX قاصدًا إلى HTML DOM باستخدام React الذي يقدم API المعروف باسم ReactDOM. -ReactDOM يوفر طريقة بسيطة لتقديم عناصر React إلى DOM التي تبدو مثل: `ReactDOM.render(componentToRender, targetNode)`, حيث الحَجَّة الأولى هي عنصر React أو المكون الذي تريد أن تنتجه، والحجة الثانية هي نقطة التواصل DOM التي تريد تقديم المكون إليها. +ReactDOM يوفر طريقة بسيطة لتقديم عناصر React إلى DOM التي تبدو مثل: `ReactDOM.render(componentToRender, targetNode)`, حيث الحَجَّة الأولى هي عنصر React أو المكون الذي تريد أن تنتجه، والحجة الثانية هي node DOM التي تريد تقديم المكون إليها. كما تتوقع، `ReactDOM.render()` يجب أن يستدعى بعد إعلانات عناصر JSX، تماما مثل كيفية الإعلان عن المتغيرات قبل استخدامها. # --instructions-- -يحتوي محرر التعليمات البرمجية على مكون JSX بسيط. استخدم طريقة `ReactDOM.render()` لإضافة هذا المكون إلى الصفحة. يمكنك تمرير عناصر JSX المحددة قاصدًا كالحجة الأولى واستخدام `document.getElementById()` لتحديد نقطة التواصل DOM لتقديمها إليها. هناك `div` مع `id='challenge-node'` متاح لك للاستخدام. تيقن من عدم تغيير ثابت `JSX`. +يحتوي محرر التعليمات البرمجية على مكون JSX بسيط. استخدم طريقة `ReactDOM.render()` لإضافة هذا المكون إلى الصفحة. يمكنك تمرير عناصر JSX المحددة قاصدًا كالحجة الأولى واستخدام `document.getElementById()` لتحديد DOM node لتقديمها إليها. هناك `div` مع `id='challenge-node'` متاح لك للاستخدام. تيقن من عدم تغيير ثابت `JSX`. # --hints-- @@ -38,7 +38,7 @@ assert(JSX.props.children[0].type === 'h1'); assert(JSX.props.children[1].type === 'p'); ``` -يجب أن ينتج عنصر JSX المقدم إلى نقطة التواصل DOM مع معرف `challenge-node`. +يجب أن ينتج عنصر JSX المقدم إلى DOM node مع معرف `challenge-node`. ```js assert( diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md index 4cca0a103d8..784787f50a1 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md @@ -8,13 +8,13 @@ dashedName: add-a-tooltip-to-a-d3-element # --description-- -يظهر أداة لتلميح (tooltip) المزيد من معلومات العنصر في صفحة عندما ينتقل المستخدم فوق (hovers) هذا العنصر. هناك عدة طرق لإضافة أداة لتلميح (tooltip) لعرض بيانات، هذا التحدي يستخدم عنصر `title` في SVG. +يظهر أداة لتلميح (tooltip) المزيد من معلومات العنصر في صفحة عندما ينتقل المستخدم فوق (hovers) هذا العنصر. هناك عدة طرق لإضافة تلميح لعرض البيانات. هذا التحدي يستخدم عنصر `title` في SVG. يرافق `title` الطريقة (method) المسمى `text()` لإضافة البيانات بشكل ديناميكي إلى الأعمدة (bars). # --instructions-- -أربط عنصر `title` تحت كل نقطة التواصل (node) المسمى `rect`. ثم فعّيل الطريقة (method) المسمى `text()` مع وظيفة تعيد تفعيل (callback function) بحيث يعرض النص قيمة البيانات. +أربط عنصر `title` تحت كل node المسمى `rect`. ثم فعّيل الطريقة (method) المسمى `text()` مع وظيفة تعيد تفعيل (callback function) بحيث يعرض النص قيمة البيانات. # --hints-- @@ -24,55 +24,55 @@ dashedName: add-a-tooltip-to-a-d3-element assert($('title').length == 9); ``` -يجب أن يحتوي أول عنصر `title` على أداة لتلميح (tooltip) بنص `12`. +يجب أن يحتوي أول عنصر `title` على تلميح بنص `12`. ```js assert($('title').eq(0).text() == '12'); ``` -يجب أن يحتوي ثاني عنصر `title` على أداة لتلميح (tooltip) بنص `31`. +يجب أن يحتوي ثاني عنصر `title` على تلميح بنص `31`. ```js assert($('title').eq(1).text() == '31'); ``` -يجب أن يحتوي ثالث عنصر `title` على أداة لتلميح (tooltip) بنص `22`. +يجب أن يحتوي ثالث عنصر `title` على تلميح بنص `22`. ```js assert($('title').eq(2).text() == '22'); ``` -يجب أن يحتوي رابع عنصر `title` على أداة لتلميح (tooltip) بنص `17`. +يجب أن يحتوي رابع عنصر `title` على تلميح بنص `17`. ```js assert($('title').eq(3).text() == '17'); ``` -يجب أن يحتوي خامس عنصر `title` على أداة لتلميح (tooltip) بنص `25`. +يجب أن يحتوي خامس عنصر `title` على تلميح بنص `25`. ```js assert($('title').eq(4).text() == '25'); ``` -يجب أن يحتوي سادس عنصر `title` على أداة لتلميح (tooltip) بنص `18`. +يجب أن يحتوي سادس عنصر `title` على تلميح بنص `18`. ```js assert($('title').eq(5).text() == '18'); ``` -يجب أن يحتوي سابع عنصر `title` على أداة لتلميح (tooltip) بنص `29`. +يجب أن يحتوي سابع عنصر `title` على تلميح بنص `29`. ```js assert($('title').eq(6).text() == '29'); ``` -يجب أن يحتوي ثامن عنصر `title` على أداة لتلميح (tooltip) بنص `14`. +يجب أن يحتوي ثامن عنصر `title` على تلميح بنص `14`. ```js assert($('title').eq(7).text() == '14'); ``` -يجب أن يحتوي تاسع عنصر `title` على أداة لتلميح (tooltip) بنص `9`. +يجب أن يحتوي تاسع عنصر `title` على تلميح بنص `9`. ```js assert($('title').eq(8).text() == '9'); diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md index 458f8ae61cd..42b50539688 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-attributes-to-the-circle-elements.md @@ -8,9 +8,9 @@ dashedName: add-attributes-to-the-circle-elements # --description-- -أنشئت في التحدي السابق عناصر `circle` لكل نقطة في `dataset`، وربطهم بلوحة (canvas) SVG. لكن D3 يحتاج إلى مزيد من المعلومات حول موقع (position) وحجم (size) كل `circle` لعرضها بشكل صحيح. +أنشئت في التحدي السابق عناصر `circle` لكل نقطة في `dataset`، وأضفتهم بلوحة (canvas) SVG. لكن D3 يحتاج إلى مزيد من المعلومات حول موقع (position) وحجم (size) كل `circle` لعرضها بشكل صحيح. -لدي `circle` في SVG ثلاث سمات (attributes) رئيسية. تكون السمات (attributes) المسمى `cx` و `cy` إحداثيات. ويخبروا D3 أين موقع (position) *مركز (center)* للشكل على لوحة (canvas) SVG. تغير سمة (attribute) نصف قطر (radius) (تكتب مثل: `r`) يأثر على حجم `circle`. +لدي `circle` في SVG ثلاث سمات (attributes) رئيسية. تكون السمات (attributes) المسمى `cx` و `cy` إحداثيات. ويخبروا D3 أين تضع *وَسَط (center)* الشكل على لوحة SVG. تحدد سمة نصف قطر (radius) (وتكتب: `r`) حجم الدائرة (`circle`). مثل مقياس الإحداثيات `rect` داخل `y`، تقاس `cy` داخل `circle` من الجزء العلوي للوحة (canvas) SVG، ليس من الأسفل. diff --git a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md index 3b425d7ffd5..2cf381b4368 100644 --- a/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md +++ b/curriculum/challenges/arabic/04-data-visualization/data-visualization-with-d3/add-document-elements-with-d3.md @@ -10,7 +10,7 @@ dashedName: add-document-elements-with-d3 يحتوي D3 على عدة طرق (methods) التي تسمح لك بإضافة وتغيير العناصر في وثيقتك. -تختار طريقة (method) `select()` عنصراً واحداً من الوثيقة. إنها تأخذ اسم العنصر الذي تريده كمعطى (argument)، وتنتج node HTML لأول عنصر في المستند يطابق الاسم. Here's an example: +تختار طريقة (method) `select()` عنصراً واحداً من الوثيقة. إنها تأخذ اسم العنصر الذي تريده كمعطى (argument)، وتنتج HTML node لأول عنصر في المستند يطابق الاسم. Here's an example: ```js const anchor = d3.select("a"); diff --git a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 984e967ff1c..47fae3090d3 100644 --- a/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/arabic/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -بعد آخر عنصر `.divider`، أنشئ عنصر `p` وأعطيه النص `Total Fat 8g 10%`. قم بتغليف `Total Fat` في `span` مع `class` تم تعيينه إلى `bold`. غلف `10%` داخل عنصر `span` مع `class` بقيمة `bold`. أخيراً، أدخل عنصر `span` الذي يحتوي على نص `Total Fat` مع نص `8g` في عنصر `span` إضافي للمحاذاة. +بعد آخر عنصر `.divider`، أنشئ عنصر `p` وأعطيه النص `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. أخيراً، أدخل عنصر `span` الذي يحتوي على نص `Total Fat` مع نص `8g` في عنصر `span` إضافي للمحاذاة. # --hints-- diff --git a/curriculum/challenges/chinese-traditional/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/chinese-traditional/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index fc6a81f51f8..980f0672685 100644 --- a/curriculum/challenges/chinese-traditional/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/chinese-traditional/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -在最後一個 `.divider` 元素之後,創建一個 `p` 元素併爲其指定文本 `Total Fat 8g 10%`。 將 `Total Fat` 包裹在 `span` 元素中,並將 `class` 設置爲 `bold`。 將 `10%` 包裹在另一個 `span` 元素中,並將 `class` 設置爲 `bold`。 最後:嵌套 `Total Fat` `span` 元素和文本 `8g` 在另一個 `span` 元素中,以實現對齊。 +在最後一個 `.divider` 元素之後,創建一個 `p` 元素併爲其指定文本 `Total Fat 8g 10%`。 Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. 最後:嵌套 `Total Fat` `span` 元素和文本 `8g` 在另一個 `span` 元素中,以實現對齊。 # --hints-- diff --git a/curriculum/challenges/chinese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/chinese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 3c5555b0ce1..c1c455124b8 100644 --- a/curriculum/challenges/chinese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/chinese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -在最后一个 `.divider` 元素之后,创建一个 `p` 元素并为其指定文本 `Total Fat 8g 10%`。 将 `Total Fat` 包裹在 `span` 元素中,并将 `class` 设置为 `bold`。 将 `10%` 包裹在另一个 `span` 元素中,并将 `class` 设置为 `bold`。 最后:嵌套 `Total Fat` `span` 元素和文本 `8g` 在另一个 `span` 元素中,以实现对齐。 +在最后一个 `.divider` 元素之后,创建一个 `p` 元素并为其指定文本 `Total Fat 8g 10%`。 Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. 最后:嵌套 `Total Fat` `span` 元素和文本 `8g` 在另一个 `span` 元素中,以实现对齐。 # --hints-- diff --git a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 384cf16d4b9..fbfed9937c9 100644 --- a/curriculum/challenges/espanol/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/espanol/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -Después de su último elemento `.divider`, cree un elemento `p` y asígnele el texto `Total Fat 8g 10%`. Envuelva `Total Fat` en un elemento `span` con la `class` configurada en `bold`. Envuelva `10%` en otro elemento `span` con el atributo `class` establecido a `bold`. Por último, anide el elemento `span` `Total Fat` y el texto `8g` en un elemento `span` adicional para alineamiento. +Después de su último elemento `.divider`, cree un elemento `p` y asígnele el texto `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Por último, anide el elemento `span` `Total Fat` y el texto `8g` en un elemento `span` adicional para alineamiento. # --hints-- diff --git a/curriculum/challenges/german/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/german/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 0d8c69723b0..c843342439d 100644 --- a/curriculum/challenges/german/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/german/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -After your last `.divider` element, create a `p` element and give it the text `Total Fat 8g 10%`. Wrap `Total Fat` in a `span` element with the `class` set to `bold`. Wrap `10%` in another `span` element with the `class` set to `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. +After your last `.divider` element, create a `p` element and give it the text `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. # --hints-- diff --git a/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 92a8c2d67ae..d53b8338403 100644 --- a/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/italian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -Dopo l'ultimo elemento `.divider`, crea un elemento `p` e assegnagli il testo `Total Fat 8g 10%`. Avvolgi `Total Fat` in un elemento `span` con l'attributo `class` con il valore `bold`. Racchiudi `10%` in un altro elemento `span` con `class` impostata su `bold`. Infine annida l'elemento `span` `Total Fat` e il testo `8g` in un altro elemento `span` per l'allineamento. +Dopo l'ultimo elemento `.divider`, crea un elemento `p` e assegnagli il testo `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Infine annida l'elemento `span` `Total Fat` e il testo `8g` in un altro elemento `span` per l'allineamento. # --hints-- diff --git a/curriculum/challenges/japanese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/japanese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 5a82f434392..e98d6b36d96 100644 --- a/curriculum/challenges/japanese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/japanese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -最後の `.divider` 要素の下に、`p` 要素を作成してテキストを `Total Fat 8g 10%` にしてください。 `Total Fat` の部分を `span` 要素で囲み、`class` を `bold` に設定してください。 Wrap `10%` in another `span` element with the `class` set to `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. +最後の `.divider` 要素の下に、`p` 要素を作成してテキストを `Total Fat 8g 10%` にしてください。 Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Finally, nest the `Total Fat` `span` element and the text `8g` in an additional `span` element for alignment. # --hints-- diff --git a/curriculum/challenges/portuguese/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md b/curriculum/challenges/portuguese/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md index 657a3f6e32d..e1563646d8c 100644 --- a/curriculum/challenges/portuguese/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md +++ b/curriculum/challenges/portuguese/10-coding-interview-prep/the-odin-project-projects/project-create-a-recipe-page.md @@ -1,40 +1,40 @@ --- id: 6391d1a4f7ac71efd0621380 -title: Build a Recipe Page Project +title: Projeto de criação de uma página de receitas challengeType: 14 dashedName: project-create-a-recipe-page --- # --description-- -The website will consist of a main index page which will have links to a few recipes. The website won’t look very pretty by the time you’ve finished. +O site consistirá em uma página index principal com links para algumas receitas. O site não ficará muito bonito quando terminar. -**User Stories:** +**Histórias de usuário:** -1. Your recipe page should contain a `DOCTYPE` tag. -1. Your recipe page should include an `html` element with a `head` and `body` element as children. -1. You should have a `title` element within the `head` element with the text `The Odin Recipes`. -1. You should see an `h1` element that has the text `Creamy Chocolate Fudge`. -1. You should see an image with the url `*placeholder-fcc-cdn*` with a fitting `alt` text. -1. There should be an `h2` element with the text `Description` under the image. -1. You should see a couple of paragraphs under `Description` that describe the recipe. -1. There should be an `h2` element with the text `Ingredients` -1. Under the `Ingredients` heading there should be an unordered list with the ingredients needed for the recipe. -1. Under the list of ingredients add another heading called `Steps`. -1. You should see an ordered list with a couple of steps needed to complete the recipe. -1. Under the steps there should be an `h2` element with the text `More Recipes` -1. You should see a couple of links to other recipes inside an unordered list which has a couple of list items with anchor elements within. -1. These anchor elements should have `href` attribute with the value set to `#` +1. A página de receita deve conter uma tag `DOCTYPE`. +1. A página de receita deve incluir um elemento `html` com os elementos `head` e `body` como filhos. +1. Você deve ter um elemento `title` dentro do elemento `head` com o texto `The Odin Recipes`. +1. Você deve ver um elemento `h1` com o texto `Creamy Chocolate Fudge`. +1. Você deve ver uma imagem com o url `*placeholder-fcc-cdn*` com um texto `alt` adequado. +1. Deve haver um elemento `h2` com o texto `Description` sob a imagem. +1. Você deve ver alguns parágrafos sob `Description` que descrevam a receita. +1. Deve haver um elemento `h2` com o texto `Ingredients` +1. Sob o título `Ingredients`, deve haver uma lista não ordenada com os ingredientes necessários para a receita. +1. Sob a lista de ingredientes, adicione outro título chamado `Steps`. +1. Você deve ver uma lista ordenada com alguns passos necessários para completar a receita. +1. Abaixo dos passos, deve haver um elemento `h2` com o texto `More Recipes` +1. Você deve ver alguns links para outras receitas dentro de uma lista não ordenada com alguns itens na lista com elementos de âncora dentro deles. +1. O elemento de âncora (a) deve ter o atributo `href` com o valor `#` # --hints-- -You should have a `DOCTYPE` tag. +Você deve ter uma tag `DOCTYPE`. ```js assert(code.match(//gi)); ``` -You should have a `html` element with `head` and `body` element. +Você precisa de um elemento `html` e, dentro dele, um elemento `head` e um elemento `body`. ```js const html = document.querySelectorAll('html')[0]; @@ -44,19 +44,19 @@ const body = document.querySelectorAll('html > body')[0]; assert(html && head && body); ``` -You should have a `title` element within the `head` element that contains the text `The Odin Recipes`. +Você deve ter um elemento `title` dentro do elemento `head` com o texto `The Odin Recipes`. ```js assert(document.querySelectorAll('HEAD > TITLE')[0].innerText == 'The Odin Recipes'); ``` -You should have a `h1` element within your `body` element that contains the text `Creamy Chocolate Fudge`. +Você deve ter um elemento `h1` dentro do elemento `body` com o texto `Creamy Chocolate Fudge`. ```js assert(document.querySelectorAll('BODY > H1')[0].innerText == 'Creamy Chocolate Fudge'); ``` -You should have an image with the url `*placeholder-fcc-cdn*` with an `alt` attribute that has a fitting text. +Você deve ter uma imagem com o url `*placeholder-fcc-cdn*` com um atributo `alt` que tenha um texto adequado. ```js const img = document.querySelectorAll('IMG')[0]; @@ -64,7 +64,7 @@ const img = document.querySelectorAll('IMG')[0]; assert(img && img.alt !='' && img.src === 'https://i.imgur.com/p0J5baJ.jpg') ``` -You should have an `h2` element with the text `Description`. +Deve haver um elemento `h2` com o texto `Description`. ```js const h2 = document.querySelectorAll('H2')[0]; @@ -72,7 +72,7 @@ const h2 = document.querySelectorAll('H2')[0]; assert(h2.innerText == 'Description'); ``` -You should have at least two `p` elements describing the recipe. +Você deve ter pelo menos dois elementos `p` que descrevam a receita. ```js const paragraphs = document.querySelectorAll('P'); @@ -80,7 +80,7 @@ const paragraphs = document.querySelectorAll('P'); assert(paragraphs.length > 1); ``` -You should have an `h2` element with the text `Ingredients`. +Você deve ter um elemento `h2` com o texto `Ingredients`. ```js const h2 = document.querySelectorAll('H2')[1]; @@ -88,7 +88,7 @@ const h2 = document.querySelectorAll('H2')[1]; assert(h2.innerText == 'Ingredients'); ``` -You should have an unordered list `
    ` with some ingredients as the list items `
  • `. +Você deve ter uma lista não ordenada `
      ` com alguns ingredientes como itens da lista `
    • `. ```js const unorderedList = document.querySelectorAll('UL')[0]; @@ -97,7 +97,7 @@ const listItems = document.querySelectorAll('UL > LI'); assert(unorderedList && listItems && listItems.length > 1); ``` -You should have an `h2` element with the text `Steps`. +Você deve ter um elemento `h2` com o texto `Steps`. ```js const h2 = document.querySelectorAll('H2')[2]; @@ -105,7 +105,7 @@ const h2 = document.querySelectorAll('H2')[2]; assert(h2.innerText == 'Steps'); ``` -You should have a `
        ` with the the steps as the list items `
      1. `. +Você deve ter uma lista ordenada `
          ` com alguns passos como itens da lista `
        1. `. ```js const orderedList = document.querySelectorAll('OL')[0]; @@ -114,7 +114,7 @@ const listItems = document.querySelectorAll('OL > LI'); assert(orderedList && listItems && listItems.length > 1); ``` -You should have an `h2` element with the text `More Recipes`. +Você deve ter um elemento `h2` com o texto `More Recipes`. ```js const h2 = document.querySelectorAll('H2')[3]; @@ -122,7 +122,7 @@ const h2 = document.querySelectorAll('H2')[3]; assert(h2.innerText == 'More Recipes'); ``` -You should have an unordered list `
            ` element with list items `
          • ` that contain `` tags which lead to other recipes. +Você deve ter um elemento de lista não ordenada `
              ` com itens de lista `
            • ` que contenham tags `` que levem a outras receitas. ```js const unorderedList = document.querySelectorAll('UL')[1]; @@ -137,7 +137,7 @@ const containsAnchors = [...listItems].every(function(listItem) { assert(unorderedList && allAreListItems && containsAnchors && listItems.length > 1); ``` -Your anchor tags linking to the recipes should have a `href` attribute with the value set to `#` +Os elementos de âncora (a) que estiverem associados a receitas devem ter o atributo `href` com o valor `#`. ```js const anchorTags = document.querySelectorAll("a"); diff --git a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index 1ecaccf66ad..591e5cd4d2a 100644 --- a/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/portuguese/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -Após o último elemento `.divider`, crie um elemento `p` e dê a ele o texto `Total Fat 8g 10%`. Encapsule `Total Fat` em um elemento `span` com a `class` definida como `bold`. Encapsule `10%` em outro elemento `span` com a `class` definida como `bold`. Por fim, coloque o elemento de `span` `Total Fat` e o texto `8g` dentro de um elemento de `span` adicional para realizar o alinhamento. +Após o último elemento `.divider`, crie um elemento `p` e dê a ele o texto `Total Fat 8g 10%`. Coloque o texto `Total Fat` dentro de um elemento `span` com a `class` definida como `bold`. Coloque o texto `10%` dentro de outro elemento `span`, com a `class` definida como `bold`. Por fim, coloque o elemento de `span` `Total Fat` e o texto `8g` dentro de um elemento de `span` adicional para realizar o alinhamento. # --hints-- diff --git a/curriculum/challenges/ukrainian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md b/curriculum/challenges/ukrainian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md index b827007312c..86ce469d92d 100644 --- a/curriculum/challenges/ukrainian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md +++ b/curriculum/challenges/ukrainian/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f6b2d164f81809efd9bdc.md @@ -7,7 +7,7 @@ dashedName: step-43 # --description-- -Після останнього елемента `.divider` створіть елемент `p` та надайте йому текст `Total Fat 8g 10%`. Обгорніть `Total Fat` в елемент `span` з `class`, встановленим на `bold`. Обгорніть `10%` в інший елемент `span` із `class` зі значенням `bold`. Наприкінці вкладіть елемент `span` (`Total Fat`) та текст `8g` у додатковий елемент `span` для вирівнювання. +Після останнього елемента `.divider` створіть елемент `p` та надайте йому текст `Total Fat 8g 10%`. Wrap the text `Total Fat` in a `span` element with the `class` of `bold`. Wrap the text `10%` in another `span` element with the `class` of `bold`. Наприкінці вкладіть елемент `span` (`Total Fat`) та текст `8g` у додатковий елемент `span` для вирівнювання. # --hints-- From 6c97591ca6a8a0fe96127d609fd8919e447f67eb Mon Sep 17 00:00:00 2001 From: Ahmad Abdolsaheb Date: Thu, 9 Feb 2023 00:28:26 +0300 Subject: [PATCH 09/52] feat(client): turn default layout to a functional component (#49289) --- client/src/components/layouts/default.tsx | 79 +++++++++++------------ 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/client/src/components/layouts/default.tsx b/client/src/components/layouts/default.tsx index 071611f499d..ad865472aec 100644 --- a/client/src/components/layouts/default.tsx +++ b/client/src/components/layouts/default.tsx @@ -1,7 +1,6 @@ -import React, { Component, ReactNode } from 'react'; +import React, { ReactNode, useEffect } from 'react'; import Helmet from 'react-helmet'; import { TFunction, withTranslation } from 'react-i18next'; -// import TagManager from 'react-gtm-module'; import { connect } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; import { createSelector } from 'reselect'; @@ -26,6 +25,7 @@ import { isServerOnlineSelector, userFetchStateSelector } from '../../redux/selectors'; + import { UserFetchState, User } from '../../redux/prop-types'; import BreadCrumb from '../../templates/Challenges/components/bread-crumb'; import Flash from '../Flash'; @@ -41,6 +41,7 @@ import './fonts.css'; import './global.css'; import './variables.css'; import './rtl-layout.css'; +import { Themes } from '../settings/theme'; const mapStateToProps = createSelector( isSignedInSelector, @@ -100,55 +101,51 @@ const getSystemTheme = () => : 'light-palette' }`; -class DefaultLayout extends Component { - static displayName = 'DefaultLayout'; - - componentDidMount() { - const { isSignedIn, fetchUser } = this.props; +function DefaultLayout({ + children, + hasMessage, + fetchState, + flashMessage, + isOnline, + isServerOnline, + isSignedIn, + removeFlashMessage, + showFooter = true, + isChallenge = false, + block, + superBlock, + t, + theme = Themes.Default, + user, + fetchUser +}: DefaultLayoutProps): JSX.Element { + useEffect(() => { + // componentDidMount if (!isSignedIn) { fetchUser(); } - window.addEventListener('online', this.updateOnlineStatus); - window.addEventListener('offline', this.updateOnlineStatus); - } + window.addEventListener('online', updateOnlineStatus); + window.addEventListener('offline', updateOnlineStatus); - componentWillUnmount() { - window.removeEventListener('online', this.updateOnlineStatus); - window.removeEventListener('offline', this.updateOnlineStatus); - } + return () => { + // componentWillUnmount. + window.removeEventListener('online', updateOnlineStatus); + window.removeEventListener('offline', updateOnlineStatus); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - updateOnlineStatus = () => { - const { onlineStatusChange } = this.props; + const updateOnlineStatus = () => { const isOnline = isBrowser() && 'navigator' in window ? window.navigator.onLine : null; return typeof isOnline === 'boolean' ? onlineStatusChange(isOnline) : null; }; - render() { - const { - children, - hasMessage, - fetchState, - flashMessage, - isOnline, - isServerOnline, - isSignedIn, - removeFlashMessage, - showFooter = true, - isChallenge = false, - block, - superBlock, - t, - theme = 'default', - user - } = this.props; - - const useSystemTheme = fetchState.complete && isSignedIn === false; - - if (fetchState.pending) { - return ; - } + const useSystemTheme = fetchState.complete && isSignedIn === false; + if (fetchState.pending) { + return ; + } else { return (
              { } } +DefaultLayout.displayName = 'DefaultLayout'; + export default connect( mapStateToProps, mapDispatchToProps From 9191bd987a10a2aa76c7897f7665c4c6076f4358 Mon Sep 17 00:00:00 2001 From: Shaun Hamilton Date: Wed, 8 Feb 2023 21:41:12 +0000 Subject: [PATCH 10/52] fix(curriculum): soften regex test ad-node (#49240) --- .../implementation-of-social-authentication-iii.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curriculum/challenges/english/06-quality-assurance/advanced-node-and-express/implementation-of-social-authentication-iii.md b/curriculum/challenges/english/06-quality-assurance/advanced-node-and-express/implementation-of-social-authentication-iii.md index aef68751990..10be5ceeb48 100644 --- a/curriculum/challenges/english/06-quality-assurance/advanced-node-and-express/implementation-of-social-authentication-iii.md +++ b/curriculum/challenges/english/06-quality-assurance/advanced-node-and-express/implementation-of-social-authentication-iii.md @@ -61,7 +61,7 @@ async (getUserInput) => { ); assert.match( data, - /GitHubStrategy[^]*return cb/gi, + /GitHubStrategy[^]*cb/gi, 'Strategy should return the callback function "cb"' ); } From 335044fecef6271cf0eeac4b28b9d64a4e777b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20B=C4=85ba?= Date: Thu, 9 Feb 2023 05:59:05 +0100 Subject: [PATCH 11/52] fix(curriculum): delete repeated sentence on data visualization with D3 project (#49275) delete repeated sentence --- .../data-visualization-with-d3/change-styles-based-on-data.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.md index 1ed6ae7d5e2..8e2005e381f 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/change-styles-based-on-data.md @@ -8,8 +8,7 @@ dashedName: change-styles-based-on-data # --description-- -D3 is about visualization and presentation of data. It's likely you'll want to change the styling of elements based on the data. You can use a callback function in the `style()` method to change the styling for different elements. - +D3 is about visualization and presentation of data. It's likely you'll want to change the styling of elements based on the data. For example, you may want to color a data point blue if it has a value less than 20, and red otherwise. You can use a callback function in the `style()` method and include the conditional logic. The callback function uses the `d` parameter to represent the data point: ```js From 9b6042e44de8f4464247cce36bbb5e8b04238bdd Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:01:13 +0530 Subject: [PATCH 12/52] feat: enable mobile auth endpoints (#49298 Reverts #49212 --- api-server/package.json | 3 + api-server/src/common/models/user.js | 17 +++++ api-server/src/server/boot/authentication.js | 62 +++++++++++++++++- api-server/src/server/middleware.json | 5 +- .../src/server/middlewares/rate-limit.js | 19 ++++++ .../middlewares/request-authorization.js | 4 +- api-server/src/server/utils/middleware.js | 14 ++++ package-lock.json | 65 +++++++++++++++++++ 8 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 api-server/src/server/middlewares/rate-limit.js diff --git a/api-server/package.json b/api-server/package.json index 7be433231a7..8b2b9214fea 100644 --- a/api-server/package.json +++ b/api-server/package.json @@ -45,6 +45,7 @@ "dedent": "0.7.0", "dotenv": "6.2.0", "express-flash": "0.0.2", + "express-rate-limit": "^6.7.0", "express-session": "1.17.3", "express-validator": "6.14.1", "helmet": "3.23.3", @@ -60,12 +61,14 @@ "mongodb": "3.6.9", "morgan": "1.10.0", "nanoid": "3.3.4", + "node-fetch": "^2.6.7", "nodemailer-ses-transport": "1.5.1", "passport": "0.4.1", "passport-auth0": "1.4.2", "passport-local": "1.0.0", "passport-mock-strategy": "2.0.0", "query-string": "6.14.0", + "rate-limit-mongo": "^2.3.2", "rx": "4.1.0", "stripe": "8.205.0", "uuid": "3.4.0", diff --git a/api-server/src/common/models/user.js b/api-server/src/common/models/user.js index 31efb6a04d5..028ffcc7dc9 100644 --- a/api-server/src/common/models/user.js +++ b/api-server/src/common/models/user.js @@ -162,6 +162,8 @@ export default function initializeUser(User) { User.definition.properties.rand.default = getRandomNumber; // increase user accessToken ttl to 900 days User.settings.ttl = 900 * 24 * 60 * 60 * 1000; + // Sets ttl to 900 days for mobile login created access tokens + User.settings.maxTTL = 900 * 24 * 60 * 60 * 1000; // username should not be in blocklist User.validatesExclusionOf('username', { @@ -341,6 +343,21 @@ export default function initializeUser(User) { ); }; + User.prototype.mobileLoginByRequest = function mobileLoginByRequest( + req, + res + ) { + return new Promise((resolve, reject) => + this.createAccessToken({}, (err, accessToken) => { + if (err) { + return reject(err); + } + setAccessTokenToResponse({ accessToken }, req, res); + return resolve(accessToken); + }) + ); + }; + User.afterRemote('logout', function ({ req, res }, result, next) { removeCookies(req, res); next(); diff --git a/api-server/src/server/boot/authentication.js b/api-server/src/server/boot/authentication.js index b55a90cdc49..c7589da53ce 100644 --- a/api-server/src/server/boot/authentication.js +++ b/api-server/src/server/boot/authentication.js @@ -2,10 +2,9 @@ import dedent from 'dedent'; import { check } from 'express-validator'; import jwt from 'jsonwebtoken'; import passport from 'passport'; +import fetch from 'node-fetch'; import { isEmail } from 'validator'; - import { jwtSecret } from '../../../../config/secrets'; - import { decodeEmail } from '../../common/utils'; import { createPassportCallbackAuthenticator, @@ -14,7 +13,11 @@ import { } from '../component-passport'; import { wrapHandledError } from '../utils/create-handled-error.js'; import { removeCookies } from '../utils/getSetAccessToken'; -import { ifUserRedirectTo, ifNoUserRedirectHome } from '../utils/middleware'; +import { + ifUserRedirectTo, + ifNoUserRedirectHome, + ifNotMobileRedirect +} from '../utils/middleware'; import { getRedirectParams } from '../utils/redirection'; import { createDeleteUserToken } from '../middlewares/user-token'; @@ -34,6 +37,7 @@ module.exports = function enableAuthentication(app) { // enable loopback access control authentication. see: // loopback.io/doc/en/lb2/Authentication-authorization-and-permissions.html app.enableAuth(); + const ifNotMobile = ifNotMobileRedirect(); const ifUserRedirect = ifUserRedirectTo(); const ifNoUserRedirect = ifNoUserRedirectHome(); const devSaveAuthCookies = devSaveResponseAuthCookies(); @@ -87,6 +91,8 @@ module.exports = function enableAuthentication(app) { createGetPasswordlessAuth(app) ); + api.get('/mobile-login', ifNotMobile, ifUserRedirect, mobileLogin(app)); + app.use(api); }; @@ -188,3 +194,53 @@ function createGetPasswordlessAuth(app) { ); }; } + +function mobileLogin(app) { + const { + models: { User } + } = app; + return async function getPasswordlessAuth(req, res, next) { + try { + const auth0Res = await fetch( + `https://${process.env.AUTH0_DOMAIN}/userinfo`, + { + headers: { Authorization: req.headers.authorization } + } + ); + + if (!auth0Res.ok) { + return next( + wrapHandledError(new Error('Invalid Auth0 token'), { + type: 'danger', + message: 'We could not log you in, please try again in a moment.', + status: auth0Res.status + }) + ); + } + + const { email } = await auth0Res.json(); + + if (!isEmail(email)) { + return next( + wrapHandledError(new TypeError('decoded email is invalid'), { + type: 'danger', + message: 'The email is incorrectly formatted', + status: 400 + }) + ); + } + + User.findOne$({ where: { email } }) + .do(async user => { + if (!user) { + user = await User.create({ email }); + } + await user.mobileLoginByRequest(req, res); + res.end(); + }) + .subscribe(() => {}, next); + } catch (err) { + next(err); + } + }; +} diff --git a/api-server/src/server/middleware.json b/api-server/src/server/middleware.json index 69a47f44021..df8d4ae9ff8 100644 --- a/api-server/src/server/middleware.json +++ b/api-server/src/server/middleware.json @@ -39,7 +39,10 @@ "./middlewares/constant-headers": {}, "./middlewares/csp": {}, "./middlewares/flash-cheaters": {}, - "./middlewares/passport-login": {} + "./middlewares/passport-login": {}, + "./middlewares/rate-limit": { + "paths": ["/mobile-login"] + } }, "files": {}, "final:after": { diff --git a/api-server/src/server/middlewares/rate-limit.js b/api-server/src/server/middlewares/rate-limit.js new file mode 100644 index 00000000000..08f7b8e0d29 --- /dev/null +++ b/api-server/src/server/middlewares/rate-limit.js @@ -0,0 +1,19 @@ +import rateLimit from 'express-rate-limit'; +import MongoStore from 'rate-limit-mongo'; + +const url = process.env.MONGODB || process.env.MONGOHQ_URL; + +// Rate limit for mobile login +// 10 requests per 15 minute windows +export default function rateLimitMiddleware() { + return rateLimit({ + windowMs: 15 * 60 * 1000, + max: 10, + standardHeaders: true, + legacyHeaders: false, + store: new MongoStore({ + uri: url, + expireTimeMs: 15 * 60 * 1000 + }) + }); +} diff --git a/api-server/src/server/middlewares/request-authorization.js b/api-server/src/server/middlewares/request-authorization.js index b12858222bf..60aedcdb936 100644 --- a/api-server/src/server/middlewares/request-authorization.js +++ b/api-server/src/server/middlewares/request-authorization.js @@ -26,6 +26,7 @@ const updateHooksRE = /^\/hooks\/update-paypal$/; // note: this would be replaced by webhooks later const donateRE = /^\/donate\/charge-stripe$/; const submitCoderoadChallengeRE = /^\/coderoad-challenge-completed$/; +const mobileLoginRE = /^\/mobile-login\/?$/; const _pathsAllowedREs = [ authRE, @@ -41,7 +42,8 @@ const _pathsAllowedREs = [ unsubscribeRE, updateHooksRE, donateRE, - submitCoderoadChallengeRE + submitCoderoadChallengeRE, + mobileLoginRE ]; export function isAllowedPath(path, pathsAllowedREs = _pathsAllowedREs) { diff --git a/api-server/src/server/utils/middleware.js b/api-server/src/server/utils/middleware.js index 52f5551fc85..61144fae64b 100644 --- a/api-server/src/server/utils/middleware.js +++ b/api-server/src/server/utils/middleware.js @@ -77,6 +77,20 @@ export function ifUserRedirectTo(status) { }; } +export function ifNotMobileRedirect() { + return (req, res, next) => { + // + // Todo: Use the below check once we have done more research on usage + // + // const isMobile = /(iPhone|iPad|Android)/.test(req.headers['user-agent']); + // if (!isMobile) { + // res.json({ error: 'not from mobile' }); + // } else { + // next(); + // } + next(); + }; +} // for use with express-validator error formatter export const createValidatorErrorHandler = (...args) => diff --git a/package-lock.json b/package-lock.json index 6f0f4f68bac..a675d5ace56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -131,6 +131,7 @@ "dedent": "0.7.0", "dotenv": "6.2.0", "express-flash": "0.0.2", + "express-rate-limit": "^6.7.0", "express-session": "1.17.3", "express-validator": "6.14.1", "helmet": "3.23.3", @@ -146,12 +147,14 @@ "mongodb": "3.6.9", "morgan": "1.10.0", "nanoid": "3.3.4", + "node-fetch": "^2.6.7", "nodemailer-ses-transport": "1.5.1", "passport": "0.4.1", "passport-auth0": "1.4.2", "passport-local": "1.0.0", "passport-mock-strategy": "2.0.0", "query-string": "6.14.0", + "rate-limit-mongo": "^2.3.2", "rx": "4.1.0", "stripe": "8.205.0", "uuid": "3.4.0", @@ -24594,6 +24597,17 @@ "version": "1.2.0", "license": "ISC" }, + "node_modules/express-rate-limit": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", + "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", + "engines": { + "node": ">= 12.9.0" + }, + "peerDependencies": { + "express": "^4 || ^5" + } + }, "node_modules/express-session": { "version": "1.17.3", "license": "MIT", @@ -42419,6 +42433,21 @@ "node": ">= 0.6" } }, + "node_modules/rate-limit-mongo": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/rate-limit-mongo/-/rate-limit-mongo-2.3.2.tgz", + "integrity": "sha512-dLck0j5N/AX9ycVHn5lX9Ti2Wrrwi1LfbXitu/mMBZOo2nC26RgYKJVbcb2mYgb9VMaPI2IwJVzIa2hAQrMaDA==", + "dependencies": { + "mongodb": "^3.6.7", + "twostep": "0.4.2", + "underscore": "1.12.1" + } + }, + "node_modules/rate-limit-mongo/node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, "node_modules/raw-body": { "version": "2.5.1", "license": "MIT", @@ -50191,6 +50220,11 @@ "dev": true, "license": "MIT" }, + "node_modules/twostep": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", + "integrity": "sha512-O/wdPYk9ey04qcCiw8AQN74DbvLFZLAgnryrNTpV7T/sxB4lcGkCMHynx5xCcA6fCh739ZAqp3HcGhy770X1qA==" + }, "node_modules/type": { "version": "1.2.0", "license": "ISC" @@ -55889,6 +55923,7 @@ "dedent": "0.7.0", "dotenv": "6.2.0", "express-flash": "0.0.2", + "express-rate-limit": "^6.7.0", "express-session": "1.17.3", "express-validator": "6.14.1", "helmet": "3.23.3", @@ -55905,6 +55940,7 @@ "mongodb": "3.6.9", "morgan": "1.10.0", "nanoid": "3.3.4", + "node-fetch": "^2.6.7", "nodemailer-ses-transport": "1.5.1", "nodemon": "2.0.16", "passport": "0.4.1", @@ -55912,6 +55948,7 @@ "passport-local": "1.0.0", "passport-mock-strategy": "2.0.0", "query-string": "6.14.0", + "rate-limit-mongo": "^2.3.2", "rx": "4.1.0", "smee-client": "1.2.3", "stripe": "8.205.0", @@ -71687,6 +71724,12 @@ } } }, + "express-rate-limit": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-6.7.0.tgz", + "integrity": "sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA==", + "requires": {} + }, "express-session": { "version": "1.17.3", "requires": { @@ -83153,6 +83196,23 @@ "range-parser": { "version": "1.2.1" }, + "rate-limit-mongo": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/rate-limit-mongo/-/rate-limit-mongo-2.3.2.tgz", + "integrity": "sha512-dLck0j5N/AX9ycVHn5lX9Ti2Wrrwi1LfbXitu/mMBZOo2nC26RgYKJVbcb2mYgb9VMaPI2IwJVzIa2hAQrMaDA==", + "requires": { + "mongodb": "^3.6.7", + "twostep": "0.4.2", + "underscore": "1.12.1" + }, + "dependencies": { + "underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + } + } + }, "raw-body": { "version": "2.5.1", "requires": { @@ -88146,6 +88206,11 @@ "version": "1.5.0", "dev": true }, + "twostep": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/twostep/-/twostep-0.4.2.tgz", + "integrity": "sha512-O/wdPYk9ey04qcCiw8AQN74DbvLFZLAgnryrNTpV7T/sxB4lcGkCMHynx5xCcA6fCh739ZAqp3HcGhy770X1qA==" + }, "type": { "version": "1.2.0" }, From 2b6ac6f7316fb7d12dbb956ef2720b33bb691e7c Mon Sep 17 00:00:00 2001 From: Balaji Sivasakthi <65065614+balaji-sivasakthi@users.noreply.github.com> Date: Thu, 9 Feb 2023 16:42:47 +0530 Subject: [PATCH 13/52] fix(curriculum): fix bad use of comma in d3 course "add a tooltip to a d3 element step" (#49296) --- .../data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md index 28ee20400f9..e16937cbff9 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-with-d3/add-a-tooltip-to-a-d3-element.md @@ -8,7 +8,7 @@ dashedName: add-a-tooltip-to-a-d3-element # --description-- -A tooltip shows more information about an item on a page when the user hovers over that item. There are several ways to add a tooltip to a visualization, this challenge uses the SVG `title` element. +A tooltip shows more information about an item on a page when the user hovers over that item. There are several ways to add a tooltip to a visualization. This challenge uses the SVG `title` element. `title` pairs with the `text()` method to dynamically add data to the bars. From 1ce707bb923d991bae1cbfa7308b275f86280dd4 Mon Sep 17 00:00:00 2001 From: Jeremy L Thompson Date: Thu, 9 Feb 2023 04:45:57 -0700 Subject: [PATCH 14/52] Fix(curriculum) better order of tests for Nutrition Step 33 (#49299) * fix - better order of tests for Nutrition Step 33 --- .../615f5486b8fd4b71633f69b0.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f5486b8fd4b71633f69b0.md b/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f5486b8fd4b71633f69b0.md index 78579fdb8b3..deabca353ff 100644 --- a/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f5486b8fd4b71633f69b0.md +++ b/curriculum/challenges/english/14-responsive-web-design-22/learn-typography-by-building-a-nutrition-label/615f5486b8fd4b71633f69b0.md @@ -29,22 +29,22 @@ Your `p` element should come after your `.small-text` element. assert(document.querySelector('.small-text')?.nextElementSibling?.localName === 'p'); ``` -Your `p` element should have the text `Calories`. - -```js -assert(document.querySelector('.left-container')?.lastElementChild?.innerText === 'Calories'); -``` - Your `span` element should come after your `.left-container` element. ```js assert(document.querySelector('.left-container')?.nextElementSibling?.localName ==='span'); ``` +Your `p` element should have the text `Calories`. + +```js +assert(document.querySelector('.small-text')?.nextElementSibling?.innerText === 'Calories'); +``` + Your `span` element should have the text `230`. ```js -assert(document.querySelector('.calories-info')?.lastElementChild?.innerText === '230'); +assert(document.querySelector('.left-container')?.nextElementSibling?.innerText === '230'); ``` # --seed-- From f17a7a266bec964ba1ce89a820752b8eef1ef42f Mon Sep 17 00:00:00 2001 From: camperbot Date: Thu, 9 Feb 2023 19:21:09 +0530 Subject: [PATCH 15/52] chore(i18n,client): processed translations (#49307) --- client/i18n/locales/arabic/intro.json | 26 +++++++++++++------ client/i18n/locales/arabic/translations.json | 1 - .../locales/chinese-traditional/intro.json | 26 +++++++++++++------ .../chinese-traditional/translations.json | 1 - client/i18n/locales/chinese/intro.json | 26 +++++++++++++------ client/i18n/locales/chinese/translations.json | 1 - client/i18n/locales/espanol/intro.json | 26 +++++++++++++------ client/i18n/locales/espanol/translations.json | 1 - client/i18n/locales/german/intro.json | 26 +++++++++++++------ client/i18n/locales/german/translations.json | 1 - client/i18n/locales/italian/intro.json | 26 +++++++++++++------ client/i18n/locales/italian/translations.json | 1 - client/i18n/locales/japanese/intro.json | 26 +++++++++++++------ .../i18n/locales/japanese/translations.json | 1 - client/i18n/locales/portuguese/intro.json | 26 +++++++++++++------ .../i18n/locales/portuguese/translations.json | 1 - client/i18n/locales/ukrainian/intro.json | 26 +++++++++++++------ .../i18n/locales/ukrainian/translations.json | 1 - 18 files changed, 162 insertions(+), 81 deletions(-) diff --git a/client/i18n/locales/arabic/intro.json b/client/i18n/locales/arabic/intro.json index 7bd66b174b1..10bb7b668ca 100644 --- a/client/i18n/locales/arabic/intro.json +++ b/client/i18n/locales/arabic/intro.json @@ -778,14 +778,6 @@ "أسناد: Rosetta Code" ] }, - "the-odin-project": { - "title": "مشروع أودين", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "مشروع Euler", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "شهادة {{cert}}", "browse-other": "تصفح الشهادات المجانية الأخرى\n(نوصي بالقيام بها بالترتيب)", diff --git a/client/i18n/locales/arabic/translations.json b/client/i18n/locales/arabic/translations.json index a6f2db3f8b3..c8e03f6e144 100644 --- a/client/i18n/locales/arabic/translations.json +++ b/client/i18n/locales/arabic/translations.json @@ -302,7 +302,6 @@ "certs": "شهادة {{title}}" }, "editor-tabs": { - "info": "معلومات", "code": "الكود", "tests": "الاختبارات", "restart": "أعد التشغيل", diff --git a/client/i18n/locales/chinese-traditional/intro.json b/client/i18n/locales/chinese-traditional/intro.json index 3c4f393dd4b..6ee34449b97 100644 --- a/client/i18n/locales/chinese-traditional/intro.json +++ b/client/i18n/locales/chinese-traditional/intro.json @@ -778,14 +778,6 @@ "屬性:Rosetta 代碼" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "歐拉計劃", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "{{cert}} 認證", "browse-other": "瀏覽我們的其他免費認證\n(我們建議你按順序學習)", diff --git a/client/i18n/locales/chinese-traditional/translations.json b/client/i18n/locales/chinese-traditional/translations.json index 0be7fdf3146..cc2d192fe41 100644 --- a/client/i18n/locales/chinese-traditional/translations.json +++ b/client/i18n/locales/chinese-traditional/translations.json @@ -302,7 +302,6 @@ "certs": "{{title}} 認證" }, "editor-tabs": { - "info": "信息", "code": "編程", "tests": "測試", "restart": "重啓", diff --git a/client/i18n/locales/chinese/intro.json b/client/i18n/locales/chinese/intro.json index fcb1167338d..ce8beea0d5b 100644 --- a/client/i18n/locales/chinese/intro.json +++ b/client/i18n/locales/chinese/intro.json @@ -778,14 +778,6 @@ "属性:Rosetta 代码" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "欧拉计划", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "{{cert}} 认证", "browse-other": "浏览我们的其他免费认证\n(我们建议你按顺序学习)", diff --git a/client/i18n/locales/chinese/translations.json b/client/i18n/locales/chinese/translations.json index 2a0ae67e97f..363620e436c 100644 --- a/client/i18n/locales/chinese/translations.json +++ b/client/i18n/locales/chinese/translations.json @@ -302,7 +302,6 @@ "certs": "{{title}} 认证" }, "editor-tabs": { - "info": "信息", "code": "编程", "tests": "测试", "restart": "重启", diff --git a/client/i18n/locales/espanol/intro.json b/client/i18n/locales/espanol/intro.json index 325a88b33da..6779cf07a7f 100644 --- a/client/i18n/locales/espanol/intro.json +++ b/client/i18n/locales/espanol/intro.json @@ -778,14 +778,6 @@ "Atributo: Código Rosetta" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "Project Euler", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "Certificación de {{cert}}", "browse-other": "Navega por nuestras otras certificaciones gratuitas\n(recomendamos hacerlo en orden)", diff --git a/client/i18n/locales/espanol/translations.json b/client/i18n/locales/espanol/translations.json index 969ab8661f6..73a90666766 100644 --- a/client/i18n/locales/espanol/translations.json +++ b/client/i18n/locales/espanol/translations.json @@ -302,7 +302,6 @@ "certs": "Certificación {{title}}" }, "editor-tabs": { - "info": "Info", "code": "Código", "tests": "Pruebas", "restart": "Reiniciar", diff --git a/client/i18n/locales/german/intro.json b/client/i18n/locales/german/intro.json index 8a6cdac58c2..bfd275257ae 100644 --- a/client/i18n/locales/german/intro.json +++ b/client/i18n/locales/german/intro.json @@ -778,14 +778,6 @@ "Attribut: Rosetta Code" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "Projekt Euler", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "{{cert}} Zertifikat", "browse-other": "Stöbere in unseren anderen kostenlosen Zertifizierungen\n(Wir empfehlen, diese der Reihe nach zu erledigen)", diff --git a/client/i18n/locales/german/translations.json b/client/i18n/locales/german/translations.json index 6026281a64f..2d78036c031 100644 --- a/client/i18n/locales/german/translations.json +++ b/client/i18n/locales/german/translations.json @@ -302,7 +302,6 @@ "certs": "{{title}} Zertifizierung" }, "editor-tabs": { - "info": "Informationen", "code": "Code", "tests": "Tests", "restart": "Neustart", diff --git a/client/i18n/locales/italian/intro.json b/client/i18n/locales/italian/intro.json index b5b1cfa3350..8a5f63f04c5 100644 --- a/client/i18n/locales/italian/intro.json +++ b/client/i18n/locales/italian/intro.json @@ -778,14 +778,6 @@ "Fonte: Codice Rosetta" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "Progetto Eulero", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "Certificazione {{cert}}", "browse-other": "Sfoglia le altre nostre certificazioni gratuite\n(consigliamo di seguirle in ordine)", diff --git a/client/i18n/locales/italian/translations.json b/client/i18n/locales/italian/translations.json index 5a582964c31..18007266443 100644 --- a/client/i18n/locales/italian/translations.json +++ b/client/i18n/locales/italian/translations.json @@ -302,7 +302,6 @@ "certs": "Certificazione {{title}}" }, "editor-tabs": { - "info": "Informazioni", "code": "Codice", "tests": "Test", "restart": "Inizia da capo", diff --git a/client/i18n/locales/japanese/intro.json b/client/i18n/locales/japanese/intro.json index 9af30b573f4..140caa5a7d9 100644 --- a/client/i18n/locales/japanese/intro.json +++ b/client/i18n/locales/japanese/intro.json @@ -778,14 +778,6 @@ "作: Rosetta Code" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["A description is to be determined"] - }, - "the-odin-project-projects": { - "title": "The Odin Project Projects", - "intro": ["A description is to be determined"] - }, "project-euler": { "title": "プロジェクト・オイラー", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "{{cert}} 認定", "browse-other": "他の無料の認定講座を閲覧する\n(上から順に受講することをお勧めします)", diff --git a/client/i18n/locales/japanese/translations.json b/client/i18n/locales/japanese/translations.json index 778950dbae5..a0aa273780a 100644 --- a/client/i18n/locales/japanese/translations.json +++ b/client/i18n/locales/japanese/translations.json @@ -302,7 +302,6 @@ "certs": "{{title}} 認定講座" }, "editor-tabs": { - "info": "詳細", "code": "コード", "tests": "テスト", "restart": "リスタート", diff --git a/client/i18n/locales/portuguese/intro.json b/client/i18n/locales/portuguese/intro.json index 230c7ef5be1..ea6ec4d33e3 100644 --- a/client/i18n/locales/portuguese/intro.json +++ b/client/i18n/locales/portuguese/intro.json @@ -778,14 +778,6 @@ "Attribute: Rosetta Code" ] }, - "the-odin-project": { - "title": "The Odin Project", - "intro": ["Uma descrição deve ser determinada"] - }, - "the-odin-project-projects": { - "title": "Os projetos do The Odin Project", - "intro": ["Uma descrição deve ser determinada"] - }, "project-euler": { "title": "Projeto Euler", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "Certificação {{cert}}", "browse-other": "Navegue por nossas outras certificações gratuitas\n(recomendamos fazer isto em sequência)", diff --git a/client/i18n/locales/portuguese/translations.json b/client/i18n/locales/portuguese/translations.json index 1d3aaf2d105..1471ae2b7ad 100644 --- a/client/i18n/locales/portuguese/translations.json +++ b/client/i18n/locales/portuguese/translations.json @@ -302,7 +302,6 @@ "certs": "Certificação {{title}}" }, "editor-tabs": { - "info": "Informações", "code": "Código", "tests": "Testes", "restart": "Reiniciar", diff --git a/client/i18n/locales/ukrainian/intro.json b/client/i18n/locales/ukrainian/intro.json index 8ebbe1516d3..d6f04eaa4e3 100644 --- a/client/i18n/locales/ukrainian/intro.json +++ b/client/i18n/locales/ukrainian/intro.json @@ -778,14 +778,6 @@ "Атрибут: Rosetta Code" ] }, - "the-odin-project": { - "title": "Проєкт «Odin»", - "intro": ["Опис буде надано пізніше"] - }, - "the-odin-project-projects": { - "title": "Проєкти «Odin»", - "intro": ["Опис буде надано пізніше"] - }, "project-euler": { "title": "Проєкт «Ейлер»", "intro": [ @@ -795,6 +787,24 @@ } } }, + "the-odin-project": { + "title": "The Odin Project", + "intro": [ + "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", + "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", + "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + ], + "blocks": { + "top-learn-html-foundations": { + "title": "Learn HTML Foundations", + "intro": ["A description is to be determined"] + }, + "top-build-a-recipe-project": { + "title": "Learn HTML Foundations by Building a Recipe Page", + "intro": ["A description is to be determined"] + } + } + }, "misc-text": { "certification": "Сертифікація «{{cert}}»", "browse-other": "Перегляньте інші безоплатні сертифікації\n(ми рекомендуємо виконувати їх послідовно)", diff --git a/client/i18n/locales/ukrainian/translations.json b/client/i18n/locales/ukrainian/translations.json index 8f33c528b3c..4bb4a7e7e92 100644 --- a/client/i18n/locales/ukrainian/translations.json +++ b/client/i18n/locales/ukrainian/translations.json @@ -302,7 +302,6 @@ "certs": "Сертифікація «{{title}}»" }, "editor-tabs": { - "info": "Інформація", "code": "Код", "tests": "Тести", "restart": "Перезапустити", From 77c8809b00324f13f00733b16fdce6031692c4bd Mon Sep 17 00:00:00 2001 From: Muhammed Mustafa Date: Thu, 9 Feb 2023 21:37:22 +0200 Subject: [PATCH 16/52] refactor(client): cleanup honesty policy section (#49003) Co-authored-by: Bruce B Co-authored-by: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Co-authored-by: sidemt <25644062+sidemt@users.noreply.github.com> Co-authored-by: Mrugesh Mohapatra Co-authored-by: Quincy Larson --- client/i18n/locales/english/translations.json | 6 ++-- .../__snapshots__/Honesty.test.tsx.snap | 16 ++++----- client/src/components/settings/honesty.css | 16 ++++++--- client/src/components/settings/honesty.tsx | 34 +++++++------------ client/src/resources/honesty-policy.tsx | 2 +- .../e2e/default/settings/certifications.ts | 8 ++--- cypress/support/commands.ts | 2 +- 7 files changed, 39 insertions(+), 45 deletions(-) diff --git a/client/i18n/locales/english/translations.json b/client/i18n/locales/english/translations.json index ce97b267a1f..9ce112fd71e 100644 --- a/client/i18n/locales/english/translations.json +++ b/client/i18n/locales/english/translations.json @@ -15,8 +15,8 @@ "show-cert": "Show Certification", "claim-cert": "Claim Certification", "save-progress": "Save Progress", - "accepted-honesty": "You have accepted our Academic Honesty Policy.", - "agree": "Agree", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Save this portfolio item", "remove-portfolio": "Remove this portfolio item", "add-portfolio": "Add a new portfolio Item", @@ -517,7 +517,7 @@ "opens-new-window": "Opens in new window" }, "flash": { - "honest-first": "To claim a certification, you must first accept our academic honesty policy", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "Something really weird happened, if it happens again, please consider raising an issue on https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Something is not quite right. A report has been generated and the freeCodeCamp.org team have been notified", "went-wrong": "Something went wrong, please check and try again", diff --git a/client/src/components/settings/__snapshots__/Honesty.test.tsx.snap b/client/src/components/settings/__snapshots__/Honesty.test.tsx.snap index 9e6d5accbde..86dcb3e0089 100644 --- a/client/src/components/settings/__snapshots__/Honesty.test.tsx.snap +++ b/client/src/components/settings/__snapshots__/Honesty.test.tsx.snap @@ -2,7 +2,6 @@ exports[` snapshot when isHonest is false: Honesty 1`] = `
              @@ -14,16 +13,16 @@ exports[` snapshot when isHonest is false: Honesty 1`] = > -
              @@ -31,7 +30,6 @@ exports[` snapshot when isHonest is false: Honesty 1`] = exports[` snapshot when isHonest is true: HonestyAccepted 1`] = `
              @@ -43,18 +41,16 @@ exports[` snapshot when isHonest is true: HonestyAccepted > -
              diff --git a/client/src/components/settings/honesty.css b/client/src/components/settings/honesty.css index 4eab7d1efad..979df5c6c86 100644 --- a/client/src/components/settings/honesty.css +++ b/client/src/components/settings/honesty.css @@ -1,3 +1,14 @@ +#honesty-policy + :is( + button[aria-disabled='true'], + button[aria-disabled='true']:is(:focus, :hover) + ) { + background-color: var(--quaternary-background); + color: var(--secondary-color); + opacity: 0.65; + cursor: not-allowed; +} + .honesty-panel p { margin-inline: 10px; font-family: 'Lato', sans-serif; @@ -7,11 +18,6 @@ padding-top: 15px; } -.honesty-policy .disabled-agreed p { - margin-top: 0; - margin-bottom: 0; -} - .honesty-panel .btn-invert { color: var(--primary-background); } diff --git a/client/src/components/settings/honesty.tsx b/client/src/components/settings/honesty.tsx index c8db8c62c9d..b8c54e31d96 100644 --- a/client/src/components/settings/honesty.tsx +++ b/client/src/components/settings/honesty.tsx @@ -15,33 +15,25 @@ type HonestyProps = { const Honesty = ({ isHonest, updateIsHonest }: HonestyProps): JSX.Element => { const { t } = useTranslation(); - const button = isHonest ? ( - - ) : ( - - ); + const buttonText = isHonest + ? t('buttons.accepted-honesty') + : t('buttons.agree-honesty'); + return ( -
              +
              {t('settings.headings.honesty')} -
              - {button} +
              ); diff --git a/client/src/resources/honesty-policy.tsx b/client/src/resources/honesty-policy.tsx index dea6b82c460..2a3a3f489ed 100644 --- a/client/src/resources/honesty-policy.tsx +++ b/client/src/resources/honesty-policy.tsx @@ -3,7 +3,7 @@ import { Trans, useTranslation } from 'react-i18next'; const HonestyPolicy = (): JSX.Element => { const { t } = useTranslation(); - const email = 'team@freecodecamp.org'; + const email = 'support@freecodecamp.org'; return ( <> diff --git a/cypress/e2e/default/settings/certifications.ts b/cypress/e2e/default/settings/certifications.ts index ad242e24f09..02611708b68 100644 --- a/cypress/e2e/default/settings/certifications.ts +++ b/cypress/e2e/default/settings/certifications.ts @@ -13,10 +13,10 @@ describe('Settings certifications area', () => { expect($btns).to.have.length(16); }); cy.findByText('Show Certification').should('not.exist'); - cy.contains('Agree'); + cy.contains(`I agree to freeCodeCamp's Academic Honesty Policy.`); cy.contains('Claim Certification').click(); cy.contains( - 'To claim a certification, you must first accept our academic honesty policy' + 'To claim a certification, you must first agree to our academic honesty policy' ); }); }); @@ -29,8 +29,8 @@ describe('Settings certifications area', () => { it('Should update the user as they try to claim their certifications', () => { cy.visit('/settings'); - cy.contains('Agree').click(); - cy.contains('You have accepted our Academic Honesty Policy.'); + cy.contains(`I agree to freeCodeCamp's Academic Honesty Policy.`).click(); + cy.contains('You have agreed to our Academic Honesty Policy.'); cy.contains('Claim Certification').click(); cy.contains( 'It looks like you have not completed the necessary steps. Please complete the required projects to claim the Responsive Web Design Certification' diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 8087b69f2c7..e1121adf333 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -21,7 +21,7 @@ const setPrivacyTogglesToPublic = () => { }); cy.get('[data-cy=save-privacy-settings]').click(); cy.get('#honesty-policy').find('button').click(); - cy.contains('You have accepted our Academic Honesty Policy'); + cy.contains('You have agreed to our Academic Honesty Policy'); }; const goToSettings = () => { From eff2166262bdc6c49b25bf6817912264c78bf957 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:34:17 +0530 Subject: [PATCH 17/52] chore: rename redux actions (#49320) --- client/gatsby-browser.js | 2 +- client/gatsby-ssr.js | 2 +- client/src/components/Intro/intro.test.tsx | 2 +- client/src/components/app-mount-notifier.test.tsx | 2 +- .../components/profile/components/time-line.test.tsx | 2 +- .../profile/components/timeline-buttons.test.js | 2 +- client/src/components/settings/certification.test.tsx | 2 +- client/src/redux/{cookieValues.js => cookie-values.js} | 0 client/src/redux/{createStore.js => create-store.js} | 10 +++++----- client/src/redux/fetch-user-saga.js | 2 +- client/src/redux/{rootEpic.js => root-epic.js} | 2 +- client/src/redux/{rootReducer.js => root-reducer.js} | 2 +- client/src/redux/{rootSaga.js => root-saga.js} | 2 +- client/utils/gatsby/layout-selector.test.tsx | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) rename client/src/redux/{cookieValues.js => cookie-values.js} (100%) rename client/src/redux/{createStore.js => create-store.js} (86%) rename client/src/redux/{rootEpic.js => root-epic.js} (84%) rename client/src/redux/{rootReducer.js => root-reducer.js} (95%) rename client/src/redux/{rootSaga.js => root-saga.js} (89%) diff --git a/client/gatsby-browser.js b/client/gatsby-browser.js index 513cc8d8a55..f93c9c10a26 100644 --- a/client/gatsby-browser.js +++ b/client/gatsby-browser.js @@ -6,7 +6,7 @@ import { Provider } from 'react-redux'; import i18n from './i18n/config'; import AppMountNotifier from './src/components/app-mount-notifier'; -import { createStore } from './src/redux/createStore'; +import { createStore } from './src/redux/create-store'; import layoutSelector from './utils/gatsby/layout-selector'; import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper'; diff --git a/client/gatsby-ssr.js b/client/gatsby-ssr.js index e7995a365d0..c0f6e4237c6 100644 --- a/client/gatsby-ssr.js +++ b/client/gatsby-ssr.js @@ -4,7 +4,7 @@ import { I18nextProvider } from 'react-i18next'; import { Provider } from 'react-redux'; import i18n from './i18n/config'; -import { createStore } from './src/redux/createStore'; +import { createStore } from './src/redux/create-store'; import layoutSelector from './utils/gatsby/layout-selector'; import { getheadTagComponents, getPostBodyComponents } from './utils/tags'; import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper'; diff --git a/client/src/components/Intro/intro.test.tsx b/client/src/components/Intro/intro.test.tsx index d1000de9fa0..61a55fe76f0 100644 --- a/client/src/components/Intro/intro.test.tsx +++ b/client/src/components/Intro/intro.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Provider } from 'react-redux'; import renderer from 'react-test-renderer'; -import { createStore } from '../../redux/createStore'; +import { createStore } from '../../redux/create-store'; import Intro from '.'; diff --git a/client/src/components/app-mount-notifier.test.tsx b/client/src/components/app-mount-notifier.test.tsx index 94121daba6c..215d99c94c0 100644 --- a/client/src/components/app-mount-notifier.test.tsx +++ b/client/src/components/app-mount-notifier.test.tsx @@ -5,7 +5,7 @@ import { Provider } from 'react-redux'; import { i18nextCodes } from '../../../config/i18n'; import i18nTestConfig from '../../i18n/config-for-tests'; -import { createStore } from '../redux/createStore'; +import { createStore } from '../redux/create-store'; import AppMountNotifier from './app-mount-notifier'; jest.unmock('react-i18next'); diff --git a/client/src/components/profile/components/time-line.test.tsx b/client/src/components/profile/components/time-line.test.tsx index 5d0dd9a1da1..2fb3e4c8669 100644 --- a/client/src/components/profile/components/time-line.test.tsx +++ b/client/src/components/profile/components/time-line.test.tsx @@ -4,7 +4,7 @@ import { useStaticQuery } from 'gatsby'; import React from 'react'; import { render, screen } from '../../../../utils/test-utils'; -import { createStore } from '../../../redux/createStore'; +import { createStore } from '../../../redux/create-store'; import TimeLine from './time-line'; const store = createStore(); diff --git a/client/src/components/profile/components/timeline-buttons.test.js b/client/src/components/profile/components/timeline-buttons.test.js index 33337e2aa7b..6a4b619bb1b 100644 --- a/client/src/components/profile/components/timeline-buttons.test.js +++ b/client/src/components/profile/components/timeline-buttons.test.js @@ -3,7 +3,7 @@ import React from 'react'; import renderer from 'react-test-renderer'; import { Provider } from 'react-redux'; -import { createStore } from '../../../redux/createStore'; +import { createStore } from '../../../redux/create-store'; import completedChallenges from '../../../__mocks__/completed-challenges.json'; import Timeline from './time-line'; diff --git a/client/src/components/settings/certification.test.tsx b/client/src/components/settings/certification.test.tsx index 195b64dd920..2c6e033ace1 100644 --- a/client/src/components/settings/certification.test.tsx +++ b/client/src/components/settings/certification.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import React from 'react'; import { Provider } from 'react-redux'; -import { createStore } from '../../redux/createStore'; +import { createStore } from '../../redux/create-store'; import { CertificationSettings } from './certification'; diff --git a/client/src/redux/cookieValues.js b/client/src/redux/cookie-values.js similarity index 100% rename from client/src/redux/cookieValues.js rename to client/src/redux/cookie-values.js diff --git a/client/src/redux/createStore.js b/client/src/redux/create-store.js similarity index 86% rename from client/src/redux/createStore.js rename to client/src/redux/create-store.js index 75e19ea5017..93918f35dea 100644 --- a/client/src/redux/createStore.js +++ b/client/src/redux/create-store.js @@ -5,9 +5,9 @@ import createSagaMiddleware from 'redux-saga'; import envData from '../../../config/env.json'; import { isBrowser } from '../../utils'; -import rootEpic from './rootEpic'; -import rootReducer from './rootReducer'; -import rootSaga from './rootSaga'; +import rootEpic from './root-epic'; +import rootReducer from './root-reducer'; +import rootSaga from './root-saga'; const { environment } = envData; @@ -47,8 +47,8 @@ export const createStore = () => { epicMiddleware.run(rootEpic); if (module.hot) { // Enable Webpack hot module replacement for reducers - module.hot.accept('./rootReducer', () => { - const nextRootReducer = require('./rootReducer'); + module.hot.accept('./root-reducer', () => { + const nextRootReducer = require('./root-reducer'); store.replaceReducer(nextRootReducer); }); } diff --git a/client/src/redux/fetch-user-saga.js b/client/src/redux/fetch-user-saga.js index 20b4d65ddae..826cccc0697 100644 --- a/client/src/redux/fetch-user-saga.js +++ b/client/src/redux/fetch-user-saga.js @@ -7,7 +7,7 @@ import { fetchUserComplete, fetchUserError } from './actions'; -import { jwt } from './cookieValues'; +import { jwt } from './cookie-values'; function* fetchSessionUser() { if (!jwt) { diff --git a/client/src/redux/rootEpic.js b/client/src/redux/root-epic.js similarity index 84% rename from client/src/redux/rootEpic.js rename to client/src/redux/root-epic.js index dd956348596..81a0a6d7712 100644 --- a/client/src/redux/rootEpic.js +++ b/client/src/redux/root-epic.js @@ -1,7 +1,7 @@ import { combineEpics } from 'redux-observable'; import { epics as challengeEpics } from '../templates/Challenges/redux'; -import { epics as appEpics } from './'; +import { epics as appEpics } from '.'; const rootEpic = combineEpics(...appEpics, ...challengeEpics); diff --git a/client/src/redux/rootReducer.js b/client/src/redux/root-reducer.js similarity index 95% rename from client/src/redux/rootReducer.js rename to client/src/redux/root-reducer.js index 6c20a0672dd..056083926f1 100644 --- a/client/src/redux/rootReducer.js +++ b/client/src/redux/root-reducer.js @@ -16,7 +16,7 @@ import { import { ns as appNameSpace } from './action-types'; import { ns as settingsNameSpace, reducer as settings } from './settings'; import { FlashApp as flashNameSpace } from './types'; -import { reducer as app } from './'; +import { reducer as app } from '.'; export default combineReducers({ [appNameSpace]: app, diff --git a/client/src/redux/rootSaga.js b/client/src/redux/root-saga.js similarity index 89% rename from client/src/redux/rootSaga.js rename to client/src/redux/root-saga.js index ec83d4a5b6e..f2d293bebd3 100644 --- a/client/src/redux/rootSaga.js +++ b/client/src/redux/root-saga.js @@ -3,7 +3,7 @@ import { all } from 'redux-saga/effects'; import { sagas as challengeSagas } from '../templates/Challenges/redux'; import errorSagas from './error-saga'; import { sagas as settingsSagas } from './settings'; -import { sagas as appSagas } from './'; +import { sagas as appSagas } from '.'; export default function* rootSaga() { yield all([...errorSagas, ...appSagas, ...challengeSagas, ...settingsSagas]); diff --git a/client/utils/gatsby/layout-selector.test.tsx b/client/utils/gatsby/layout-selector.test.tsx index ac769f44d1a..f56a25a68fb 100644 --- a/client/utils/gatsby/layout-selector.test.tsx +++ b/client/utils/gatsby/layout-selector.test.tsx @@ -6,7 +6,7 @@ import ShallowRenderer from 'react-test-renderer/shallow'; import FourOhFourPage from '../../src/pages/404'; import Certification from '../../src/pages/certification'; import Learn from '../../src/pages/learn'; -import { createStore } from '../../src/redux/createStore'; +import { createStore } from '../../src/redux/create-store'; import layoutSelector from './layout-selector'; jest.mock('../../src/analytics'); From 96a5699c39c9671b36269d2b22e608f7130748ba Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:41:16 +0530 Subject: [PATCH 18/52] chore: rename icons (#49319) --- client/src/assets/icons/{API-icon.tsx => api.tsx} | 0 .../{certification-icon.tsx => certification.tsx} | 0 client/src/assets/icons/{D3-icon.tsx => d3.tsx} | 0 .../icons/{Database-icon.tsx => database.tsx} | 0 .../{FreeCodeCamp-logo.tsx => freecodecamp.tsx} | 0 client/src/assets/icons/index.tsx | 14 +++++++------- .../icons/{inputReset.tsx => input-reset.tsx} | 0 .../icons/{JavaScript-icon.tsx => javascript.tsx} | 0 .../assets/icons/{Magnifier.tsx => magnifier.tsx} | 0 .../assets/icons/{python-icon.tsx => python.tsx} | 0 .../src/assets/icons/{React-icon.tsx => react.tsx} | 0 .../icons/{Tensorflow-icon.tsx => tensorflow.tsx} | 0 .../src/client-only-routes/show-certification.tsx | 2 +- .../src/components/Header/components/nav-logo.tsx | 2 +- .../components/profile/components/time-line.tsx | 2 +- .../search/searchBar/search-bar-optimized.tsx | 4 ++-- 16 files changed, 12 insertions(+), 12 deletions(-) rename client/src/assets/icons/{API-icon.tsx => api.tsx} (100%) rename client/src/assets/icons/{certification-icon.tsx => certification.tsx} (100%) rename client/src/assets/icons/{D3-icon.tsx => d3.tsx} (100%) rename client/src/assets/icons/{Database-icon.tsx => database.tsx} (100%) rename client/src/assets/icons/{FreeCodeCamp-logo.tsx => freecodecamp.tsx} (100%) rename client/src/assets/icons/{inputReset.tsx => input-reset.tsx} (100%) rename client/src/assets/icons/{JavaScript-icon.tsx => javascript.tsx} (100%) rename client/src/assets/icons/{Magnifier.tsx => magnifier.tsx} (100%) rename client/src/assets/icons/{python-icon.tsx => python.tsx} (100%) rename client/src/assets/icons/{React-icon.tsx => react.tsx} (100%) rename client/src/assets/icons/{Tensorflow-icon.tsx => tensorflow.tsx} (100%) diff --git a/client/src/assets/icons/API-icon.tsx b/client/src/assets/icons/api.tsx similarity index 100% rename from client/src/assets/icons/API-icon.tsx rename to client/src/assets/icons/api.tsx diff --git a/client/src/assets/icons/certification-icon.tsx b/client/src/assets/icons/certification.tsx similarity index 100% rename from client/src/assets/icons/certification-icon.tsx rename to client/src/assets/icons/certification.tsx diff --git a/client/src/assets/icons/D3-icon.tsx b/client/src/assets/icons/d3.tsx similarity index 100% rename from client/src/assets/icons/D3-icon.tsx rename to client/src/assets/icons/d3.tsx diff --git a/client/src/assets/icons/Database-icon.tsx b/client/src/assets/icons/database.tsx similarity index 100% rename from client/src/assets/icons/Database-icon.tsx rename to client/src/assets/icons/database.tsx diff --git a/client/src/assets/icons/FreeCodeCamp-logo.tsx b/client/src/assets/icons/freecodecamp.tsx similarity index 100% rename from client/src/assets/icons/FreeCodeCamp-logo.tsx rename to client/src/assets/icons/freecodecamp.tsx diff --git a/client/src/assets/icons/index.tsx b/client/src/assets/icons/index.tsx index ae851d8eeb7..839f2090965 100644 --- a/client/src/assets/icons/index.tsx +++ b/client/src/assets/icons/index.tsx @@ -1,15 +1,15 @@ import React from 'react'; import { SuperBlocks } from '../../../../config/certification-settings'; -import APIIcon from './API-icon'; -import D3Icon from './D3-icon'; -import DatabaseIcon from './Database-icon'; -import JavaScriptIcon from './JavaScript-icon'; -import ReactIcon from './React-icon'; -import TensorflowIcon from './Tensorflow-icon'; +import APIIcon from './api'; +import D3Icon from './d3'; +import DatabaseIcon from './database'; +import JavaScriptIcon from './javascript'; +import ReactIcon from './react'; +import TensorflowIcon from './tensorflow'; import Algorithm from './algorithm'; import Analytics from './analytics'; import Clipboard from './clipboard'; -import PythonIcon from './python-icon'; +import PythonIcon from './python'; import ResponsiveDesign from './responsive-design'; import Shield from './shield'; import VikingHelmet from './viking-helmet'; diff --git a/client/src/assets/icons/inputReset.tsx b/client/src/assets/icons/input-reset.tsx similarity index 100% rename from client/src/assets/icons/inputReset.tsx rename to client/src/assets/icons/input-reset.tsx diff --git a/client/src/assets/icons/JavaScript-icon.tsx b/client/src/assets/icons/javascript.tsx similarity index 100% rename from client/src/assets/icons/JavaScript-icon.tsx rename to client/src/assets/icons/javascript.tsx diff --git a/client/src/assets/icons/Magnifier.tsx b/client/src/assets/icons/magnifier.tsx similarity index 100% rename from client/src/assets/icons/Magnifier.tsx rename to client/src/assets/icons/magnifier.tsx diff --git a/client/src/assets/icons/python-icon.tsx b/client/src/assets/icons/python.tsx similarity index 100% rename from client/src/assets/icons/python-icon.tsx rename to client/src/assets/icons/python.tsx diff --git a/client/src/assets/icons/React-icon.tsx b/client/src/assets/icons/react.tsx similarity index 100% rename from client/src/assets/icons/React-icon.tsx rename to client/src/assets/icons/react.tsx diff --git a/client/src/assets/icons/Tensorflow-icon.tsx b/client/src/assets/icons/tensorflow.tsx similarity index 100% rename from client/src/assets/icons/Tensorflow-icon.tsx rename to client/src/assets/icons/tensorflow.tsx diff --git a/client/src/client-only-routes/show-certification.tsx b/client/src/client-only-routes/show-certification.tsx index 6ac89c242ed..6edff2f96a5 100644 --- a/client/src/client-only-routes/show-certification.tsx +++ b/client/src/client-only-routes/show-certification.tsx @@ -9,7 +9,7 @@ import { createSelector } from 'reselect'; import envData from '../../../config/env.json'; import { getLangCode } from '../../../config/i18n'; -import FreeCodeCampLogo from '../assets/icons/FreeCodeCamp-logo'; +import FreeCodeCampLogo from '../assets/icons/freecodecamp'; import DonateForm from '../components/Donation/donate-form'; import { createFlashMessage } from '../components/Flash/redux'; diff --git a/client/src/components/Header/components/nav-logo.tsx b/client/src/components/Header/components/nav-logo.tsx index 94111b149c7..393b8f32df0 100644 --- a/client/src/components/Header/components/nav-logo.tsx +++ b/client/src/components/Header/components/nav-logo.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import FreeCodeCampLogo from '../../../assets/icons/FreeCodeCamp-logo'; +import FreeCodeCampLogo from '../../../assets/icons/freecodecamp'; const NavLogo = (): JSX.Element => { const { t } = useTranslation(); diff --git a/client/src/components/profile/components/time-line.tsx b/client/src/components/profile/components/time-line.tsx index b9c19a0d426..38f65146227 100644 --- a/client/src/components/profile/components/time-line.tsx +++ b/client/src/components/profile/components/time-line.tsx @@ -14,7 +14,7 @@ import { getTitleFromId } from '../../../../../utils'; import { regeneratePathAndHistory } from '../../../../../utils/polyvinyl'; -import CertificationIcon from '../../../assets/icons/certification-icon'; +import CertificationIcon from '../../../assets/icons/certification'; import { CompletedChallenge } from '../../../redux/prop-types'; import ProjectPreviewModal from '../../../templates/Challenges/components/project-preview-modal'; import { openModal } from '../../../templates/Challenges/redux/actions'; diff --git a/client/src/components/search/searchBar/search-bar-optimized.tsx b/client/src/components/search/searchBar/search-bar-optimized.tsx index b7464973424..68be861c940 100644 --- a/client/src/components/search/searchBar/search-bar-optimized.tsx +++ b/client/src/components/search/searchBar/search-bar-optimized.tsx @@ -1,7 +1,7 @@ import React, { useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; -import Magnifier from '../../../assets/icons/Magnifier'; -import InputReset from '../../../assets/icons/inputReset'; +import Magnifier from '../../../assets/icons/magnifier'; +import InputReset from '../../../assets/icons/input-reset'; import { searchPageUrl } from '../../../utils/algolia-locale-setup'; type Props = { From 0f4fd9d57b6465b3299ceb5e6f8f6d92910d2839 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:42:02 +0530 Subject: [PATCH 19/52] chore: rename mockfiles in jest config (#49318) --- client/src/__mocks__/{fileMock.ts => file-mock.ts} | 0 client/src/__mocks__/{styleMock.ts => style-mock.ts} | 0 jest.config.js | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename client/src/__mocks__/{fileMock.ts => file-mock.ts} (100%) rename client/src/__mocks__/{styleMock.ts => style-mock.ts} (100%) diff --git a/client/src/__mocks__/fileMock.ts b/client/src/__mocks__/file-mock.ts similarity index 100% rename from client/src/__mocks__/fileMock.ts rename to client/src/__mocks__/file-mock.ts diff --git a/client/src/__mocks__/styleMock.ts b/client/src/__mocks__/style-mock.ts similarity index 100% rename from client/src/__mocks__/styleMock.ts rename to client/src/__mocks__/style-mock.ts diff --git a/jest.config.js b/jest.config.js index 20a49f14a3e..84689f41854 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,11 +2,11 @@ module.exports = { testPathIgnorePatterns: ['/node_modules/'], moduleNameMapper: { '\\.(jpg|jpeg|png|svg|woff|woff2)$': - '/client/src/__mocks__/fileMock.ts', + '/client/src/__mocks__/file-mock.ts', // Plain CSS - match css files that don't end with // '.module.css' https://regex101.com/r/VzwrKH/4 '^(?!.*\\.module\\.css$).*\\.css$': - '/client/src/__mocks__/styleMock.ts', + '/client/src/__mocks__/style-mock.ts', // CSS Modules - match files that end with 'module.css' '\\.module\\.css$': 'identity-obj-proxy', '^lodash-es$': 'lodash' From ffc97f15d1ea3c3f956ef745ff4377ed7de41cf6 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:43:54 +0530 Subject: [PATCH 20/52] fix(api): update mobile-auth ratelimit config (#49194) * fix(api): use proper name for collection * fix(api): use the x-forwarded-for ip address --- api-server/src/server/middlewares/rate-limit.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api-server/src/server/middlewares/rate-limit.js b/api-server/src/server/middlewares/rate-limit.js index 08f7b8e0d29..b461039a12c 100644 --- a/api-server/src/server/middlewares/rate-limit.js +++ b/api-server/src/server/middlewares/rate-limit.js @@ -11,7 +11,11 @@ export default function rateLimitMiddleware() { max: 10, standardHeaders: true, legacyHeaders: false, + keyGenerator: req => { + return req.headers['x-forwarded-for'] || 'localhost'; + }, store: new MongoStore({ + collectionName: 'UserRateLimit', uri: url, expireTimeMs: 15 * 60 * 1000 }) From 6e53c852de3f2ce2b6fd6117c1903d4c3d41368b Mon Sep 17 00:00:00 2001 From: Ahmad Abdolsaheb Date: Fri, 10 Feb 2023 16:16:11 +0300 Subject: [PATCH 21/52] feat(client): pull percentage challenge data from redux (#49308) * feat(client): pull percentage challenge data from redux * Apply suggestions from code review Co-authored-by: Oliver Eyton-Williams Co-authored-by: Tom <20648924+moT01@users.noreply.github.com> * feat: update updateAllChallengesInfo name --------- Co-authored-by: Oliver Eyton-Williams Co-authored-by: Tom <20648924+moT01@users.noreply.github.com> --- client/src/components/layouts/default.tsx | 63 +++++++++++++++++-- client/src/redux/action-types.js | 1 + client/src/redux/actions.js | 4 ++ client/src/redux/index.js | 9 ++- client/src/redux/prop-types.ts | 13 ++++ client/src/redux/selectors.js | 2 + .../components/completion-modal.tsx | 62 ++++-------------- 7 files changed, 99 insertions(+), 55 deletions(-) diff --git a/client/src/components/layouts/default.tsx b/client/src/components/layouts/default.tsx index ad865472aec..a86eae022a8 100644 --- a/client/src/components/layouts/default.tsx +++ b/client/src/components/layouts/default.tsx @@ -4,6 +4,7 @@ import { TFunction, withTranslation } from 'react-i18next'; import { connect } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; import { createSelector } from 'reselect'; +import { useStaticQuery, graphql } from 'gatsby'; import latoBoldURL from '../../../static/fonts/lato/Lato-Bold.woff'; import latoLightURL from '../../../static/fonts/lato/Lato-Light.woff'; @@ -16,7 +17,8 @@ import { isBrowser } from '../../../utils'; import { fetchUser, onlineStatusChange, - serverStatusChange + serverStatusChange, + updateAllChallengesInfo } from '../../redux/actions'; import { isSignedInSelector, @@ -26,7 +28,12 @@ import { userFetchStateSelector } from '../../redux/selectors'; -import { UserFetchState, User } from '../../redux/prop-types'; +import { + UserFetchState, + User, + AllChallengeNode, + CertificateNode +} from '../../redux/prop-types'; import BreadCrumb from '../../templates/Challenges/components/bread-crumb'; import Flash from '../Flash'; import { flashMessageSelector, removeFlashMessage } from '../Flash/redux'; @@ -77,7 +84,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => fetchUser, removeFlashMessage, onlineStatusChange, - serverStatusChange + serverStatusChange, + updateAllChallengesInfo }, dispatch ); @@ -117,10 +125,13 @@ function DefaultLayout({ t, theme = Themes.Default, user, - fetchUser + fetchUser, + updateAllChallengesInfo }: DefaultLayoutProps): JSX.Element { + const { challengeEdges, certificateNodes } = useGetAllBlockIds(); useEffect(() => { // componentDidMount + updateAllChallengesInfo({ challengeEdges, certificateNodes }); if (!isSignedIn) { fetchUser(); } @@ -237,6 +248,50 @@ function DefaultLayout({ } } +// TODO: get challenge nodes directly rather than wrapped in edges +const useGetAllBlockIds = () => { + const { + allChallengeNode: { edges: challengeEdges }, + allCertificateNode: { nodes: certificateNodes } + }: { + allChallengeNode: AllChallengeNode; + allCertificateNode: { nodes: CertificateNode[] }; + } = useStaticQuery(graphql` + query getBlockNode { + allChallengeNode( + sort: { + fields: [ + challenge___superOrder + challenge___order + challenge___challengeOrder + ] + } + ) { + edges { + node { + challenge { + block + id + } + } + } + } + allCertificateNode { + nodes { + challenge { + certification + tests { + id + } + } + } + } + } + `); + + return { challengeEdges, certificateNodes }; +}; + DefaultLayout.displayName = 'DefaultLayout'; export default connect( diff --git a/client/src/redux/action-types.js b/client/src/redux/action-types.js index 7aa77c37257..c4c3e7b12c5 100644 --- a/client/src/redux/action-types.js +++ b/client/src/redux/action-types.js @@ -27,6 +27,7 @@ export const actionTypes = createTypes( 'updateDonationFormState', 'updateUserToken', 'postChargeProcessing', + 'updateAllChallengesInfo', ...createAsyncTypes('fetchUser'), ...createAsyncTypes('postCharge'), ...createAsyncTypes('fetchProfileForUser'), diff --git a/client/src/redux/actions.js b/client/src/redux/actions.js index 43c1d3923b9..38608a046bc 100644 --- a/client/src/redux/actions.js +++ b/client/src/redux/actions.js @@ -53,6 +53,10 @@ export const fetchUser = createAction(actionTypes.fetchUser); export const fetchUserComplete = createAction(actionTypes.fetchUserComplete); export const fetchUserError = createAction(actionTypes.fetchUserError); +export const updateAllChallengesInfo = createAction( + actionTypes.updateAllChallengesInfo +); + export const postCharge = createAction(actionTypes.postCharge); export const postChargeProcessing = createAction( actionTypes.postChargeProcessing diff --git a/client/src/redux/index.js b/client/src/redux/index.js index 9dbaf84a81e..a6328ee5980 100644 --- a/client/src/redux/index.js +++ b/client/src/redux/index.js @@ -56,6 +56,10 @@ const initialState = { userFetchState: { ...defaultFetchState }, + allChallengesInfo: { + challengeEdges: [], + certificateNodes: [] + }, userProfileFetchState: { ...defaultFetchState }, @@ -153,7 +157,10 @@ export const reducer = handleActions( ...state, donationFormState: { ...defaultDonationFormState, error: payload } }), - + [actionTypes.updateAllChallengesInfo]: (state, { payload }) => ({ + ...state, + allChallengesInfo: { ...payload } + }), [actionTypes.fetchUser]: state => ({ ...state, userFetchState: { ...defaultFetchState } diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index e7444fcb018..062b201a3eb 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -142,6 +142,19 @@ export type ChallengeNode = { }; }; +export type CertificateNode = { + challenge: { + // TODO: use enum + certification: string; + tests: { id: string }[]; + }; +}; + +export type AllChallengesInfo = { + challengeEdges: { node: ChallengeNode }[]; + certificateNodes: CertificateNode[]; +}; + export type AllChallengeNode = { edges: [ { diff --git a/client/src/redux/selectors.js b/client/src/redux/selectors.js index 9faca5b8eab..eb6c71697c5 100644 --- a/client/src/redux/selectors.js +++ b/client/src/redux/selectors.js @@ -202,6 +202,8 @@ export const certificatesByNameSelector = username => state => { }; export const userFetchStateSelector = state => state[MainApp].userFetchState; +export const allChallengesInfoSelector = state => + state[MainApp].allChallengesInfo; export const userProfileFetchStateSelector = state => state[MainApp].userProfileFetchState; export const usernameSelector = state => state[MainApp].appUsername; diff --git a/client/src/templates/Challenges/components/completion-modal.tsx b/client/src/templates/Challenges/components/completion-modal.tsx index 95e64be8f98..de8c7076b8c 100644 --- a/client/src/templates/Challenges/components/completion-modal.tsx +++ b/client/src/templates/Challenges/components/completion-modal.tsx @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/restrict-template-expressions */ import { Button, Modal } from '@freecodecamp/react-bootstrap'; -import { useStaticQuery, graphql } from 'gatsby'; import { noop } from 'lodash-es'; import React, { Component } from 'react'; import { TFunction, withTranslation } from 'react-i18next'; @@ -13,8 +12,11 @@ import { dasherize } from '../../../../../utils/slugs'; import { isFinalProject } from '../../../../utils/challenge-types'; import Login from '../../../components/Header/components/Login'; import { executeGA, allowBlockDonationRequests } from '../../../redux/actions'; -import { isSignedInSelector } from '../../../redux/selectors'; -import { AllChallengeNode, ChallengeFiles } from '../../../redux/prop-types'; +import { + isSignedInSelector, + allChallengesInfoSelector +} from '../../../redux/selectors'; +import { AllChallengesInfo, ChallengeFiles } from '../../../redux/prop-types'; import { closeModal, submitChallenge } from '../redux/actions'; import { @@ -34,6 +36,7 @@ const mapStateToProps = createSelector( completedChallengesIds, isCompletionModalOpenSelector, isSignedInSelector, + allChallengesInfoSelector, successMessageSelector, ( challengeFiles: ChallengeFiles, @@ -45,6 +48,7 @@ const mapStateToProps = createSelector( completedChallengesIds: string[], isOpen: boolean, isSignedIn: boolean, + allChallengesInfo: AllChallengesInfo, message: string ) => ({ challengeFiles, @@ -54,6 +58,7 @@ const mapStateToProps = createSelector( completedChallengesIds, isOpen, isSignedIn, + allChallengesInfo, message }) ); @@ -118,6 +123,7 @@ interface CompletionModalsProps { id: string; isOpen: boolean; isSignedIn: boolean; + allChallengesInfo: AllChallengesInfo; message: string; submitChallenge: () => void; superBlock: string; @@ -324,58 +330,13 @@ interface Options { isFinalProjectBlock: boolean; } -interface CertificateNode { - challenge: { - // TODO: use enum - certification: string; - tests: { id: string }[]; - }; -} - const useCurrentBlockIds = ( + allChallengesInfo: AllChallengesInfo, block: string, certification: string, options?: Options ) => { - const { - allChallengeNode: { edges: challengeEdges }, - allCertificateNode: { nodes: certificateNodes } - }: { - allChallengeNode: AllChallengeNode; - allCertificateNode: { nodes: CertificateNode[] }; - } = useStaticQuery(graphql` - query getCurrentBlockNodes { - allChallengeNode( - sort: { - fields: [ - challenge___superOrder - challenge___order - challenge___challengeOrder - ] - } - ) { - edges { - node { - challenge { - block - id - } - } - } - } - allCertificateNode { - nodes { - challenge { - certification - tests { - id - } - } - } - } - } - `); - + const { challengeEdges, certificateNodes } = allChallengesInfo; const currentCertificateIds = certificateNodes .filter( node => dasherize(node.challenge.certification) === certification @@ -390,6 +351,7 @@ const useCurrentBlockIds = ( const CompletionModal = (props: CompletionModalsProps) => { const currentBlockIds = useCurrentBlockIds( + props.allChallengesInfo, props.block || '', props.certification || '', // eslint-disable-next-line @typescript-eslint/no-unsafe-call From 47ffd20f74cebe779308a1f8d526c1b074e92590 Mon Sep 17 00:00:00 2001 From: Muhammed Mustafa Date: Fri, 10 Feb 2023 15:24:23 +0200 Subject: [PATCH 22/52] fix(client): add type to warn misuse of attributes in formControl (#48696) * feat: add type to warn miss usage of attributes in formControl Co-authored-by: Oliver Eyton-Williams * refactor the value type Co-authored-by: sembauke * add condition type for readyonly and onchange types * warn when using readonly and onchange props together Co-authored-by: Ahmad Abdolsaheb * allow value to be undefined * Make read-only undefined Co-authored-by: Ahmad Abdolsaheb --------- Co-authored-by: Oliver Eyton-Williams Co-authored-by: sembauke Co-authored-by: Ahmad Abdolsaheb --- tools/ui-components/src/form-control/types.ts | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/ui-components/src/form-control/types.ts b/tools/ui-components/src/form-control/types.ts index d26f2c1b1d6..41c77d5d169 100644 --- a/tools/ui-components/src/form-control/types.ts +++ b/tools/ui-components/src/form-control/types.ts @@ -2,20 +2,34 @@ import React from 'react'; export type FormControlElement = HTMLInputElement | HTMLTextAreaElement; -export interface FormControlProps - extends React.HTMLAttributes { +type ChangibleValues = + | { + value?: never; + onChange?: never; + readonly?: never; + } + | { + value: string; + onChange?: never; + readonly: boolean; + } + | { + value: string; + onChange: (event: React.ChangeEvent) => void; + readonly?: never; + }; + +export type FormControlProps = React.HTMLAttributes & { className?: string; id?: string; testId?: string; - onChange?: React.ChangeEventHandler; - value?: string; componentClass?: typeof React.Component; placeholder?: string; name?: string; required?: boolean; rows?: number; type?: 'text' | 'email' | 'url'; -} +} & ChangibleValues; export interface FormControlVariationProps { className?: string; From 8a66f2967dae5e68073d41d7f1eed9217e6cb47b Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 21:51:43 +0530 Subject: [PATCH 23/52] chore: rename curriculum tooling (#49333) --- curriculum/test/test-challenges.js | 4 ++-- .../test/utils/{challengeTitles.js => challenge-titles.js} | 0 curriculum/test/utils/{mongoIds.js => mongo-ids.js} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename curriculum/test/utils/{challengeTitles.js => challenge-titles.js} (100%) rename curriculum/test/utils/{mongoIds.js => mongo-ids.js} (100%) diff --git a/curriculum/test/test-challenges.js b/curriculum/test/test-challenges.js index 115e0915170..65eb5aa005b 100644 --- a/curriculum/test/test-challenges.js +++ b/curriculum/test/test-challenges.js @@ -44,8 +44,8 @@ const { getLines } = require('../../utils/get-lines'); const { getChallengesForLang, getMetaForBlock } = require('../getChallenges'); const { challengeSchemaValidator } = require('../schema/challengeSchema'); const { testedLang, getSuperOrder } = require('../utils'); -const ChallengeTitles = require('./utils/challengeTitles'); -const MongoIds = require('./utils/mongoIds'); +const ChallengeTitles = require('./utils/challenge-titles'); +const MongoIds = require('./utils/mongo-ids'); const createPseudoWorker = require('./utils/pseudo-worker'); const { sortChallenges } = require('./utils/sort-challenges'); diff --git a/curriculum/test/utils/challengeTitles.js b/curriculum/test/utils/challenge-titles.js similarity index 100% rename from curriculum/test/utils/challengeTitles.js rename to curriculum/test/utils/challenge-titles.js diff --git a/curriculum/test/utils/mongoIds.js b/curriculum/test/utils/mongo-ids.js similarity index 100% rename from curriculum/test/utils/mongoIds.js rename to curriculum/test/utils/mongo-ids.js From 63762164d5870d618a7e41dac713f635c0fb704d Mon Sep 17 00:00:00 2001 From: a2937 Date: Fri, 10 Feb 2023 11:47:39 -0500 Subject: [PATCH 24/52] chore: migrate navigation bar tests to TypeScript (#49215) * Chore: Rename navbar * Remove error suppressors * Fix the prototype issue * Experiment with listeners * Fix the arguments problem. * Remove anti-pattern loader. * Fix: Properly wait for the page to load. --- .../default/learn/common-components/navbar.js | 115 ------------------ .../default/learn/common-components/navbar.ts | 91 ++++++++++++++ 2 files changed, 91 insertions(+), 115 deletions(-) delete mode 100644 cypress/e2e/default/learn/common-components/navbar.js create mode 100644 cypress/e2e/default/learn/common-components/navbar.ts diff --git a/cypress/e2e/default/learn/common-components/navbar.js b/cypress/e2e/default/learn/common-components/navbar.js deleted file mode 100644 index 928cc7ee714..00000000000 --- a/cypress/e2e/default/learn/common-components/navbar.js +++ /dev/null @@ -1,115 +0,0 @@ -const selectors = { - heading: "[data-test-label='landing-header']", - smallCallToAction: "[data-test-label='landing-small-cta']", - navigationLinks: '.nav-list', - avatarContainer: '.avatar-container', - defaultAvatar: '.avatar-container', - menuButton: '.toggle-button-nav', - avatarImage: '.avatar-container .avatar' -}; - -let appHasStarted; -function spyOnListener(win) { - const addListener = win.EventTarget.prototype.addEventListener; - win.EventTarget.prototype.addEventListener = function (name) { - if (name === 'click') { - appHasStarted = true; - win.EventTarget.prototype.addEventListener = addListener; - } - return addListener.apply(this, arguments); - }; -} - -function waitForAppStart() { - return new Promise(resolve => { - const isReady = () => { - if (appHasStarted) { - return resolve(); - } - return setTimeout(isReady, 0); - }; - isReady(); - }); -} - -describe('Navbar when logged out', () => { - beforeEach(() => { - appHasStarted = false; - cy.visit('/', { - onBeforeLoad: spyOnListener - }).then(waitForAppStart); - cy.viewport(1300, 660); - }); - - it('Should have a "Sign in" button', () => { - cy.contains("[data-test-label='landing-small-cta']", 'Sign in'); - }); - - it( - 'Should have `Sign in` link on landing and learn pages' + - ' when not signed in', - () => { - cy.contains(selectors.smallCallToAction, 'Sign in'); - cy.get(selectors.menuButton).click(); - cy.get(selectors.navigationLinks).contains('Curriculum').click(); - cy.contains(selectors.smallCallToAction, 'Sign in'); - } - ); -}); - -describe('Navbar Logged in', () => { - beforeEach(() => { - cy.login(); - appHasStarted = false; - cy.visit('/', { - onBeforeLoad: spyOnListener - }).then(waitForAppStart); - cy.viewport(1300, 660); - }); - - it('Should render properly', () => { - cy.get('#universal-nav').should('be.visible'); - cy.get('#universal-nav').should('have.class', 'universal-nav'); - }); - - it( - 'Should take user to learn page when clicked on ' + 'the freeCodeCamp logo', - () => { - cy.get('.universal-nav-middle').within(() => { - cy.get('svg').click(); - }); - cy.url().should('include', '/learn'); - } - ); - - // have the curriculum and CTA on landing and /learn pages. - it( - 'Should have `Radio`, `Forum`, and `Curriculum` links on landing and learn pages' + - 'page when not signed in', - () => { - cy.get(selectors.menuButton).click(); - cy.get(selectors.navigationLinks).contains('Forum'); - cy.get(selectors.navigationLinks).contains('Curriculum').click(); - cy.url().should('include', '/learn'); - cy.get(selectors.navigationLinks).contains('Curriculum'); - cy.get(selectors.navigationLinks).contains('Forum'); - cy.get(selectors.navigationLinks).contains('Radio'); - } - ); - - it('Should have `Profile` link when user is signed in', () => { - cy.get(selectors.menuButton).click(); - cy.get(selectors.navigationLinks).contains('Profile').click(); - cy.url().should('include', '/developmentuser'); - }); - - it('Should have a profile image with class `default-border`', () => { - cy.get(selectors.avatarContainer).should('have.class', 'default-border'); - cy.get(selectors.defaultAvatar).should('exist'); - }); - - it('Should have a profile image with dimensions that are <= 31px', () => { - cy.get(selectors.avatarImage).invoke('width').should('lte', 31); - cy.get(selectors.avatarImage).invoke('height').should('lte', 31); - }); -}); diff --git a/cypress/e2e/default/learn/common-components/navbar.ts b/cypress/e2e/default/learn/common-components/navbar.ts new file mode 100644 index 00000000000..9072b7960b0 --- /dev/null +++ b/cypress/e2e/default/learn/common-components/navbar.ts @@ -0,0 +1,91 @@ +const navBarselectors = { + heading: "[data-test-label='landing-header']", + smallCallToAction: "[data-test-label='landing-small-cta']", + navigationLinks: '.nav-list', + avatarContainer: '.avatar-container', + defaultAvatar: '.avatar-container', + menuButton: '.toggle-button-nav', + avatarImage: '.avatar-container .avatar' +}; + +describe('Navbar when logged out', () => { + beforeEach(() => { + cy.visit('/'); + cy.viewport(1200, 660); + cy.contains('Learn to code — for free.').should('exist'); + }); + + it('Should have a "Sign in" button', () => { + cy.contains("[data-test-label='landing-small-cta']", 'Sign in'); + }); + + it( + 'Should have `Sign in` link on landing and learn pages' + + ' when not signed in', + () => { + cy.contains(navBarselectors.smallCallToAction, 'Sign in'); + cy.get(navBarselectors.menuButton).click(); + cy.get(navBarselectors.navigationLinks).contains('Curriculum').click(); + cy.contains(navBarselectors.smallCallToAction, 'Sign in'); + } + ); +}); + +describe('Navbar Logged in', () => { + beforeEach(() => { + cy.visit('/'); + cy.viewport(1200, 660); + cy.contains('Learn to code — for free.') + .should('exist') + .then(() => cy.login()); + }); + + it('Should render properly', () => { + cy.get('#universal-nav').should('be.visible'); + cy.get('#universal-nav').should('have.class', 'universal-nav'); + }); + + it( + 'Should take user to learn page when clicked on ' + 'the freeCodeCamp logo', + () => { + cy.get('.universal-nav-middle').within(() => { + cy.get('svg').click(); + }); + cy.url().should('include', '/learn'); + } + ); + + // have the curriculum and CTA on landing and /learn pages. + it( + 'Should have `Radio`, `Forum`, and `Curriculum` links on landing and learn pages' + + 'page when not signed in', + () => { + cy.get(navBarselectors.menuButton).click(); + cy.get(navBarselectors.navigationLinks).contains('Forum'); + cy.get(navBarselectors.navigationLinks).contains('Curriculum').click(); + cy.url().should('include', '/learn'); + cy.get(navBarselectors.navigationLinks).contains('Curriculum'); + cy.get(navBarselectors.navigationLinks).contains('Forum'); + cy.get(navBarselectors.navigationLinks).contains('Radio'); + } + ); + + it('Should have `Profile` link when user is signed in', () => { + cy.get(navBarselectors.menuButton).click(); + cy.get(navBarselectors.navigationLinks).contains('Profile').click(); + cy.url().should('include', '/developmentuser'); + }); + + it('Should have a profile image with class `default-border`', () => { + cy.get(navBarselectors.avatarContainer).should( + 'have.class', + 'default-border' + ); + cy.get(navBarselectors.defaultAvatar).should('exist'); + }); + + it('Should have a profile image with dimensions that are <= 31px', () => { + cy.get(navBarselectors.avatarImage).invoke('width').should('lte', 31); + cy.get(navBarselectors.avatarImage).invoke('height').should('lte', 31); + }); +}); From a1ebe6dcd66ec3b6ed7e8f8b16d8f6fcab0354ee Mon Sep 17 00:00:00 2001 From: Muhammed Mustafa Date: Fri, 10 Feb 2023 19:13:27 +0200 Subject: [PATCH 25/52] refactor(client): turn image validation component into subComponent (#49155) * refactor(client): clean extra FormGroup component in personal info * Revert "refactor(client): clean extra FormGroup component in personal info" This reverts commit cc29df30339e623a5c673f42aab467116702d1a4. * refactor show image component into JSX * Remove redundant text Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com> --------- Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com> --- client/src/components/settings/about.tsx | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/client/src/components/settings/about.tsx b/client/src/components/settings/about.tsx index 4b3f1aa8d16..ab8f1b96dfa 100644 --- a/client/src/components/settings/about.tsx +++ b/client/src/components/settings/about.tsx @@ -48,6 +48,18 @@ type AboutState = { isPictureUrlValid: boolean; }; +const ShowImageValidationWarning = ({ + alertContent +}: { + alertContent: string; +}) => { + return ( + + {alertContent} + + ); +}; + class AboutSettings extends Component { validationImage: HTMLImageElement; static displayName: string; @@ -79,7 +91,6 @@ class AboutSettings extends Component { picture === formValues.picture && about === formValues.about ) { - // eslint-disable-next-line react/no-did-update-set-state return this.setState({ originalValues: { name, @@ -170,21 +181,6 @@ class AboutSettings extends Component { })); }; - showImageValidationWarning = () => { - const { t } = this.props; - if (this.state.isPictureUrlValid === false) { - return ( - - - {t('validation.url-not-image')} - - - ); - } else { - return true; - } - }; - handleAboutChange = (e: React.FormEvent) => { const value = (e.target as HTMLInputElement).value.slice(0); return this.setState(state => ({ @@ -210,9 +206,9 @@ class AboutSettings extends Component { toggleKeyboardShortcuts } = this.props; return ( -
              + <> -
              + {t('settings.headings.personal-info')} @@ -246,7 +242,11 @@ class AboutSettings extends Component { type='url' value={picture} /> - {this.showImageValidationWarning()} + {!this.state.isPictureUrlValid && ( + + )} @@ -279,7 +279,7 @@ class AboutSettings extends Component { toggleKeyboardShortcuts={toggleKeyboardShortcuts} /> -
              + ); } } From 17bca17c1c7be86b1b2711443115a71ea5329f84 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra <1884376+raisedadead@users.noreply.github.com> Date: Fri, 10 Feb 2023 22:44:29 +0530 Subject: [PATCH 26/52] chore: rename e2e tests (#49332) --- .../e2e/default/{ShowCertification.js => show-certification.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cypress/e2e/default/{ShowCertification.js => show-certification.js} (100%) diff --git a/cypress/e2e/default/ShowCertification.js b/cypress/e2e/default/show-certification.js similarity index 100% rename from cypress/e2e/default/ShowCertification.js rename to cypress/e2e/default/show-certification.js From c12f7ad623841c38e68ed85a99f0c01afa0a4a94 Mon Sep 17 00:00:00 2001 From: camperbot Date: Sat, 11 Feb 2023 02:47:31 +0530 Subject: [PATCH 27/52] chore(i18n,client): processed translations (#49325) --- client/i18n/locales/arabic/translations.json | 6 +++--- .../chinese-traditional/translations.json | 6 +++--- client/i18n/locales/chinese/translations.json | 6 +++--- client/i18n/locales/espanol/translations.json | 6 +++--- client/i18n/locales/german/translations.json | 6 +++--- client/i18n/locales/italian/translations.json | 6 +++--- client/i18n/locales/japanese/translations.json | 6 +++--- client/i18n/locales/portuguese/intro.json | 14 +++++++------- client/i18n/locales/portuguese/translations.json | 6 +++--- client/i18n/locales/ukrainian/intro.json | 16 ++++++++-------- client/i18n/locales/ukrainian/translations.json | 6 +++--- 11 files changed, 42 insertions(+), 42 deletions(-) diff --git a/client/i18n/locales/arabic/translations.json b/client/i18n/locales/arabic/translations.json index c8e03f6e144..05161c547e8 100644 --- a/client/i18n/locales/arabic/translations.json +++ b/client/i18n/locales/arabic/translations.json @@ -15,8 +15,8 @@ "show-cert": "عرض الشهادة", "claim-cert": "المطالبة بالشهادة", "save-progress": "حفظ التقدم", - "accepted-honesty": "لقد قبلت سياسة الصدق الأكاديمي الخاصة بنا.", - "agree": "موافق", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "حفظ عنصر الحافظة هذا", "remove-portfolio": "إزالة عنصر الحافظة هذا", "add-portfolio": "إضافة عنصر حافظة جديد", @@ -517,7 +517,7 @@ "opens-new-window": "فتح في نافذة جديدة" }, "flash": { - "honest-first": "للمطالبة بشهادة ، يجب عليك أولاً قبول سياسة الصدق الأكاديمي الخاصة بنا", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "حدث شيء غريب حقاً، إذا حدث مرة أخرى، يرجى النظر في الإبلاغ عنها على https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "يبدو ان هناك خطأ ما. لقد تم إنشاء تقرير وتم إخطار فريق freeCodeCamp.org", "went-wrong": "حدث خطأ ما، الرجاء التحقق والمحاولة مرة أخرى", diff --git a/client/i18n/locales/chinese-traditional/translations.json b/client/i18n/locales/chinese-traditional/translations.json index cc2d192fe41..4489ee6239e 100644 --- a/client/i18n/locales/chinese-traditional/translations.json +++ b/client/i18n/locales/chinese-traditional/translations.json @@ -15,8 +15,8 @@ "show-cert": "顯示認證", "claim-cert": "申請認證", "save-progress": "保存進度", - "accepted-honesty": "你已接受我們的《學術誠信條例》", - "agree": "同意", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "保存這個作品集項目", "remove-portfolio": "移除這個作品集項目", "add-portfolio": "增加一個新的作品集項目", @@ -517,7 +517,7 @@ "opens-new-window": "Opens in new window" }, "flash": { - "honest-first": "申請認證之前,你必須先接受我們的《學術誠信條例》", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "出現了一些奇怪的情況。如果再出現這種情況,請考慮在 https://github.com/freeCodeCamp/freeCodeCamp/issues/new 提交 issue。", "not-right": "有些不對勁。已生成報告,通知 freeCodeCamp.org 團隊。", "went-wrong": "出了點問題,請檢查並重試。", diff --git a/client/i18n/locales/chinese/translations.json b/client/i18n/locales/chinese/translations.json index 363620e436c..8d7625d6a4c 100644 --- a/client/i18n/locales/chinese/translations.json +++ b/client/i18n/locales/chinese/translations.json @@ -15,8 +15,8 @@ "show-cert": "显示认证", "claim-cert": "申请认证", "save-progress": "保存进度", - "accepted-honesty": "你已接受我们的《学术诚信条例》", - "agree": "同意", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "保存这个作品集项目", "remove-portfolio": "移除这个作品集项目", "add-portfolio": "增加一个新的作品集项目", @@ -517,7 +517,7 @@ "opens-new-window": "Opens in new window" }, "flash": { - "honest-first": "申请认证之前,你必须先接受我们的《学术诚信条例》", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "出现了一些奇怪的情况。如果再出现这种情况,请考虑在 https://github.com/freeCodeCamp/freeCodeCamp/issues/new 提交 issue。", "not-right": "有些不对劲。已生成报告,通知 freeCodeCamp.org 团队。", "went-wrong": "出了点问题,请检查并重试。", diff --git a/client/i18n/locales/espanol/translations.json b/client/i18n/locales/espanol/translations.json index 73a90666766..6565ee368f9 100644 --- a/client/i18n/locales/espanol/translations.json +++ b/client/i18n/locales/espanol/translations.json @@ -15,8 +15,8 @@ "show-cert": "Mostrar certificación", "claim-cert": "Solicitar certificación", "save-progress": "Guardar progreso", - "accepted-honesty": "Has aceptado nuestra Política de Honestidad Académica.", - "agree": "Aceptar", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Guardar este elemento de portafolio", "remove-portfolio": "Eliminar este elemento de portafolio", "add-portfolio": "Agregar un nuevo elemento de portafolio", @@ -517,7 +517,7 @@ "opens-new-window": "Opens in new window" }, "flash": { - "honest-first": "Para reclamar una certificación, primero debes aceptar nuestra política de honestidad académica.", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "Sucedió algo realmente extraño. Si vuelve a ocurrir, considera hacer un reporte del problema en https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Algo no está bien. Se ha generado un informe y se ha notificado al equipo de freeCodeCamp.org", "went-wrong": "Algo salió mal, verifica e intenta nuevamente", diff --git a/client/i18n/locales/german/translations.json b/client/i18n/locales/german/translations.json index 2d78036c031..452779783dd 100644 --- a/client/i18n/locales/german/translations.json +++ b/client/i18n/locales/german/translations.json @@ -15,8 +15,8 @@ "show-cert": "Zertifikat anzeigen", "claim-cert": "Zertifizierung anfordern", "save-progress": "Fortschritt speichern", - "accepted-honesty": "Du hast unsere Akademische Ehrlichkeitsrichtlinie akzeptiert.", - "agree": "Zustimmen", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Dieses Portfolioelement speichern", "remove-portfolio": "Dieses Portfolioelement entfernen", "add-portfolio": "Neues Portfolioelement hinzufügen", @@ -517,7 +517,7 @@ "opens-new-window": "Opens in new window" }, "flash": { - "honest-first": "Um eine Zertifizierung zu erlangen, musst du zunächst unsere Richtlinie zur akademischen Ehrlichkeit akzeptieren", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "Etwas wirklich Seltsames ist passiert. Wenn es wieder passiert, erwäge bitte, einen Fehler auf https://github.com/freeCodeCamp/freeCodeCamp/issues/new zu melden.", "not-right": "Irgendetwas ist nicht in Ordnung. Es wurde ein Bericht erstellt und das freeCodeCamp.org Team wurde benachrichtigt", "went-wrong": "Etwas ist schief gelaufen, bitte überprüfe und versuche es erneut", diff --git a/client/i18n/locales/italian/translations.json b/client/i18n/locales/italian/translations.json index 18007266443..bb22c1ac79f 100644 --- a/client/i18n/locales/italian/translations.json +++ b/client/i18n/locales/italian/translations.json @@ -15,8 +15,8 @@ "show-cert": "Mostra la Certificazione", "claim-cert": "Richiedi la Certificazione", "save-progress": "Salva l'avanzamento", - "accepted-honesty": "Hai accettato la nostra Politica di Onestà Accademica.", - "agree": "Accetta", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Salva questo elemento del portfolio", "remove-portfolio": "Rimuovi questo elemento del portfolio", "add-portfolio": "Aggiungi un nuovo elemento nel portfolio", @@ -517,7 +517,7 @@ "opens-new-window": "Apri in una nuova finestra" }, "flash": { - "honest-first": "Per richiedere una certificazione, è necessario prima accettare la nostra politica di onestà accademica", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "È successo qualcosa di veramente strano, se succede di nuovo, ti preghiamo di considerare di sollevare un problema su https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Qualcosa non è del tutto giusto. Un rapporto è stato generato e il team freeCodeCamp.org è stato avvisato", "went-wrong": "Qualcosa è andato storto, controlla e riprova", diff --git a/client/i18n/locales/japanese/translations.json b/client/i18n/locales/japanese/translations.json index a0aa273780a..fa2cb2b43c2 100644 --- a/client/i18n/locales/japanese/translations.json +++ b/client/i18n/locales/japanese/translations.json @@ -15,8 +15,8 @@ "show-cert": "認定証を表示", "claim-cert": "認定証を取得", "save-progress": "進行状況を保存", - "accepted-honesty": "学問的誠実性ポリシーに同意しました。", - "agree": "同意する", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "このポートフォリオアイテムを保存", "remove-portfolio": "このポートフォリオアイテムを削除", "add-portfolio": "新規ポートフォリオアイテムを追加", @@ -517,7 +517,7 @@ "opens-new-window": "新しいウィンドウで開く" }, "flash": { - "honest-first": "認定証を請求するには、まず学問的誠実性ポリシーに同意する必要があります。", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "予期しない問題が発生しました。この問題が何度も発生するようであれば、https://github.com/freeCodeCamp/freeCodeCamp/issues/new への Issue 登録をご検討ください。", "not-right": "問題が発生しました。レポートが生成され、freeCodeCamp.org チームへ通知されました。", "went-wrong": "問題が発生しました。ご確認の上もう一度お試しください。", diff --git a/client/i18n/locales/portuguese/intro.json b/client/i18n/locales/portuguese/intro.json index ea6ec4d33e3..a0262686a7b 100644 --- a/client/i18n/locales/portuguese/intro.json +++ b/client/i18n/locales/portuguese/intro.json @@ -790,18 +790,18 @@ "the-odin-project": { "title": "The Odin Project", "intro": [ - "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", - "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", - "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + "The Odin Project é um daqueles recursos do tipo \"O que eu gostaria de ter visto quando estava aprendendo\". ", + "Nem todas as pessoas têm acesso à educação em ciência da computação ou aos fundos necessários para frequentar uma escola de programação intensiva. De qualquer modo, não necessariamente, essas duas sejam a solução final para todos que queiram aprender.", + "Este projeto destina-se a preencher a lacuna para aquelas pessoas que tentam buscar suas próprias soluções, mas que continuam procurando uma educação de alta qualidade." ], "blocks": { "top-learn-html-foundations": { - "title": "Learn HTML Foundations", - "intro": ["A description is to be determined"] + "title": "Aprenda o básico de HTML", + "intro": ["Uma descrição deve ser determinada"] }, "top-build-a-recipe-project": { - "title": "Learn HTML Foundations by Building a Recipe Page", - "intro": ["A description is to be determined"] + "title": "Aprenda o básico de HTML criando uma página de receitas", + "intro": ["Uma descrição deve ser determinada"] } } }, diff --git a/client/i18n/locales/portuguese/translations.json b/client/i18n/locales/portuguese/translations.json index 1471ae2b7ad..1d6f945a5e5 100644 --- a/client/i18n/locales/portuguese/translations.json +++ b/client/i18n/locales/portuguese/translations.json @@ -15,8 +15,8 @@ "show-cert": "Exibir certificado", "claim-cert": "Solicitar certificação", "save-progress": "Salvar progresso", - "accepted-honesty": "Você aceitou nossa política de honestidade acadêmica.", - "agree": "Aceitar", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Salvar esse item de portfólio", "remove-portfolio": "Remover este item de portfólio", "add-portfolio": "Adicionar um novo item de portfólio", @@ -517,7 +517,7 @@ "opens-new-window": "Abre em uma nova janela" }, "flash": { - "honest-first": "Para solicitar uma certificação, você precisa primeiro aceitar nossa política de honestidade acadêmica", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "Algo realmente estranho aconteceu. Se acontecer novamente, considere apresentar um problema pelo endereço https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Algo não está certo. Um relatório foi gerado e a equipe do freeCodeCamp.org foi notificada", "went-wrong": "Algo deu errado. Verifique e tente novamente", diff --git a/client/i18n/locales/ukrainian/intro.json b/client/i18n/locales/ukrainian/intro.json index d6f04eaa4e3..ec06abf9f61 100644 --- a/client/i18n/locales/ukrainian/intro.json +++ b/client/i18n/locales/ukrainian/intro.json @@ -788,20 +788,20 @@ } }, "the-odin-project": { - "title": "The Odin Project", + "title": "Проєкт «Odin»", "intro": [ - "The Odin Project is one of those \"What I wish I had when I was learning\" resources. ", - "Not everyone has access to a computer science education or the funds to attend an intensive coding school and neither of those is right for everyone anyway.", - "This project is designed to fill in the gap for people who are trying to hack it on their own but still want a high quality education." + "Проєкт «Odin» є одним з тих ресурсів, про які хотіли б дізнатися ще коли навчались. ", + "Не кожен має доступ до технологічної освіти або коштів, необхідних для відвідування інтенсивної школи. Однак це не остаточне рішення для тих, хто хоче вчитися.", + "Цей проєкт розроблений, щоб заповнити прогалину для людей, які намагаються вчитись самостійно, але все ж таки хочуть високоякісну освіту." ], "blocks": { "top-learn-html-foundations": { - "title": "Learn HTML Foundations", - "intro": ["A description is to be determined"] + "title": "Вивчіть основи HTML", + "intro": ["Опис буде надано пізніше"] }, "top-build-a-recipe-project": { - "title": "Learn HTML Foundations by Building a Recipe Page", - "intro": ["A description is to be determined"] + "title": "Вивчіть основи HTML, побудувавши сторінку з рецептами", + "intro": ["Опис буде надано пізніше"] } } }, diff --git a/client/i18n/locales/ukrainian/translations.json b/client/i18n/locales/ukrainian/translations.json index 4bb4a7e7e92..16aab52cdae 100644 --- a/client/i18n/locales/ukrainian/translations.json +++ b/client/i18n/locales/ukrainian/translations.json @@ -15,8 +15,8 @@ "show-cert": "Показати сертифікацію", "claim-cert": "Отримати сертифікацію", "save-progress": "Зберегти прогрес", - "accepted-honesty": "Ви прийняли нашу Політику академічної доброчесності.", - "agree": "Прийняти", + "accepted-honesty": "You have agreed to our Academic Honesty Policy.", + "agree-honesty": "I agree to freeCodeCamp's Academic Honesty Policy.", "save-portfolio": "Зберегти цей елемент портфоліо", "remove-portfolio": "Видалити цей елемент портфоліо", "add-portfolio": "Додати новий елемент портфоліо", @@ -517,7 +517,7 @@ "opens-new-window": "Відкривається у новому вікні" }, "flash": { - "honest-first": "Щоб отримати сертифікацію, ви повинні спочатку прийняти нашу політику академічної доброчесності", + "honest-first": "To claim a certification, you must first agree to our academic honesty policy", "really-weird": "Щось пішло не так. Якщо це повториться, будь ласка, повідомте про це за посиланням: https://github.com/freeCodeCamp/freeCodeCamp/issues/new", "not-right": "Щось пішло не так. Звіт було сформовано і команду freeCodeCamp.org вже сповістили.", "went-wrong": "Щось пішло не так. Будь ласка, перевірте та повторіть спробу.", From d7787eb0cc0c53a1ff2ed96cb22ebf931664c6ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:00:19 +0530 Subject: [PATCH 28/52] chore(deps): update github/codeql-action digest to 17573ee (#49338) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index eb6949ec6f2..7eb860f4417 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -32,8 +32,8 @@ jobs: - name: Checkout repository uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 - name: Setup CodeQL - uses: github/codeql-action/init@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2 + uses: github/codeql-action/init@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2 with: languages: ${{ matrix.language }} - name: Perform Analysis - uses: github/codeql-action/analyze@3ebbd71c74ef574dbc558c82f70e52732c8b44fe # v2 + uses: github/codeql-action/analyze@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2 From 1cc6c5546975d72793c1d4cced0f3fc49a9a16f8 Mon Sep 17 00:00:00 2001 From: a2937 Date: Sat, 11 Feb 2023 02:57:47 -0500 Subject: [PATCH 29/52] Chore : Migrate universal-navigation.js (#49337) --- config/i18n.ts | 2 +- ...-navigation.js => universal-navigation.ts} | 41 ++++++++++++------- 2 files changed, 28 insertions(+), 15 deletions(-) rename cypress/e2e/default/learn/header/{universal-navigation.js => universal-navigation.ts} (91%) diff --git a/config/i18n.ts b/config/i18n.ts index 9fe7a6311d2..88a0e24713b 100644 --- a/config/i18n.ts +++ b/config/i18n.ts @@ -68,7 +68,7 @@ export const i18nextCodes = { }; // These are for the language selector dropdown menu in the footer -export const LangNames = { +export const LangNames: { [key: string]: string } = { [Languages.English]: 'English', [Languages.Espanol]: 'Español', [Languages.Chinese]: '中文(简体字)', diff --git a/cypress/e2e/default/learn/header/universal-navigation.js b/cypress/e2e/default/learn/header/universal-navigation.ts similarity index 91% rename from cypress/e2e/default/learn/header/universal-navigation.js rename to cypress/e2e/default/learn/header/universal-navigation.ts index 23301aafae9..aa898243e95 100644 --- a/cypress/e2e/default/learn/header/universal-navigation.js +++ b/cypress/e2e/default/learn/header/universal-navigation.ts @@ -7,7 +7,7 @@ import envData from '../../../../../config/env.json'; const { clientLocale } = envData; -const selectors = { +const selectors: { [key: string]: string } = { 'navigation-list': '.nav-list', 'toggle-button': '.toggle-button-nav', 'language-menu': '.nav-lang-menu', @@ -21,7 +21,7 @@ const selectors = { 'cancel-signout': "[data-test-label='cancel-signout']" }; -const links = { +const links: { [key: string]: string } = { 'sign-in': '/signin', donate: '/donate', curriculum: '/learn', @@ -223,31 +223,44 @@ const testAllLanguages = () => { const availableLangNames = availableLangs.client .filter(lang => !hiddenLangs.includes(lang)) .map(lang => LangNames[lang]); - availableLangNames.forEach(langName => - cy.get(selectors['language-menu']).contains(langName) - ); + for (let i = 0; i < availableLangNames.length; i++) { + const langName = availableLangNames[i]; + cy.get(selectors['language-menu']).contains(langName); + } }; -const testLink = (item, selector = 'navigation-list', checkParent) => { +const testLink = ( + item: string, + selector = 'navigation-list', + checkParent = false +) => { if (checkParent) { return cy .get(selectors[selector]) .should('contain.text', item) .should('have.attr', 'href') - .and('contain', links[item.replaceAll(' ', '-').toLowerCase()]); + .and('contain', links[item.replace(/\s+/g, '-').toLowerCase()]); + //.and('contain', links[item.replaceAll(' ', '-').toLowerCase()]); } - return cy - .get(selectors[selector]) - .contains(item) - .should('have.attr', 'href') - .and('contain', links[item.replaceAll(' ', '-').toLowerCase()]); + return ( + cy + .get(selectors[selector]) + .contains(item) + .should('have.attr', 'href') + //.and('contain', links[item.replaceAll(' ', '-').toLowerCase()]); + + .and('contain', links[item.replace(/\s+/g, '-').toLowerCase()]) + ); }; -const navigateLanguagesWithKey = direction => { +const navigateLanguagesWithKey = (direction: string) => { const directions = ['downArrow', 'upArrow']; if (!directions.includes(direction)) { throw new Error( - 'Invalid direction: ' + direction + '\nMust be one of: ' + directions + 'Invalid direction: ' + + direction + + '\nMust be one of: ' + + directions.join(',') ); } const availableLangNames = availableLangs.client From e9b2cc630ba05e2961c17f8e4a163ded727c2603 Mon Sep 17 00:00:00 2001 From: Vansh Baghel <103327712+Vansh-Baghel@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:30:51 +0530 Subject: [PATCH 30/52] chore(curriculum) : Added backticks and class reference to bar word (#49322) Added backticks and class reference to bar word --- .../visualize-data-with-a-bar-chart.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/curriculum/challenges/english/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md b/curriculum/challenges/english/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md index 4e648ec9b72..a86369073dd 100644 --- a/curriculum/challenges/english/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md +++ b/curriculum/challenges/english/04-data-visualization/data-visualization-projects/visualize-data-with-a-bar-chart.md @@ -24,17 +24,17 @@ You can use HTML, JavaScript, CSS, and the D3 svg-based visualization library. T **User Story #5:** My chart should have a `rect` element for each data point with a corresponding `class="bar"` displaying the data. -**User Story #6:** Each bar should have the properties `data-date` and `data-gdp` containing `date` and `GDP` values. +**User Story #6:** Each `.bar` should have the properties `data-date` and `data-gdp` containing `date` and `GDP` values. -**User Story #7:** The bar elements' `data-date` properties should match the order of the provided data. +**User Story #7:** The `.bar` elements' `data-date` properties should match the order of the provided data. -**User Story #8:** The bar elements' `data-gdp` properties should match the order of the provided data. +**User Story #8:** The `.bar` elements' `data-gdp` properties should match the order of the provided data. -**User Story #9:** Each bar element's height should accurately represent the data's corresponding `GDP`. +**User Story #9:** Each `.bar` element's height should accurately represent the data's corresponding `GDP`. -**User Story #10:** The `data-date` attribute and its corresponding bar element should align with the corresponding value on the x-axis. +**User Story #10:** The `data-date` attribute and its corresponding `.bar` element should align with the corresponding value on the x-axis. -**User Story #11:** The `data-gdp` attribute and its corresponding bar element should align with the corresponding value on the y-axis. +**User Story #11:** The `data-gdp` attribute and its corresponding `.bar` element should align with the corresponding value on the y-axis. **User Story #12:** I can mouse over an area and see a tooltip with a corresponding `id="tooltip"` which displays more information about the area. From 3065d7cab7fa623e795aad445bdbcec398be6f5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Feb 2023 12:47:01 +0200 Subject: [PATCH 31/52] chore(deps): update dependency tailwindcss to v3.2.6 (#49342) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 49 +++++++++++++++++++++----------- tools/ui-components/package.json | 2 +- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index a675d5ace56..3979c332441 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41718,8 +41718,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "license": "MIT", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -49314,8 +49315,9 @@ } }, "node_modules/tailwindcss": { - "version": "3.2.4", - "license": "MIT", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.6.tgz", + "integrity": "sha512-BfgQWZrtqowOQMC2bwaSNe7xcIjdDEgixWGYOd6AL0CbKHJlvhfdbINeAW76l1sO+1ov/MJ93ODJ9yluRituIw==", "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -49331,12 +49333,12 @@ "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.18", + "postcss": "^8.0.9", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", "postcss-nested": "6.0.0", - "postcss-selector-parser": "^6.0.10", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", "resolve": "^1.22.1" @@ -49354,15 +49356,18 @@ }, "node_modules/tailwindcss/node_modules/arg": { "version": "5.0.2", - "license": "MIT" + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/tailwindcss/node_modules/color-name": { "version": "1.1.4", - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/tailwindcss/node_modules/glob-parent": { "version": "6.0.2", - "license": "ISC", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dependencies": { "is-glob": "^4.0.3" }, @@ -54343,7 +54348,7 @@ "rollup": "2.79.1", "rollup-plugin-postcss": "4.0.2", "rollup-plugin-terser": "7.0.2", - "tailwindcss": "3.2.4" + "tailwindcss": "3.2.6" }, "engines": { "node": ">=16", @@ -56650,7 +56655,7 @@ "rollup": "2.79.1", "rollup-plugin-postcss": "4.0.2", "rollup-plugin-terser": "7.0.2", - "tailwindcss": "3.2.4", + "tailwindcss": "3.2.6", "typescript": "4.9.5" } }, @@ -82754,7 +82759,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.10", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -87628,7 +87635,9 @@ } }, "tailwindcss": { - "version": "3.2.4", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.6.tgz", + "integrity": "sha512-BfgQWZrtqowOQMC2bwaSNe7xcIjdDEgixWGYOd6AL0CbKHJlvhfdbINeAW76l1sO+1ov/MJ93ODJ9yluRituIw==", "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -87644,25 +87653,31 @@ "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.18", + "postcss": "^8.0.9", "postcss-import": "^14.1.0", "postcss-js": "^4.0.0", "postcss-load-config": "^3.1.4", "postcss-nested": "6.0.0", - "postcss-selector-parser": "^6.0.10", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", "resolve": "^1.22.1" }, "dependencies": { "arg": { - "version": "5.0.2" + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "color-name": { - "version": "1.1.4" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "requires": { "is-glob": "^4.0.3" } diff --git a/tools/ui-components/package.json b/tools/ui-components/package.json index cb821fb6da7..cb6931a27c7 100644 --- a/tools/ui-components/package.json +++ b/tools/ui-components/package.json @@ -53,7 +53,7 @@ "rollup": "2.79.1", "rollup-plugin-postcss": "4.0.2", "rollup-plugin-terser": "7.0.2", - "tailwindcss": "3.2.4" + "tailwindcss": "3.2.6" }, "scripts": { "storybook": "start-storybook -p 6006", From 8aa35385a04579900293077ce49f6ec86272db2d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Feb 2023 10:47:49 +0000 Subject: [PATCH 32/52] chore(deps): update dependency prettier to v2.8.4 (#49341) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 16 ++++++++-------- tools/challenge-helper-scripts/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3979c332441..5bf40a16fab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41801,9 +41801,9 @@ } }, "node_modules/prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "bin": { "prettier": "bin-prettier.js" }, @@ -54048,7 +54048,7 @@ "cross-env": "7.0.3", "gray-matter": "4.0.3", "inquirer": "8.2.5", - "prettier": "2.8.3", + "prettier": "2.8.4", "ts-node": "10.9.1", "typescript": "4.9.5" }, @@ -56500,7 +56500,7 @@ "cross-env": "7.0.3", "gray-matter": "4.0.3", "inquirer": "8.2.5", - "prettier": "2.8.3", + "prettier": "2.8.4", "ts-node": "10.9.1", "typescript": "4.9.5" } @@ -82809,9 +82809,9 @@ "version": "2.0.0" }, "prettier": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", - "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==" + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==" }, "pretty-bytes": { "version": "5.6.0" diff --git a/tools/challenge-helper-scripts/package.json b/tools/challenge-helper-scripts/package.json index f55579a5add..91613a9b754 100644 --- a/tools/challenge-helper-scripts/package.json +++ b/tools/challenge-helper-scripts/package.json @@ -28,7 +28,7 @@ "cross-env": "7.0.3", "gray-matter": "4.0.3", "inquirer": "8.2.5", - "prettier": "2.8.3", + "prettier": "2.8.4", "ts-node": "10.9.1", "typescript": "4.9.5" } From 65b9f87b0bf048785c3f415abbf68ad6fb32c4ca Mon Sep 17 00:00:00 2001 From: Shiva kumar <39256145+ShivaKodes@users.noreply.github.com> Date: Sat, 11 Feb 2023 17:04:56 +0530 Subject: [PATCH 33/52] fix(curriculum): remove attributes from Building a registration Form (#49334) fix #49301-removed name attributes from seed code on step 41 --- .../60fad1cafcde010995e15306.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/curriculum/challenges/english/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60fad1cafcde010995e15306.md b/curriculum/challenges/english/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60fad1cafcde010995e15306.md index 0f68b139a27..ec598b5f119 100644 --- a/curriculum/challenges/english/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60fad1cafcde010995e15306.md +++ b/curriculum/challenges/english/14-responsive-web-design-22/learn-html-forms-by-building-a-registration-form/60fad1cafcde010995e15306.md @@ -103,23 +103,23 @@ You should not give any of the `fieldset` elements a `name` attribute. --fcc-editable-region--
              - - - - + + + +