├── .DS_Store ├── project-one ├── movie_recs.py └── movie_recs2.py ├── project-three ├── .env.example ├── .gitignore ├── README.md ├── _assets │ ├── api-chat-route.ts │ ├── api-vectorSearch-route.ts │ ├── fcc_docs │ │ ├── FAQ.md │ │ ├── README.md │ │ ├── authors-analytics-manual.md │ │ ├── codebase-best-practices.md │ │ ├── courses-vscode-extension.md │ │ ├── curriculum-file-structure.md │ │ ├── curriculum-help.md │ │ ├── devops.md │ │ ├── how-to-add-cypress-tests.md │ │ ├── how-to-add-playwright-tests.md │ │ ├── how-to-catch-outgoing-emails-locally.md │ │ ├── how-to-contribute-to-the-codebase.md │ │ ├── how-to-enable-new-languages.md │ │ ├── how-to-help-with-video-challenges.md │ │ ├── how-to-open-a-pull-request.md │ │ ├── how-to-proofread-files.md │ │ ├── how-to-setup-freecodecamp-locally.md │ │ ├── how-to-setup-freecodecamp-mobile-app-locally.md │ │ ├── how-to-setup-wsl.md │ │ ├── how-to-translate-files.md │ │ ├── how-to-use-docker-on-windows-home.md │ │ ├── how-to-work-on-coding-challenges.md │ │ ├── how-to-work-on-localized-client-webapp.md │ │ ├── how-to-work-on-practice-projects.md │ │ ├── how-to-work-on-the-component-library.md │ │ ├── how-to-work-on-the-docs-theme.md │ │ ├── how-to-work-on-tutorials-that-use-coderoad.md │ │ ├── index.md │ │ ├── language-lead-handbook.md │ │ ├── moderator-handbook.md │ │ ├── moderator-onboarding-guide.md │ │ ├── reply-templates.md │ │ ├── security-hall-of-fame.md │ │ ├── security.md │ │ ├── troubleshooting-development-issues.md │ │ └── user-token-workflow.md │ ├── index.json │ └── questions.txt ├── app │ ├── api │ │ ├── chat │ │ │ └── route.ts │ │ └── vectorSearch │ │ │ └── route.ts │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx │ ├── lib │ │ └── mongodb.ts │ └── page.tsx ├── createEmbeddings.mjs ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── tailwind.config.js └── tsconfig.json └── project-two ├── .gitignore ├── .vscode └── extensions.json ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public └── favicon.ico ├── src ├── App.vue ├── assets │ ├── base.css │ ├── logo.svg │ └── main.css ├── components │ └── icons │ │ ├── IconCommunity.vue │ │ ├── IconDocumentation.vue │ │ ├── IconEcosystem.vue │ │ ├── IconSupport.vue │ │ └── IconTooling.vue └── main.js └── vite.config.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/vector-search-tutorial/f9d70ca770716d1ef76ad6eec444de82f00649ab/.DS_Store -------------------------------------------------------------------------------- /project-one/movie_recs.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | import requests 3 | 4 | client = pymongo.MongoClient("mongodb+srv://beau:bngeFBqJJoEWqRNd@cluster0.svcxhgj.mongodb.net/?retryWrites=true&w=majority") 5 | db = client.sample_mflix 6 | collection = db.movies 7 | 8 | hf_token = "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" 9 | embedding_url = "https://api-inference.huggingface.co/pipeline/feature-extraction/sentence-transformers/all-MiniLM-L6-v2" 10 | 11 | def generate_embedding(text: str) -> list[float]: 12 | 13 | response = requests.post( 14 | embedding_url, 15 | headers={"Authorization": f"Bearer {hf_token}"}, 16 | json={"inputs": text}) 17 | 18 | if response.status_code != 200: 19 | raise ValueError(f"Request failed with status code {response.status_code}: {response.text}") 20 | 21 | return response.json() 22 | 23 | # for doc in collection.find({'plot':{"$exists": True}}).limit(50): 24 | # doc['plot_embedding_hf'] = generate_embedding(doc['plot']) 25 | # collection.replace_one({'_id': doc['_id']}, doc) 26 | 27 | query = "imaginary characters from outer space at war" 28 | 29 | results = collection.aggregate([ 30 | {"$vectorSearch": { 31 | "queryVector": generate_embedding(query), 32 | "path": "plot_embedding_hf", 33 | "numCandidates": 100, 34 | "limit": 4, 35 | "index": "PlotSemanticSearch", 36 | }} 37 | ]); 38 | 39 | for document in results: 40 | print(f'Movie Name: {document["title"]},\nMovie Plot: {document["plot"]}\n') -------------------------------------------------------------------------------- /project-one/movie_recs2.py: -------------------------------------------------------------------------------- 1 | import pymongo 2 | import openai 3 | 4 | # Set your OpenAI API key 5 | openai.api_key = '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' 6 | 7 | client = pymongo.MongoClient("mongodb+srv://beau:n9KkbZz60mfMPhWM@cluster0.svcxhgj.mongodb.net/?retryWrites=true&w=majority") 8 | db = client.sample_mflix 9 | collection = db.embedded_movies 10 | 11 | def generate_embedding(text: str) -> list[float]: 12 | 13 | response = openai.Embedding.create( 14 | model="text-embedding-ada-002", 15 | input=text 16 | ) 17 | return response['data'][0]['embedding'] 18 | 19 | query = "imaginary characters from outer space at war" 20 | 21 | results = collection.aggregate([ 22 | {"$vectorSearch": { 23 | "queryVector": generate_embedding(query), 24 | "path": "plot_embedding", 25 | "numCandidates": 100, 26 | "limit": 4, 27 | "index": "PlotSemanticSearch", 28 | }} 29 | ]); 30 | 31 | for document in results: 32 | print(f'Movie Name: {document["title"]},\nMovie Plot: {document["plot"]}\n') -------------------------------------------------------------------------------- /project-three/.env.example: -------------------------------------------------------------------------------- 1 | NODE_ENV=development 2 | OPENAI_API_KEY=YOUR-KEY-HERE 3 | MONGODB_ATLAS_URI=YOUR-CONNECTION-STRING-HERE -------------------------------------------------------------------------------- /project-three/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /project-three/README.md: -------------------------------------------------------------------------------- 1 | # Workshop Demo Application - Let AI Be Your Docs 2 | 3 | This is a demo application for the [Let AI Be Your Docs](https://github.com/mongodb-developer/vector-search-workshop) workshop. 4 | -------------------------------------------------------------------------------- /project-three/_assets/api-chat-route.ts: -------------------------------------------------------------------------------- 1 | import { StreamingTextResponse, LangChainStream, Message } from "ai"; 2 | import { ChatOpenAI } from "langchain/chat_models/openai"; 3 | import { AIMessage, HumanMessage } from "langchain/schema"; 4 | 5 | export const runtime = "edge"; 6 | 7 | export async function POST(req: Request) { 8 | const { messages } = await req.json(); 9 | const currentMessageContent = messages[messages.length - 1].content; 10 | 11 | const vectorSearch = await fetch("http://localhost:3000/api/vectorSearch", { 12 | method: "POST", 13 | headers: { 14 | "Content-Type": "application/json", 15 | }, 16 | body: currentMessageContent, 17 | }).then((res) => res.json()); 18 | 19 | const TEMPLATE = `You are a very enthusiastic freeCodeCamp.org representative who loves to help people! Given the following sections from the freeCodeCamp.org contributor documentation, answer the question using only that information, outputted in markdown format. If you are unsure and the answer is not explicitly written in the documentation, say "Sorry, I don't know how to help with that." 20 | 21 | Context sections: 22 | ${JSON.stringify(vectorSearch)} 23 | 24 | Question: """ 25 | ${currentMessageContent} 26 | """ 27 | `; 28 | 29 | messages[messages.length -1].content = TEMPLATE; 30 | 31 | const { stream, handlers } = LangChainStream(); 32 | 33 | const llm = new ChatOpenAI({ 34 | modelName: "gpt-3.5-turbo", 35 | streaming: true, 36 | }); 37 | 38 | llm 39 | .call( 40 | (messages as Message[]).map((m) => 41 | m.role == "user" 42 | ? new HumanMessage(m.content) 43 | : new AIMessage(m.content) 44 | ), 45 | {}, 46 | [handlers] 47 | ) 48 | .catch(console.error); 49 | 50 | return new StreamingTextResponse(stream); 51 | } 52 | -------------------------------------------------------------------------------- /project-three/_assets/api-vectorSearch-route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIEmbeddings } from "langchain/embeddings/openai"; 2 | import { MongoDBAtlasVectorSearch } from "langchain/vectorstores/mongodb_atlas"; 3 | import mongoClientPromise from '@/app/lib/mongodb'; 4 | 5 | export async function POST(req: Request) { 6 | const client = await mongoClientPromise; 7 | const dbName = "docs"; 8 | const collectionName = "embeddings"; 9 | const collection = client.db(dbName).collection(collectionName); 10 | 11 | const question = await req.text(); 12 | 13 | const vectorStore = new MongoDBAtlasVectorSearch( 14 | new OpenAIEmbeddings({ 15 | modelName: 'text-embedding-ada-002', 16 | stripNewLines: true, 17 | }), { 18 | collection, 19 | indexName: "default", 20 | textKey: "text", 21 | embeddingKey: "embedding", 22 | }); 23 | 24 | const retriever = vectorStore.asRetriever({ 25 | searchType: "mmr", 26 | searchKwargs: { 27 | fetchK: 20, 28 | lambda: 0.1, 29 | }, 30 | }); 31 | 32 | const retrieverOutput = await retriever.getRelevantDocuments(question); 33 | 34 | return Response.json(retrieverOutput); 35 | } 36 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/FAQ.md: -------------------------------------------------------------------------------- 1 | # Frequently Asked Questions 2 | 3 | Answers to common questions. 4 | 5 | ## I am new to GitHub and Open Source. Where should I start? 6 | 7 | Read our ["How to Contribute to Open Source Guide"](https://github.com/freeCodeCamp/how-to-contribute-to-open-source). It's a comprehensive reference for first-timer-friendly projects. And it includes a lot of open-source contribution tips. 8 | 9 | ## What do I need to know to contribute to the codebase? 10 | 11 | freeCodeCamp runs on a modern JavaScript stack. If you're interested in contributing to our codebase, you will need some familiarity with JavaScript and some of the technologies we use like Node.js, MongoDB, OAuth 2.0, React, Gatsby, and Webpack. 12 | 13 | ## Can I translate freeCodeCamp's resources? 14 | 15 | Yes - You can contribute to any of the 30+ languages we have enabled on our translation platform. 16 | 17 | We have user-contributed translations live in some languages. We intend to localize freeCodeCamp into several major world languages. You can read all about this in our [announcement here](https://www.freecodecamp.org/news/help-translate-freecodecamp-language/). 18 | 19 | If you are interested in contributing to translations please make sure you [read this guide](how-to-translate-files.md) first. 20 | 21 | ## Can I contribute articles to freeCodeCamp News or videos to freeCodeCamp's YouTube channel? 22 | 23 | Yes - you can contribute to our publication blog and YouTube channel. 24 | 25 | If you're interested in writing articles for freeCodeCamp News, please visit this [publication guide](https://www.freecodecamp.org/news/how-to-write-for-freecodecamp/). In addition, please read our [style guide](https://www.freecodecamp.org/news/developer-news-style-guide/) as this will help you write stronger and more effective articles. 26 | 27 | To help us make educational videos for our YouTube channel, you can follow the [YouTube channel guide here](https://www.freecodecamp.org/news/how-to-contribute-to-the-freecodecamp-community-youtube-channel-b86bce4c865/). 28 | 29 | ## How can I report a new bug? 30 | 31 | If you think you've found a bug, first read the ["How to Report a Bug"](https://www.freecodecamp.org/news/how-to-report-a-bug-to-freecodecamp/) article and follow its instructions. 32 | 33 | If you're confident it's a new bug, go ahead and create a new GitHub issue. Be sure to include as much information as possible so that we can reproduce the bug. We have a pre-defined issue template to help you through this. 34 | 35 | Please note that these GitHub issues are for codebase-related issues and discussions – not for getting help with learning to code. Whenever in doubt, you should [seek assistance on the forum](https://forum.freecodecamp.org) before creating a GitHub issue. 36 | 37 | ## How can I report a security issue? 38 | 39 | Please don't create GitHub issues for security issues. Instead, please [follow our security policy](https://contribute.freecodecamp.org/#/security). 40 | 41 | ## I am a student. Can I work on a feature for academic credits? 42 | 43 | Yes. Please note we are unable to commit to any timelines or paperwork that may be a requirement by your college or university. We receive many pull-requests and code contributions from volunteer developers, and we respect their time and efforts. Out of respect for all of our other contributors, we will not give any PR special priority just because it happens to be school-related. 44 | 45 | We request you to plan ahead and work on code contributions with this in mind. 46 | 47 | ## What do these different labels that are tagged on issues mean? 48 | 49 | The code maintainers [triage](https://en.wikipedia.org/wiki/Software_bug#Bug_management) issues and pull requests based on their priority, severity, and other factors. You can [find a complete glossary of their meanings here](https://github.com/freecodecamp/freecodecamp/labels). 50 | 51 | ## Where do I start if I want to work on an issue? 52 | 53 | You should go through [**`help wanted`**](https://github.com/freeCodeCamp/freeCodeCamp/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [**`first timers only`**](https://github.com/freeCodeCamp/freeCodeCamp/issues?q=is%3Aopen+is%3Aissue+label%3A%22first+timers+only%22) issues for a quick overview of what is available for you to work on. 54 | 55 | > [!TIP] **`help wanted`** issues are up for grabs, and you do not need to seek permission before working on them. However, issues with the **`first timers only`** label are special issues that are designed for people who have not contributed to the freeCodeCamp codebase before. 56 | 57 | ## I found a typo. Should I report an issue before I can make a pull request? 58 | 59 | For typos and other wording changes, you can directly open pull requests without creating an issue first. Please be sure to mention details in the pull request description to help us understand and review your contribution – even if it's just a minor change. 60 | 61 | Please do create an issue if you want to discuss bigger aspects of the codebase or curriculum. 62 | 63 | ## How can I get an issue assigned to me? 64 | 65 | We typically do not assign issues to anyone other than long-time contributors. Instead, we follow the below policy to be fair to everyone: 66 | 67 | 1. We are most likely to merge the first pull request that addresses the issue. 68 | 2. In the case of multiple contributors opening a pull request for the same issue at around the same time, we will give priority to the pull request that best addresses the issue. Some of the things we consider: 69 | - Did you include tests? 70 | - Did you catch all use cases? 71 | - Did you ensure all tests pass, and confirm everything works locally? 72 | 3. Finally, we give priority to pull requests which follow our recommended guidelines. 73 | - Did you follow the pull request checklist? 74 | - Did you give your pull request a meaningful title? 75 | 76 | ## I am interested in being a moderator at freeCodeCamp. Where should I start? 77 | 78 | Our community moderators are our heroes. Their voluntary contributions make freeCodeCamp a safe and welcoming community. 79 | 80 | First and foremost, we would need you to be an active participant in the community, and live by our [code of conduct](https://www.freecodecamp.org/news/code-of-conduct/) (not just enforce it). 81 | 82 | Here are some recommended paths for some of our platforms: 83 | 84 | - To be a **Discord/Chat** moderator, have an active presence in our chat and have positive engagements with others, while also learning and practicing how to deal with potential conflicts that may arise. 85 | - To be a **Forum** moderator, similar to a chat moderator, have an active presence and engage with other forum posters, supporting others in their learning journey, and even giving feedback when asked. Take a look at [The Subforum Leader Handbook](https://forum.freecodecamp.org/t/the-subforum-leader-handbook/326326) for more information. 86 | - To be a **GitHub** moderator, help process GitHub issues that are brought up to see if they are valid and (ideally) try to propose solutions for these issues to be picked up by others (or yourself). 87 | 88 | Altogether, be respectful to others. We are humans from all around the world. With that in mind, please also consider using encouraging or supportive language and be mindful of cross-cultural communication. 89 | 90 | If you practice the above **consistently for a while** and our fellow moderator members recommend you, a staff member will reach out and onboard you to the moderators' team. Open source work is voluntary work and our time is limited. We acknowledge that this is probably true in your case as well. So we emphasize being **consistent** rather than engaging in the community 24/7. 91 | 92 | Take a look at our [Moderator Handbook](moderator-handbook.md) for a more exhaustive list of other responsibilities and expectations we have of our moderators. 93 | 94 | ## I am stuck on something that is not included in this documentation. 95 | 96 | **Feel free to ask for help in:** 97 | 98 | - The `Contributors` category of [our community forum](https://forum.freecodecamp.org/c/contributors). 99 | - The `#Contributors` channel on [our chat server](https://discord.gg/PRyKn3Vbay). 100 | 101 | We are excited to help you contribute to any of the topics that you would like to work on. If you ask us questions on the related issue threads, we will be glad to clarify. Be sure to search for your question before posting a new one. 102 | 103 | Thanks in advance for being polite and patient. Remember – this community is run mainly by volunteers. 104 | 105 | ## Additional Assistance 106 | 107 | If you have queries about the stack, architecture of the codebase, translations, or anything else, feel free to reach out to our staff team [on the forum](https://forum.freecodecamp.org/g/team). 108 | 109 | **You can email our developer staff at: `dev[at]freecodecamp.org`** 110 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/README.md: -------------------------------------------------------------------------------- 1 | ## Our contributing docs are available here: . 2 | 3 | Looking to edit these docs? Read [this document](how-to-work-on-the-docs-theme.md) first. 4 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/authors-analytics-manual.md: -------------------------------------------------------------------------------- 1 | # Authors Analytics Manual 2 | 3 | If you are an author with access to the publication's Google Analytics Property (News), you can use this guide to view your article engagement and search for articles by publication language. 4 | 5 | ## Search by Language 6 | 7 | To search for engagement reports in a specific language: 8 | 9 | ![Image - Show steps to search by language on googla analytics](https://contribute.freecodecamp.org/images/google-analytics/search-by-language.png) 10 | 11 | 1. From the top dropdown menu, select `News`. 12 | 1. From the sidebar, click on `Reports`. 13 | 1. From the secondary sidebar, select `Engagement`. 14 | 1. Click on `Pages and Screens`. 15 | 1. In the search bar, type the subpath for the desired language. 16 | 1. From the dropdown under the search bar, choose `Page path and screen class`. 17 | 18 | ## Filter Reports by Author 19 | 20 | After arriving at the `Pages and Screens` reports mentioned above, use the following steps to filter the results by specific authors. 21 | 22 | ![Image - Show steps to search by language on googla analytics](https://contribute.freecodecamp.org/images/google-analytics/filter-by-author.png) 23 | 24 | 1. Click on the `Add filter` button. 25 | 1. From the side navigation include `Author`. 26 | 1. From the `Dimensions values` dropdown, choose an author's name. 27 | 1. Click on the `Apply` button to apply changes. 28 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/codebase-best-practices.md: -------------------------------------------------------------------------------- 1 | # Codebase Best Practices 2 | 3 | ## Styling a component 4 | 5 | We recommend styling components using our [design style guide](https://design-style-guide.freecodecamp.org/). 6 | 7 | The colors are defined in [`variable.css`](/client/src/components/layouts/variables.css), and the fonts are in [`fonts.css`](/client/src/components/layouts/fonts.css). 8 | 9 | We are strongly opinionated about adding new variables/tokens to the colors. After careful research, the colors have been chosen to respect the freeCodeCamp brand identity, developer experience, and accessibility. 10 | 11 | The `!important` keyword may be used to override values in some cases (e.g. accessibility concerns). You should add a comment describing the issue, so it doesn't get removed in future refactoring. 12 | 13 | ### RTL support 14 | 15 | We are striving to support right-to-left (RTL) layout in the codebase for languages that are read in this direction. For this you need be mindful of how to style components. Here are some quick rules of thumb to follow: 16 | 17 | - Don't use `float` properties 18 | - Use Flexbox and Grid layouts instead, as they have RTL support already built-in, and those will be easier to maintain and review. 19 | - Don't define the direction while using `margin` and `padding`: it may seem harmless to use `padding-right` and `margin-left`, but these directions aren't mirrored when the layout changes to RTL, and adding counter values for them in the RTL file makes maintaining the codebase harder. 20 | - Use logical properties for them: You can add the same spacing by using `padding-inline-end` and `margin-inline-start`, and you won't need to worry about RTL layout, as they follow where the line starts and ends, and you won't need to add any extra values in the RTL files, so people won't need to remember to change the same values in two files. 21 | - Don't use `!important` in `font-family`: RTL layout uses different fonts compared to the LTR layout, when you add `!important` in the `font-family` property it affects the RTL layout too. 22 | 23 | ## General JavaScript 24 | 25 | In most cases, our [linter](how-to-setup-freecodecamp-locally.md#follow-these-steps-to-get-your-development-environment-ready) will warn of any formatting which goes against this codebase's preferred practice. 26 | 27 | It is encouraged to use functional components over class-based components. 28 | 29 | ## Specific TypeScript 30 | 31 | ### Migrating a JavaScript File to TypeScript 32 | 33 | #### Retaining Git File History 34 | 35 | Sometimes changing the file from `.js` to `.ts` (or `.tsx`) causes the original file to be deleted, and a new one created, and other times the filename just changes - in terms of Git. Ideally, we want the file history to be preserved. 36 | 37 | The best bet at achieving this is to: 38 | 39 | 1. Rename the file 40 | 2. Commit with the flag `--no-verify` to prevent Husky from complaining about the lint errors 41 | 3. Refactor to TypeScript for migration, in a separate commit 42 | 43 | > [!NOTE] 44 | > Editors like VSCode are still likely to show you the file has been deleted and a new one created. If you use the CLI to `git add .`, then VSCode will show the file as renamed in stage 45 | 46 | ### Naming Conventions 47 | 48 | #### Interfaces and Types 49 | 50 | For the most part, it is encouraged to use interface declarations over type declarations. 51 | 52 | React Component Props - suffix with `Props` 53 | 54 | ```typescript 55 | interface MyComponentProps {} 56 | // type MyComponentProps = {}; 57 | const MyComponent = (props: MyComponentProps) => {}; 58 | ``` 59 | 60 | React Stateful Components - suffix with `State` 61 | 62 | ```typescript 63 | interface MyComponentState {} 64 | // type MyComponentState = {}; 65 | class MyComponent extends Component {} 66 | ``` 67 | 68 | Default - object name in PascalCase 69 | 70 | ```typescript 71 | interface MyObject {} 72 | // type MyObject = {}; 73 | const myObject: MyObject = {}; 74 | ``` 75 | 76 | 77 | 78 | 79 | 80 | ## Redux 81 | 82 | ### Action Definitions 83 | 84 | ```typescript 85 | enum AppActionTypes = { 86 | actionFunction = 'actionFunction' 87 | } 88 | 89 | export const actionFunction = ( 90 | arg: Arg 91 | ): ReducerPayload => ({ 92 | type: AppActionTypes.actionFunction, 93 | payload: arg 94 | }); 95 | ``` 96 | 97 | ### How to Reduce 98 | 99 | ```typescript 100 | // Base reducer action without payload 101 | type ReducerBase = { type: T }; 102 | // Logic for handling optional payloads 103 | type ReducerPayload = 104 | T extends AppActionTypes.actionFunction 105 | ? ReducerBase & { 106 | payload: AppState['property']; 107 | } 108 | : ReducerBase; 109 | 110 | // Switch reducer exported to Redux combineReducers 111 | export const reducer = ( 112 | state: AppState = initialState, 113 | action: ReducerPayload 114 | ): AppState => { 115 | switch (action.type) { 116 | case AppActionTypes.actionFunction: 117 | return { ...state, property: action.payload }; 118 | default: 119 | return state; 120 | } 121 | }; 122 | ``` 123 | 124 | ### How to Dispatch 125 | 126 | Within a component, import the actions and selectors needed. 127 | 128 | ```tsx 129 | // Add type definition 130 | interface MyComponentProps { 131 | actionFunction: typeof actionFunction; 132 | } 133 | // Connect to Redux store 134 | const mapDispatchToProps = { 135 | actionFunction 136 | }; 137 | // Example React Component connected to store 138 | const MyComponent = ({ actionFunction }: MyComponentProps): JSX.Element => { 139 | const handleClick = () => { 140 | // Dispatch function 141 | actionFunction(); 142 | }; 143 | return ; 144 | }; 145 | 146 | export default connect(null, mapDispatchToProps)(MyComponent); 147 | ``` 148 | 149 | 150 | 151 | 152 | ## API 153 | 154 | ### Testing 155 | 156 | The `api/` tests are split into two parts: 157 | 158 | 1. Unit tests 159 | 2. Integration tests 160 | 161 | #### Unit Tests 162 | 163 | Unit tests isolate a single function or component. The tests do not need mocking, but will require fixtures. 164 | 165 | The unit tests are located in a new file adjacent to the file exporting that is being tested: 166 | 167 | ```text 168 | api/ 169 | ├── src/ 170 | │ ├── utils.ts 171 | │ ├── utils.test.ts 172 | ``` 173 | 174 | #### Integration Tests 175 | 176 | Integration tests test the API as a whole. The tests will require mocking, and should not require fixtures beyond the database seeding data, and a method to authenticate. 177 | 178 | Typically, each integration test file will be directly related to a route. The integration tests are located in the `api/tests/` directory: 179 | 180 | ```text 181 | api/ 182 | ├── tests/ 183 | │ ├── settings.ts 184 | ``` 185 | 186 | ## Further Literature 187 | 188 | - [TypeScript Docs](https://www.typescriptlang.org/docs/) 189 | - [TypeScript with React CheatSheet](https://github.com/typescript-cheatsheets/react#readme) 190 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/courses-vscode-extension.md: -------------------------------------------------------------------------------- 1 | # Courses VSCode Extension 2 | 3 | This details the maintenance guidelines for the [freeCodeCamp/courses-vscode-extension](https://github.com/freeCodeCamp/courses-vscode-extension) repository which contains the source code for the [freeCodeCamp - Courses](https://marketplace.visualstudio.com/items?itemName=freeCodeCamp.freecodecamp-courses) extension. 4 | 5 | ## Publishing the Extension 6 | 7 | A GitHub Action automagically publishes the extension to the Visual Studio Marketplace, on the release of a new GitHub Release. 8 | 9 | 1. Package a new version of the extension: 10 | 11 | ```bash 12 | npm run pack -- 13 | ``` 14 | 15 | Where `` is one of: `major`, `minor`, `patch`. 16 | 17 | 2. Push the new version to `main`: 18 | 19 | ```bash 20 | git commit -am "(): " 21 | git push 22 | ``` 23 | 24 | Optionally, you can push directly to `upstream/main`, but opening a new PR is recommended for a sanity check. 25 | 26 | 3. Create a new GitHub Release using the GitHub UI: 27 | 28 | - Correctly increment the version number, when creating a new tag. 29 | - Upload the `.vsix` file with the release. 30 | - Publish the release, and confirm the action succeeded. 31 | 32 | > [!NOTE] 33 | > Creating a release requires write access to the `freeCodeCamp/courses-vscode-extension` repository. 34 | 35 | ## Manually Publishing the Extension 36 | 37 | A manual upload to the Visual Studio Marketplace can be achieved, by following these steps: 38 | 39 | 1. Visit https://marketplace.visualstudio.com/ and sign in 40 | 2. Navigate to the [freeCodeCamp Publisher page](https://marketplace.visualstudio.com/manage/publishers/freecodecamp) 41 | 3. Select the relevant extension, and select `Update` 42 | 4. Upload the file from your local files 43 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/curriculum-file-structure.md: -------------------------------------------------------------------------------- 1 | # Curriculum File Structure 2 | 3 | Our core instructional content is located within the conveniently named `curriculum` directory. This page will break down how these files are organized. 4 | 5 | ## Terminology 6 | 7 | There are a few terms we use when discussing our curriculum content. 8 | 9 | - `certification` : When referring to a certification in this instance, it is talking about the actual certificate that users claim. Which is separate from the name of the superBlock. 10 | - `superBlock` : A superblock is the top level collection of challenges. Each superblock corresponds to a certification in the curriculum (e.g. Responsive Web Design). 11 | - `block` : A block is a section within a superblock. A block corresponds to a group of challenges in a given certification (e.g. Basic HTML and HTML5) 12 | - `challenge` : A challenge is a single lesson within the curriculum (e.g. Say Hello to HTML Elements) 13 | 14 | ## File Tree 15 | 16 | Using those terms, here is how the file structure would be defined: 17 | 18 | 19 | ```md 20 | 21 | curriculum/ 22 | ├─ _meta/ 23 | │ ├─ {block}/ 24 | │ │ ├─ meta.json 25 | ├─ {language}/ 26 | │ ├─ {superBlock}/ 27 | │ │ ├─ {block}/ 28 | │ │ │ ├─ {challenge}.md 29 | ``` 30 | 31 | ## The `_meta` Directory 32 | 33 | The `_meta` directory is a special directory which contains `.json` files. These files correspond to each block in the curriculum, and are used to determine which superBlock a block belongs to, and the order of the challenges within that block. 34 | 35 | ## Renaming Files 36 | 37 | There may be times when you need to rename a certificate, superblock, block, or challenge. This section will outline the steps needed to avoid build errors when doing so. 38 | 39 | > [!ATTENTION] 40 | > Renaming files within the curriculum structure will often change the path (or URL) of the content on the main webpage. Doing so should be done with care, as redirects have to be set up for each change that is made. 41 | 42 | ### Renaming a Certification 43 | 44 | When renaming a certification, you will likely want to rename the associated superblock along with it. Do the following to rename only the certificate: 45 | 46 | 1. Rename the `curriculum/challenges/_meta/{superBlock}-certificate` folder to the new name. 47 | 1. In the `meta.json` file of that folder, rename the values in `name`, `dashedName`, and `challengeOrder` to the new cert name. 48 | 1. In `curriculum/challenges/english/12-certificate`, rename the `{superBlock}-certificate` folder, and the YAML file within it, to the new name. 49 | 1. In the YAML file, change the `title` to the new name. 50 | 1. Rename the file and folder from step 3 for the rest of the curriculum languages. 51 | 1. Update `client/src/redux/index.ts` to use the correct `title`. 52 | 1. Optionally, update the `certSlug` for the superblock in the same file. **Note** that renaming a `certSlug` will change the URL for certifications and should only be done with careful consideration. 53 | 1. Update the `title` in `client/src/resources/cert-and-project-map.ts` to the new value. **Note** that changing the `title` here **will break** the superBlock page for the associated certification. It relies on the superBlock title to match the certification title. You will likely want to rename the superBlock at the same time. 54 | 1. If you renamed the `certSlug` in step 7, change it here for the cert and all the nested `projects` values. 55 | 1. In `shared/config/certification-settings.js`, update the value of `certTypeTitleMap` to the new name. 56 | 1. If you renamed the `certSlug` in step 7, update the key of `certSlugTypeMap` in the same file. 57 | 1. Update the certificate name in the `legacyCerts` array of the `client/src/client-only-routes/show-project-links.tsx` if needed. 58 | 1. Update the main `README.md` file to the new name. 59 | 60 | ### Renaming a Superblock 61 | 62 | > [!NOTE] 63 | > When you rename a superBlock, the new folder name is used as the path and should be considered the "correct" name. All other values should be updated to reflect that change. 64 | 65 | Also, you will likely want to rename the certificate and the `{superBlock}-projects` block when you rename a superBlock since they all share a name. To rename only a superBlock you need to: 66 | 67 | 1. Rename the superBlock folder in the `curriculum/challenges/english` directory. 68 | 1. Rename the superBlock folder in _all_ other `curriculum/challenges/{language}` directories. 69 | 1. For each block within that superBlock, update the `superBlock` value in the `meta.json` file to its dashedName. You don't need to rename any folders here. Do that when renaming a block. 70 | 1. Rename the superblock folder in `client/src/pages/learn`. 71 | 1. Update the `index.md` file in the above folder, changing the `title` and `superBlock` values to the new name. 72 | 1. For each block folder within the above, update the `index.md` to use the correct `superBlock` value. 73 | 1. In the `client/src/resources/cert-and-project-map.ts` file, update the path for the cert at the top of the file, and the `title` value for that superBlock. **Note** that changing the `title` here **will break** the ability to view the actual certification for this superBlock. It relies on the superBlock title to match the certification title. You will likely want to rename the certification at the same time. 74 | 1. Update the `superBlockCertTypeMap` key in `shared/config/certification-settings.js` to the new superBlock name. 75 | 1. Update the path value in `client/src/assets/icons/index.tsx`. 76 | 1. For each language in `client/i18n/locales`, update the `intro.json` file to use the new superBlock `dashedName`. In the English file, also update the `title`. 77 | 1. Check the `shared/config/i18n/all-langs.js` file to see if the superBlock is enabled in i18n builds. Update all the values where it is used. 78 | 1. Update the main `README.md` file to the new name. 79 | 80 | ### Renaming a Block 81 | 82 | When renaming a curriculum block, you need to: 83 | 84 | 1. Change the name of the block folder in the `curriculum/challenges/english/{superBlock}` directory. 85 | 1. Change the name of the same block folder in _all_ of the other language directories to match. These must all be the same as the English structure or the build will error out. 86 | 1. Change the name of the block folder in the `_meta` directory. 87 | 1. Update the `name` and `dashedName` property for that block's `meta.json` file. 88 | 1. Update the block folder in `client/src/pages/learn/{superBlock}`. 89 | 1. In the `index.md` file of the above folder, update the `block` value in the frontmatter. 90 | 1. In the `client/i18n/locales/{language}/intro.json` files, update the block name to the new name for all the languages. In the English `intro.json` file, update the `title` as well. 91 | 1. Update the main `README.md` file to the new name. 92 | 93 | ### Renaming a Challenge 94 | 95 | When renaming a single challenge file, you need to: 96 | 97 | 1. Change the name of the challenge file in the `curriculum/challenges/english` directory. 98 | 1. Change the name of the `title` and `dashedName` within that file. 99 | 1. Change the name of the file, and the `dashedName` in those files for _all_ of the other language directories to match. 100 | 1. Update the name of the challenge in the relevant `meta.json` file. The challenge names here are not used in the build, but provide a user-friendly way to identify the challenge order. 101 | 1. If the challenge is a certificate project, update the YAML file in `curriculum/english/12-certificates/` to the new name. 102 | 1. If the challenge is a certificate project, update the `title` and `link` in `client/src/resources/cert-and-project-map.ts` 103 | 1. If the challenge is a certificate project, update the main `README.md` file to the new name. 104 | 105 | ## The `dashedName` Property 106 | 107 | The `dashedName` property is used to generate the URL path for the superblock, block, or challenge. These should generally match what the `/utils/slugs.js` helper would output for the file name. 108 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/curriculum-help.md: -------------------------------------------------------------------------------- 1 | # Using the Curriculum Helpers 2 | 3 | The test runner has access to a few helpers that can assist with testing campers' code. 4 | 5 | ## CSS Helper 6 | 7 | To instantiate the helper within a test block, use this: 8 | 9 | ```js 10 | const helper = new __helpers.CSSHelp(document); 11 | ``` 12 | 13 | In that example, the `document` variable refers to the document object of the test runner's iframe. 14 | 15 | ### Methods 16 | 17 | There are a few methods available for parsing and testing CSS. 18 | 19 | #### `.getStyle()` 20 | 21 | The `.getStyle()` method takes a CSS selector and returns a CSS style declaration object. 22 | 23 | For example, if the camper has written the following CSS: 24 | 25 | ```css 26 | body { 27 | background: linear-gradient(45deg, rgb(118, 201, 255), rgb(247, 255, 222)); 28 | margin: 0; 29 | padding: 0; 30 | width: 100%; 31 | height: 100vh; 32 | overflow: hidden; 33 | } 34 | ``` 35 | 36 | You would get an object that looks like this: 37 | 38 | ```js 39 | { 40 | 0: "background-image", 41 | 1: "background-position-x", 42 | 2: "background-position-y", 43 | 3: "background-size", 44 | 4: "background-repeat-x", 45 | 5: "background-repeat-y", 46 | 6: "background-attachment", 47 | 7: "background-origin", 48 | 8: "background-clip", 49 | 9: "background-color", 50 | 10: "margin-top", 51 | 11: "margin-right", 52 | 12: "margin-bottom", 53 | 13: "margin-left", 54 | 14: "padding-top", 55 | 15: "padding-right", 56 | 16: "padding-bottom", 57 | 17: "padding-left", 58 | 18: "width", 59 | 19: "height", 60 | 20: "overflow-x", 61 | 21: "overflow-y", 62 | "accentColor": "", 63 | "additiveSymbols": "", 64 | "alignContent": "", 65 | "alignItems": "", 66 | ... 67 | } 68 | ``` 69 | 70 | This method allows you to test that specific properties have been set: 71 | 72 | ```js 73 | assert.strictEqual(helper.getStyle('body')?.width, '100%'); 74 | ``` 75 | 76 | The helper attaches a `.getPropVal()` method to the style declaration object that allows you to get the value of a specific property: 77 | 78 | ```js 79 | assert.strictEqual(helper.getStyle('body').getPropVal('width'), '100%'); 80 | ``` 81 | 82 | #### `.getCSSRules()` 83 | 84 | The `.getCSSRules()` takes an at-rule type from the union `media | fontface | import | keyframes`, and returns an array of CSS rules matching that at-rule. 85 | 86 | For example, if the camper has written the following code: 87 | 88 | ```css 89 | @media (max-width: 100px) { 90 | body { 91 | background-color: green; 92 | } 93 | } 94 | ``` 95 | 96 | Then the returned value of `helper.getCSSRules('media')` would be this array: 97 | 98 | ```js 99 | [ 100 | { 101 | conditionText: "(max-width: 100px)", 102 | cssRules: [ 103 | selectorText: 'body', 104 | style: CSSStyleDeclaration, 105 | styleMap: StylePropertyMap, 106 | cssRules: CSSRuleList, 107 | type: 1, 108 | ... 109 | ], 110 | cssText: "@media (max-width: 100px) {\n body { background-color: green; }\n}", 111 | ... 112 | } 113 | ] 114 | ``` 115 | 116 | You can then test that the camper has written the correct media query: 117 | 118 | ```js 119 | const hasCorrectHeight = helper.getCSSRules('media').some(x => x.style.height === '3px');; 120 | assert.isTrue(hasCorrectHeight); 121 | ``` 122 | 123 | #### `.getRuleListsWithinMedia()` 124 | 125 | The `.getRuleListsWithinMedia()` method takes a media text (e.g. `("max-width: 200")`) and returns the CSS rules within that media query. 126 | 127 | The return result is the equivalent of that media rule's `cssRules` property from the return value of `.getCSSRules("media")`. 128 | 129 | ### Less Frequent Methods 130 | 131 | These methods are not as commonly used, but are available if needed. 132 | 133 | #### `.getStyleDeclarations()` 134 | 135 | The `.getStyleDeclarations()` method takes a CSS selector and returns an array of CSS style declaration objects (from the `.getStyle()` method). 136 | 137 | #### `.isPropertyUsed()` 138 | 139 | The `.isPropertyUsed()` method takes a CSS **property** and checks if it has been set/used anywhere in the camper's CSS. 140 | 141 | #### `.getStyleRule()` 142 | 143 | The `.getStyleRule()` method takes a CSS selector and returns the CSS Style Declaration, much like `.getStyle()`. However, the declaration returned from this method includes an additional `.isDeclaredAfter()` method which takes a selector and returns whether this rule is declared after the selector passed in. 144 | 145 | #### `.getStyleSheet()` 146 | 147 | The `.getStyleSheet()` method returns the camper's CSS, parsed into a CSS Style Sheet object. 148 | 149 | ## Strip Content 150 | 151 | There are a few methods on the `__helpers` object to remove content from the camper's code. 152 | 153 | These do NOT need to be instantiated they are static methods. 154 | 155 | ### Removing Comments 156 | 157 | Using `__helpers.removeCssComments()`, `__helpers.removeHTMLComments()`, or `__helpers.removeJSComments()` allows you to pass the camper's code (through the `code` variable) to remove comments matching the language's comment syntax. 158 | 159 | ### Removing Whitespace 160 | 161 | Using `__helpers.removeWhitespace()` allows you to pass the camper's code (through the `code` variable) to remove all whitespace. 162 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-add-cypress-tests.md: -------------------------------------------------------------------------------- 1 | # How to add Cypress tests 2 | 3 | When making changes to JavaScript, CSS, or HTML which could change the functionality or layout of a page, it's important to add corresponding [Cypress](https://docs.cypress.io) integration tests. 4 | 5 | To learn how to write Cypress tests, or 'specs', please see Cypress' official [documentation](https://docs.cypress.io/guides/getting-started/writing-your-first-test.html). 6 | 7 | ## Where to Add a Test 8 | 9 | - Cypress tests are in the `./cypress` directory. 10 | 11 | - Cypress tests for a curriculum module are in the corresponding curriculum directory, i.e. `cypress/integration/learn/responsive-web-design/basic-css/index.js`. 12 | 13 | ## How to Run Tests 14 | 15 | > [!NOTE] 16 | > If using Gitpod, please see [Cypress-Gitpod Setup](how-to-add-cypress-tests.md#cypress-gitpod-setup) 17 | 18 | ### 1. Ensure that MongoDB and Client Applications are Running 19 | 20 | - [Start MongoDB and seed the database](how-to-setup-freecodecamp-locally.md#step-3-start-mongodb-and-seed-the-database) 21 | 22 | - [Start the freeCodeCamp client application and API server](how-to-setup-freecodecamp-locally.md#step-4-start-the-freecodecamp-client-application-and-api-server) 23 | 24 | ### 2. Run the Cypress Tests 25 | 26 | To run tests against production builds, replace `dev` with `prd` below. 27 | 28 | - To run all tests in the `./cypress` directory: 29 | 30 | ```bash 31 | pnpm run cypress:dev:run 32 | ``` 33 | 34 | - To run a single test: 35 | 36 | ```bash 37 | pnpm run cypress run --spec=cypress/ 38 | ``` 39 | 40 | For example: 41 | 42 | ```bash 43 | pnpm run cypress run --spec=cypress/e2e/default/landing.ts 44 | ``` 45 | 46 | - To create a development build, start the development server, and run all existing cypress end-to-end tests: 47 | 48 | ```bash 49 | pnpm run e2e:dev:run 50 | ``` 51 | 52 | ## Cypress-Gitpod Setup 53 | 54 | ### 1. Ensure Development Environment is Running 55 | 56 | If starting the Gitpod environment did not automatically develop the environment: 57 | 58 | - Follow the [MongoDB installation guide](https://www.mongodb.com/basics/get-started). 59 | - Create a config file. 60 | 61 | ```bash 62 | pnpm run create:shared 63 | ``` 64 | 65 | - Seed the database 66 | 67 | ```bash 68 | pnpm run seed 69 | ``` 70 | 71 | - Develop the server and client 72 | 73 | ```bash 74 | pnpm run develop 75 | ``` 76 | 77 | ### 2. Install Cypress Build Tools 78 | 79 | ```bash 80 | pnpm run cypress:install-build-tools 81 | ``` 82 | 83 | - When prompted in the terminal, select your keyboard layout by language/area 84 | 85 | Now, [Cypress can be run](how-to-add-cypress-tests.md#_2-run-the-cypress-tests) 86 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-add-playwright-tests.md: -------------------------------------------------------------------------------- 1 | # How to add Playwright tests 2 | 3 | ## Installation 4 | 5 | To install Playwright run: 6 | 7 | ```bash 8 | pnpm run playwright:install-build-tools 9 | ``` 10 | 11 | Alternatively you can follow official documentation referenced below: 12 | 13 | To install and configure Playwright on your machine check out this [documentation](https://playwright.dev/docs/intro#installing-playwright). 14 | 15 | To learn how to write Playwright tests, or 'specs', please see Playwright's official [documentation](https://playwright.dev/docs/writing-tests). 16 | 17 | ## Where to Add a Test 18 | 19 | - Playwright tests are in the `./e2e` directory. 20 | 21 | - Playwright test files are always with a `.spec.ts` extension. 22 | 23 | ## Best Practices for writing E2E tests 24 | 25 | This section will explain in detail about best practices for writing and documenting E2E tests based on Playwright documentation and our community code-style. 26 | 27 | ### - Imports 28 | 29 | Always start with necessary imports at the beginning of the file. 30 | 31 | For example: 32 | 33 | ```ts 34 | import { test, expect, type Page } from '@playwright/test'; 35 | ``` 36 | 37 | ### - Identifying a DOM element 38 | 39 | Playwright comes with [multiple built-in locators](https://playwright.dev/docs/locators#quick-guide), but we recommend prioritizing the following locators: 40 | - `getByRole` for querying semantic elements, whose role is important and allows assistive technology to perceive the page correctly. 41 | - `getByText` for querying non-semantic elements such as `div`, `span`, or `p`. 42 | 43 | For example: 44 | ```ts 45 | await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible(); 46 | await expect(page.getByText('Hello World')).toBeVisible(); 47 | ``` 48 | 49 | In cases where the elements cannot be queried using the above-mentioned locators, you can use the `data-playwright-test-label` attribute as the last resort. This attribute is used to identify elements in the DOM for testing with playwright only. It is not used for styling or any other purpose. 50 | 51 | For example: 52 | 53 | ```html 54 |
55 | ... 56 |
57 | ``` 58 | 59 | In the test file, you can use the `getByTestId` method to identify the element. 60 | 61 | For example: 62 | 63 | ```ts 64 | await expect(page.getByTestId('landing-page-figure')).toBeVisible(); 65 | ``` 66 | 67 | ### - Constants 68 | 69 | Define any constant elements, data sets, or configurations used throughout your tests for easy reference. 70 | 71 | For example: 72 | 73 | ```ts 74 | const landingPageElements = { ... }; 75 | const superBlocks = [ ... ]; 76 | ``` 77 | 78 | ### - Shared Context 79 | 80 | If tests depend on a shared context (like a loaded web page), use beforeAll and afterAll hooks to set up and tear down that context. 81 | 82 | For example: 83 | 84 | ```ts 85 | let page: Page; 86 | 87 | beforeAll(async ({ browser }) => { 88 | page = await browser.newPage(); 89 | }); 90 | 91 | afterAll(async () => { 92 | await page.close(); 93 | }); 94 | ``` 95 | 96 | ### - Descriptive test names 97 | 98 | Each test block should have a clear and concise name describing exactly what it's testing. 99 | 100 | For example: 101 | 102 | ```ts 103 | test('The component landing-top renders correctly', async ({ page }) => { 104 | // ... 105 | }); 106 | ``` 107 | 108 | ### - Human readable assertions 109 | 110 | Each assertion should be as human readable as possible. This makes it easier to understand what the test is doing and what it's expecting. 111 | 112 | For example: 113 | 114 | ```ts 115 | await expect(landingHeading1).toHaveText('Learn to code — for free.'); 116 | ``` 117 | 118 | ### - Keep it DRY 119 | 120 | Make sure that the tests are not repeating the same code over and over again. If you find yourself repeating the same code, consider refactoring it as a loop or a function. 121 | 122 | For example: 123 | 124 | ```ts 125 | for (const logo of await logos.all()) { 126 | await expect(logo).toBeVisible(); 127 | } 128 | ``` 129 | 130 | ### - Tests for mobile screens 131 | 132 | Use the `isMobile` argument to run tests that include logic that varies for mobile screens. 133 | 134 | For example: 135 | 136 | ```ts 137 | test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({ 138 | isMobile 139 | }) => { 140 | const landingPageImage = page.getByTestId('landing-page-figure'); 141 | 142 | if (isMobile) { 143 | await expect(landingPageImage).toBeHidden(); 144 | } else { 145 | await expect(landingPageImage).toBeVisible(); 146 | } 147 | }); 148 | ``` 149 | 150 | ### - Group related tests 151 | 152 | Group related tests together using describe blocks. This makes it easier to understand what the tests are doing and what they're testing. 153 | 154 | For example: 155 | 156 | ```ts 157 | describe('The campers landing page', () => { 158 | test('The campers landing page figure is visible on desktop and hidden on mobile view', async ({ 159 | isMobile 160 | }) => { 161 | // ... 162 | }); 163 | 164 | test('The campers landing page figure has the correct image', async () => { 165 | // ... 166 | }); 167 | }); 168 | ``` 169 | 170 | ## How to Run Tests 171 | 172 | ### 1. Ensure that MongoDB and Client Applications are Running 173 | 174 | - [Start MongoDB and seed the database](how-to-setup-freecodecamp-locally.md#step-3-start-mongodb-and-seed-the-database) 175 | 176 | - [Start the freeCodeCamp client application and API server](how-to-setup-freecodecamp-locally.md#step-4-start-the-freecodecamp-client-application-and-api-server) 177 | 178 | ### 2. Run the Playwright Tests 179 | 180 | To run tests with Playwright check the following below 181 | 182 | - Make sure you navigate to the e2e repo first 183 | 184 | ```bash 185 | cd e2e 186 | ``` 187 | 188 | - To run tests in UI helper mode: 189 | 190 | ```bash 191 | npx playwright test --ui 192 | ``` 193 | 194 | - To run a single test: 195 | 196 | ```bash 197 | npx playwright test 198 | ``` 199 | 200 | For example: 201 | 202 | ```bash 203 | npx playwright test landing-page.spec.ts 204 | ``` 205 | 206 | - Run a set of test files in respective folders: 207 | 208 | ```bash 209 | npx playwright test 210 | ``` 211 | 212 | For example: 213 | 214 | ```bash 215 | npx playwright test tests/todo-page/ tests/landing-page/ 216 | ``` 217 | 218 | - Run the test with the title: 219 | 220 | ```bash 221 | npx playwright test -g 222 | ``` 223 | 224 | For example: 225 | 226 | ```bash 227 | npx playwright test -g "add a todo item" 228 | ``` 229 | 230 | ### 3. Debugging Tests 231 | 232 | Since Playwright runs in Node.js, you can debug it with your debugger of choice e.g. using console.log or inside your IDE 233 | 234 | - Debugging all tests: 235 | 236 | ```bash 237 | npx playwright test --debug 238 | ``` 239 | 240 | - Debugging one test file: 241 | 242 | ```bash 243 | npx playwright test example.spec.ts --debug 244 | ``` 245 | 246 | ### 4. Generate Test Reports 247 | 248 | The HTML Reporter shows you a full report of your tests allowing you to filter the report by browsers, passed tests, failed tests, skipped tests and flaky tests. 249 | 250 | ```bash 251 | npx playwright show-report 252 | ``` 253 | 254 | ### 5. Troubleshooting 255 | 256 | Playwright is generally a solid bullet-proof tool. The contributor has already configured the tests to run on all OS machines, including major distributions of Windows, MacOS and Linux. 257 | 258 | - (MacOs and Linux) If running Playwright results in an error due to kernel dependencies, run the following command: 259 | 260 | ```bash 261 | pnpm run playwright:install-build-tools-linux 262 | ``` 263 | 264 | - A common error seen in playwright is as follows: 265 | 266 | ```bash 267 | Error: page.goto: Could not connect: Connection refused 268 | =========================== logs =========================== 269 | navigating to "https://127.0.0.1:8000/", waiting until "load" 270 | ============================================================ 271 | ``` 272 | 273 | You can fix the above error with the following steps: 274 | 275 | 1. **Check the URL:** Ensure that the URL you're trying to navigate to is correct and properly formatted. Make sure there are no typos in the URL. 276 | 277 | 2. **Server Status:** Check whether the server at the URL is running and accessible. You might encounter this error if the server is not running or is not accessible. 278 | 279 | 3. **Port Availability:** Verify that the port mentioned in the URL (8000 in this case) is the correct port and is available for use. Make sure no other process is already using that port. 280 | 281 | 4. **Firewall or Security Software:** Sometimes, firewall or security software can block connections to specific ports. Check your firewall settings to ensure that the port is allowed. 282 | 283 | 5. **Network Connectivity:** Ensure that your system has a working network connection and can access external resources. 284 | 285 | - Another common error seen in playwright is as follows: 286 | 287 | ```bash 288 | Protocol error (Network.getResponseBody): Request content was evicted from inspector cache 289 | ``` 290 | 291 | 1. The network request was made using a method that does not include a response body, such as HEAD or CONNECT. 292 | 2. The network request was made over a secure (HTTPS) connection, and the response body is not available for security reasons. 293 | 3. The network request was made by a third-party resource (such as an advertisement or a tracking pixel) that is not controlled by the script. 294 | 4. The network request was made by a script that has been paused or stopped before the response was received. 295 | 296 | **For more insights on issues visit the official documentation.** 297 | 298 | ## Playwright-Gitpod Setup 299 | 300 | ### 1. Ensure Development Environment is Running 301 | 302 | If starting the Gitpod environment did not automatically develop the environment: 303 | 304 | - Follow the [MongoDB installation guide](https://www.mongodb.com/basics/get-started). 305 | 306 | - Create the .env 307 | 308 | ```bash 309 | cp sample.env .env 310 | ``` 311 | 312 | - Create a config file. 313 | 314 | ```bash 315 | pnpm run create:shared 316 | ``` 317 | 318 | - Seed the database 319 | 320 | ```bash 321 | pnpm run seed 322 | ``` 323 | 324 | - Develop the server and client 325 | 326 | ```bash 327 | pnpm run develop 328 | ``` 329 | 330 | ### 2. Install Playwright Build Tools 331 | 332 | To install necessary dependencies for running Playwright run the following command: 333 | 334 | ```bash 335 | pnpm run playwright:install-build-tools 336 | ``` 337 | 338 | ### 3. Run the Playwright Tests on Gitpod 339 | 340 | To run all Playwright tests, run the following command: 341 | 342 | ```bash 343 | npx playwright test 344 | ``` 345 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-catch-outgoing-emails-locally.md: -------------------------------------------------------------------------------- 1 | > **Note:** This is an **optional** step and is required only when working with email workflows 2 | 3 | - [Introduction](#introduction) 4 | - [Installing MailHog](#installing-mailhog) 5 | - [Using MailHog](#using-mailhog) 6 | - [Useful Links](#useful-links) 7 | 8 | ## Introduction 9 | 10 | Some email workflows, like updating a user's email, require the back-end API server to send outgoing emails. MailHog is an alternative to using an email service provider to send actual email messages. It is a developer tool for email testing that will catch the email messages sent by your freeCodeCamp instance. 11 | 12 | ## Installing MailHog 13 | 14 | MailHog can be installed on macOS, Windows, and Linux or used via Docker. 15 | 16 | <details><summary>Installing MailHog with Docker</summary> 17 | 18 | If you have Docker installed then you can use 19 | 20 | ```bash 21 | docker run -d --name mailhog --network host --rm mailhog/mailhog 22 | ``` 23 | 24 | to start MailHog in the background and 25 | 26 | ```bash 27 | docker stop mailhog 28 | ``` 29 | 30 | to stop it. 31 | 32 | When the installation completes, you can start [using MailHog](#using-mailhog). 33 | 34 | </details> 35 | 36 | <details><summary>Installing MailHog on macOS</summary> 37 | 38 | Install MailHog on macOS with [Homebrew](https://brew.sh/): 39 | 40 | ```bash 41 | brew install mailhog 42 | brew services start mailhog 43 | ``` 44 | 45 | The above commands will start a MailHog service in the background. 46 | 47 | When the installation completes, you can start [using MailHog](#using-mailhog). 48 | 49 | </details> 50 | 51 | <details><summary>Installing MailHog on Windows</summary> 52 | 53 | Download the latest version of MailHog from [MailHog's official repository](https://github.com/mailhog/MailHog/releases). Locate and click on the link for your Windows version (32 or 64 bit) and a `.exe` file will be downloaded to your computer. 54 | 55 | When the download completes, click to open the file. A Windows firewall notification may appear, requesting access permission for MailHog. A standard Windows command line prompt will open where MailHog will be running once firewall access is granted. 56 | 57 | Close MailHog by closing the command prompt window. To start MailHog again, click on the MailHog executable (`.exe`) file that was downloaded initially - it is not necessary to download a new MailHog installation file. 58 | 59 | Start [using MailHog](#using-mailhog). 60 | 61 | </details> 62 | 63 | <details><summary>Installing MailHog on Linux</summary> 64 | 65 | First, install [Go](https://golang.org). 66 | 67 | Run the following commands to install GO on Debian-based systems like Ubuntu and Linux Mint. 68 | 69 | ```bash 70 | sudo apt-get install golang 71 | ``` 72 | 73 | Run the following commands to install GO on RPM-based systems like CentOS, Fedora, Red Hat Linux, etc. 74 | 75 | ```bash 76 | sudo dnf install golang 77 | ``` 78 | 79 | Alternatively, run the following commands to install GO. 80 | 81 | ```bash 82 | sudo yum install golang 83 | ``` 84 | 85 | Now set the path for Go with the following commands. 86 | 87 | ```bash 88 | echo "export GOPATH=$HOME/go" >> ~/.profile 89 | echo 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' >> ~/.profile 90 | source ~/.profile 91 | ``` 92 | 93 | Finally, enter the commands below to install and run MailHog. 94 | 95 | ```bash 96 | go get github.com/mailhog/MailHog 97 | sudo cp /home/$(whoami)/go/bin/MailHog /usr/local/bin/mailhog 98 | mailhog 99 | ``` 100 | 101 | Start [using MailHog](#using-mailhog). 102 | 103 | </details> 104 | 105 | ## Using MailHog 106 | 107 | Open a new browser tab or window and navigate to [http://localhost:8025](http://localhost:8025) to open your MailHog inbox when the MailHog installation has been completed and MailHog is running. 108 | 109 | ## Useful Links 110 | 111 | - Check out the [MailHog](https://github.com/mailhog/MailHog) repository for further information related to MailHog. Additional information is also available regarding custom MailHog configurations. 112 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-contribute-to-the-codebase.md: -------------------------------------------------------------------------------- 1 | Follow these guidelines to contribute to the codebase. This is highly recommended if you want to contribute regularly. 2 | 3 | Ignoring these steps may soil your copy which makes the contributing, maintaining, and reviewing processes difficult. 4 | 5 | ## Contributing to the Codebase 6 | 7 | You can now make changes to files and commit your changes to your fork, which you can prepare by reading [how to set up freeCodeCamp locally](how-to-setup-freecodecamp-locally.md). 8 | 9 | Follow these steps: 10 | 11 | 1. Validate that you are on the `main` branch: 12 | 13 | ```bash 14 | git status 15 | ``` 16 | 17 | You should get an output like this: 18 | 19 | ```bash 20 | On branch main 21 | Your branch is up-to-date with 'origin/main'. 22 | 23 | nothing to commit, working directory clean 24 | ``` 25 | 26 | If you got a different message, then you aren't on main or your working directory isn't clean, resolve any outstanding files/commits and checkout `main`: 27 | 28 | ```bash 29 | git checkout main 30 | ``` 31 | 32 | 2. Sync the latest changes from the freeCodeCamp upstream `main` branch to your `main` fork branch: 33 | 34 | > [!WARNING] 35 | > If you have any outstanding pull requests that you made from the `main` branch of your fork, you will lose them at the end of this step. 36 | > 37 | > You should ensure your pull request is merged by a moderator before performing this step. To avoid this scenario, you should **always** work on a branch other than the `main`. 38 | 39 | This step **will sync the latest changes** from the main repository of freeCodeCamp. 40 | 41 | Update your copy of the freeCodeCamp upstream repository: 42 | 43 | ```bash 44 | git fetch upstream 45 | ``` 46 | 47 | Hard reset your main branch with the freeCodeCamp main: 48 | 49 | ```bash 50 | git reset --hard upstream/main 51 | ``` 52 | 53 | Push your main branch to your origin to have a clean history on your fork on GitHub: 54 | 55 | ```bash 56 | git push origin main --force 57 | ``` 58 | 59 | You can validate that your current main matches the upstream/main by performing a diff: 60 | 61 | ```bash 62 | git diff upstream/main 63 | ``` 64 | 65 | The resulting output should be empty. This process is important, because you will be rebase your branch on top of the latest `upstream/main` as often as possible to avoid conflicts later. 66 | 67 | 3. Create a fresh new branch: 68 | 69 | Working on a separate branch for each issue helps you keep your work copy clean. You should never work on the `main`. This will soil your copy of freeCodeCamp and you may have to start over with a fresh clone or fork. 70 | 71 | Check that you are on `main` as explained previously, and branch off from there: 72 | 73 | ```bash 74 | git checkout -b fix/update-guide-for-xyz 75 | ``` 76 | 77 | Your branch name should start with a `fix/`, `feat/`, `docs/`, etc. Avoid using issue numbers in branches. Keep them short, meaningful and unique. 78 | 79 | Some examples of good branch names are: 80 | 81 | ```md 82 | fix/update-challenges-for-react 83 | fix/update-guide-for-html-css 84 | fix/platform-bug-sign-in-issues 85 | feat/add-guide-article-for-javascript 86 | translate/add-spanish-basic-html 87 | ``` 88 | 89 | 4. Edit pages and work on code in your favorite text editor. 90 | 91 | 5. Once you are happy with the changes you should optionally run freeCodeCamp to preview the changes. 92 | 93 | 6. Make sure you fix any errors and check the formatting of your changes. 94 | 95 | 7. Check and confirm the files you are updating: 96 | 97 | ```bash 98 | git status 99 | ``` 100 | 101 | This should show a list of `unstaged` files that you have edited. 102 | 103 | ```bash 104 | On branch feat/documentation 105 | Your branch is up to date with 'upstream/feat/documentation'. 106 | 107 | Changes were not staged for commit: 108 | (use "git add/rm <file>..." to update what will be committed) 109 | (use "git checkout -- <file>..." to discard changes in the working directory) 110 | 111 | modified: CONTRIBUTING.md 112 | modified: docs/README.md 113 | modified: docs/how-to-setup-freecodecamp-locally.md 114 | modified: docs/how-to-work-on-guide-articles.md 115 | ... 116 | ``` 117 | 118 | 8. Stage the changes and make a commit: 119 | 120 | In this step, you should only mark files that you have edited or added yourself. You can perform a reset and resolve files that you did not intend to change if needed. 121 | 122 | ```bash 123 | git add path/to/my/changed/file.ext 124 | ``` 125 | 126 | Or you can add all the `unstaged` files to the staging area: 127 | 128 | ```bash 129 | git add . 130 | ``` 131 | 132 | Only the files that were moved to the staging area will be added when you make a commit. 133 | 134 | ```bash 135 | git status 136 | ``` 137 | 138 | Output: 139 | 140 | ```bash 141 | On branch feat/documentation 142 | Your branch is up to date with 'upstream/feat/documentation'. 143 | 144 | Changes to be committed: 145 | (use "git reset HEAD <file>..." to unstage) 146 | 147 | modified: CONTRIBUTING.md 148 | modified: docs/README.md 149 | modified: docs/how-to-setup-freecodecamp-locally.md 150 | modified: docs/how-to-work-on-guide-articles.md 151 | ``` 152 | 153 | Now, you can commit your changes with a short message like so: 154 | 155 | ```bash 156 | git commit -m "fix: my short commit message" 157 | ``` 158 | 159 | Some examples: 160 | 161 | ```md 162 | fix: add test for JavaScript - for loop step 163 | feat: add link for article for alexa skills 164 | ``` 165 | 166 | Make a conventional commit message. This is a good practice as a developer, and you will be following standard practices. 167 | 168 | Some examples of conventional commit messages are: 169 | 170 | ```md 171 | fix: improve HTML step 172 | fix: fix build scripts for Travis-CI 173 | feat: add link to JavaScript hoisting article 174 | docs: update contributing guidelines 175 | ``` 176 | 177 | Keep these short, not more than 50 characters. You can always add additional information in the description of the commit message. 178 | 179 | This does not take any more time than an unconventional message like 'update file' or 'add index.md' 180 | 181 | You can learn more about why you should use conventional commits [here](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#why-use-conventional-commits). 182 | 183 | 9. If you realize that you need to edit a file or update the commit message after making a commit you can do so after editing the files with: 184 | 185 | ```bash 186 | git commit --amend 187 | ``` 188 | 189 | This will open up a default text editor like `nano` or `vi` where you can edit the commit message title and add/edit the description. 190 | 191 | 10. Next, you can push your changes to your fork: 192 | 193 | ```bash 194 | git push origin branch/name-here 195 | ``` 196 | 197 | ## Proposing a Pull Request (PR) 198 | 199 | After you've committed your changes, check here for [how to open a Pull Request](how-to-open-a-pull-request.md). 200 | 201 | ## Quick commands reference 202 | 203 | A quick reference to the commands that you will need when working. 204 | 205 | | command | description | 206 | | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------- | 207 | | `pnpm test` | Run all JS tests in the system, including client, server, lint and challenge tests. | 208 | | `pnpm run test-client` | Run the client test suite. | 209 | | `pnpm run test-client -u` | Run the client test suite, updating the Jest snapshots that are out of sync. | 210 | | `pnpm run test:curriculum` | Run the curriculum test suite. | 211 | | `FCC_BLOCK='Basic HTML and HTML5' pnpm run test:curriculum` | Test a specific Block. | 212 | | `FCC_SUPERBLOCK='responsive-web-design' pnpm run test:curriculum` | Test a specific SuperBlock. | 213 | | `pnpm run test-curriculum-full-output` | Run the curriculum test suite, without bailing after the first error | 214 | | `pnpm run test-server` | Run the server test suite. | 215 | | `pnpm run e2e` | Run the Cypress end to end tests. | 216 | | `pnpm run clean` | Uninstalls all dependencies and cleans up caches. | 217 | | `pnpm run storybook` | Starts Storybook for component library development. | 218 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-help-with-video-challenges.md: -------------------------------------------------------------------------------- 1 | # How to Help with Video Challenges 2 | 3 | Video challenges are a new type of challenge in the freeCodeCamp curriculum. 4 | 5 | A video challenge is a small section of a full-length video course on a particular topic. A video challenge page embeds a YouTube video. Each challenge page has a single multiple-choice question related to the video. A user must answer the question correctly before moving on to the next video challenge in the course. 6 | 7 | The video challenge pages are created by members of the freeCodeCamp team. YouTube videos are also uploaded by members of the freeCodeCamp team. Many of the video challenges do not yet have questions associated with them. 8 | 9 | You can help by creating multiple-choice questions related to video sections and adding the questions to the markdown files for the video challenges. 10 | 11 | ## Challenge Template 12 | 13 | Below is a template of what the challenge markdown files look like. 14 | 15 | ````md 16 | --- 17 | id: Unique identifier (alphanumerical, MongoDB_id) 18 | title: Challenge Title 19 | challengeType: 11 20 | videoId: 'YouTube videoId for video challenge' 21 | forumTopicId: 12345 22 | --- 23 | 24 | # --description-- 25 | 26 | Challenge description text, in markdown 27 | 28 | ```html 29 | <div>example code</div> 30 | ``` 31 | 32 | # --question-- 33 | 34 | These fields are currently used for the multiple-choice Python challenges. 35 | 36 | ## --text-- 37 | 38 | The question text goes here. 39 | 40 | ## --answers-- 41 | 42 | Answer 1 43 | 44 | --- 45 | 46 | Answer 2 47 | 48 | --- 49 | 50 | More answers 51 | 52 | ## --video-solution-- 53 | 54 | The number for the correct answer goes here. 55 | ```` 56 | 57 | ## Creating Questions for Video Challenges 58 | 59 | ### Access the Video Challenge Markdown Files 60 | 61 | You can find the markdown files for video challenges at the following locations in the curriculum: 62 | 63 | - [Data Analysis with Python Course](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges/english/08-data-analysis-with-python/data-analysis-with-python-course) 64 | - [TensorFlow 2.0 Course](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges/english/11-machine-learning-with-python/tensorflow) 65 | - [Numpy Course](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges/english/08-data-analysis-with-python/numpy) 66 | - [How Neural Networks Work Course](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges/english/11-machine-learning-with-python/how-neural-networks-work) 67 | 68 | Pick a challenge markdown file from the options above. 69 | 70 | ### Skim through the video associated with the challenge and create a multiple-choice question 71 | 72 | First, find the `videoId`. 73 | 74 | For example, in the following code from the header of a video challenge markdown file, the `videoId` is "nVAaxZ34khk". On GitHub, the information should be laid out in a table format. 75 | 76 | ``` 77 | --- 78 | id: 5e9a093a74c4063ca6f7c14d 79 | title: Data Analysis Example A 80 | challengeType: 11 81 | videoId: nVAaxZ34khk 82 | --- 83 | ``` 84 | 85 | Next, access the YouTube video with that `videoId`. The URL for the video will be: 86 | https://www.youtube.com/watch?v=[videoId] (replace `videoId` in the URL with the video's ID - without square brackets) 87 | 88 | In the example above, the URL is https://www.youtube.com/watch?v=nVAaxZ34khk 89 | 90 | Skim the YouTube video with that `videoId` and think of a multiple-choice question based on the content of the video. 91 | 92 | ### Add the Question to the Markdown File 93 | 94 | You can add the question locally or using the GitHub interface. To add the question locally, you need to [set up freeCodeCamp locally](how-to-setup-freecodecamp-locally.md). You can also find the file on GitHub and click the edit button to add the question right in your browser. 95 | 96 | If a question has not yet been added to a particular video challenge, it will have the following default question: 97 | 98 | ```md 99 | # --question-- 100 | 101 | ## --text-- 102 | 103 | Question text 104 | 105 | ## --answers-- 106 | 107 | Answer 1 108 | 109 | --- 110 | 111 | Answer 2 112 | 113 | --- 114 | 115 | More answers 116 | 117 | ## --video-solution-- 118 | 119 | 1 120 | ``` 121 | 122 | Add/Update the question text under the part that shows: 123 | 124 | ``` 125 | # --question-- 126 | 127 | ## --text-- 128 | ``` 129 | 130 | Add/Update answers (`Answer 1`, `Answer 2`, and so on) under `## --answers--`. Make sure to update the number under `## --video-solution--` with the correct answer number. You can add more possible answers using the same format. The questions and answers can be surrounded with quotation marks. 131 | 132 | ### Question examples 133 | 134 | ````md 135 | # --question-- 136 | 137 | ## --text-- 138 | 139 | What does this JavaScript code log to the console? 140 | 141 | ```js 142 | console.log('hello world'); 143 | ``` 144 | 145 | ## --answers-- 146 | 147 | hello _world_ 148 | 149 | --- 150 | 151 | **hello** world 152 | 153 | --- 154 | 155 | hello world 156 | 157 | --- 158 | 159 | ## --video-solution-- 160 | 161 | 3 162 | ```` 163 | 164 | ````md 165 | # --question-- 166 | 167 | ## --text-- 168 | 169 | What will print out after running this code: 170 | 171 | ```py 172 | width = 15 173 | height = 12.0 174 | print(height/3) 175 | ``` 176 | 177 | ## --answers-- 178 | 179 | 39 180 | 181 | --- 182 | 183 | 4 184 | 185 | --- 186 | 187 | 4.0 188 | 189 | --- 190 | 191 | 5.0 192 | 193 | --- 194 | 195 | 5 196 | 197 | ## --video-solution-- 198 | 199 | 3 200 | ```` 201 | 202 | For more examples, you can look at the markdown files for the following video course. All the challenges already have questions: [Python for Everybody Course](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/curriculum/challenges/english/07-scientific-computing-with-python/python-for-everybody) 203 | 204 | ## Open a Pull Request 205 | 206 | After creating one or more questions, you can commit the changes to a new branch and [open a pull request](how-to-open-a-pull-request.md). 207 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-open-a-pull-request.md: -------------------------------------------------------------------------------- 1 | # How to open a Pull Request (PR) 2 | 3 | A pull request (PR), enables you to send changes from your fork on GitHub to freeCodeCamp.org's main repository. Once you are done making changes to the code, you can follow these guidelines to open a PR. 4 | 5 | We expect our contributors to be aware of the process specific to this project. Following the guidelines carefully earns you the respect of fellow maintainers and saves everyone time. 6 | 7 | Some examples of this are: 8 | 9 | 1. Do not edit files directly through GitHub – while you can, it's not a good idea. 10 | 2. Make sure you follow the PR checklist and not just tick things off; otherwise, we won't take you seriously. 11 | 3. Use the correct way to link issues in the description of the PR by updating the `XXXXXX`. Do not just add issue numbers everywhere and anywhere you feel like. 12 | 4. Do not "@mention" or request someone for reviews too many times. 13 | 14 | We understand you are excited about contributing. As much as a maintainer will love to get back to you, they are busy people looking after hundreds of requests just like yours. Be patient, someone will get to you sooner or later. 15 | 16 | 5. Do not work directly off your `main` branch - create a new branch for the changes you are working on. 17 | 18 | > [!NOTE] 19 | > Your PR should be targeting changes to the English curriculum only. Read [this guide](index.md#translations) instead for contributing to translations. 20 | 21 | ## Prepare a Good PR Title 22 | 23 | We recommend using [conventional title and messages](https://www.conventionalcommits.org/) for commits and pull request. The convention has the following format: 24 | 25 | > `<type>([optional scope(s)]): <description>` 26 | > 27 | > For example: 28 | > 29 | > `fix(learn): tests for the do...while loop challenge` 30 | 31 | Whenever you open a Pull Request(PR), you can use the below to determine the type, scope (optional), and description. 32 | 33 | **Type:** 34 | 35 | | Type | When to select | 36 | |:------|:--------------------------------------------------------------------------------| 37 | | fix | Changed or updated/improved functionality, tests, the wording of a lesson, etc. | 38 | | feat | Only if you are adding new functionality, tests, etc. | 39 | | chore | Changes that are not related to code, tests, or verbiage of a lesson. | 40 | | docs | Changes to `/docs` directory or the contributing guidelines, etc. | 41 | 42 | **Scope:** 43 | 44 | You can select a scope from [this list of labels](https://github.com/freeCodeCamp/freeCodeCamp/labels?q=scope). 45 | 46 | **Description:** 47 | 48 | Keep it short (less than 30 characters) and simple; you can add more information in the PR description box and comments. 49 | 50 | Some examples of good PR titles would be: 51 | 52 | - `fix(a11y): improved search bar contrast` 53 | - `feat: add more tests to HTML and CSS challenges` 54 | - `fix(api,client): prevent CORS errors on form submission` 55 | - `docs(i18n): fix links to be relative instead of absolute` 56 | 57 | ## Proposing a Pull Request 58 | 59 | 1. Once the edits have been committed, you will be prompted to create a pull request on your fork's GitHub Page. 60 | 61 | <details> 62 | <summary>See screenshot</summary> 63 | 64 | ![Image - Compare & pull request prompt on GitHub](https://contribute.freecodecamp.org/images/github/compare-pull-request-prompt.png) 65 | 66 | </details> 67 | 68 | 2. By default, all pull requests should be against the freeCodeCamp main repo, `main` branch. 69 | 70 | Make sure that your Base Fork is set to freeCodeCamp/freeCodeCamp when raising a Pull Request. 71 | 72 | <details> 73 | <summary>See screenshot</summary> 74 | 75 | ![Image - Comparing forks when making a pull request](https://contribute.freecodecamp.org/images/github/comparing-forks-for-pull-request.png) 76 | 77 | </details> 78 | 79 | 3. Submit the pull request from your branch to freeCodeCamp's `main` branch. 80 | 81 | 4. Include a more detailed summary of the changes you made and how your changes are helpful in the body of your PR. 82 | 83 | - You will be presented with a pull request template. This is a checklist that you should have followed before opening the pull request. 84 | 85 | - Fill in the details as you see fit. This information will be reviewed and the reviewers will decide whether or not your pull request is accepted. 86 | 87 | - If the PR is meant to address an existing GitHub Issue then, at the end of 88 | your PR's description body, use the keyword _Closes_ with the issue number to [automatically close that issue if the PR is accepted and merged](https://help.github.com/en/articles/closing-issues-using-keywords). 89 | 90 | > Example: `Closes #123` will close issue 123 91 | 92 | 5. Indicate if you have tested on a local copy of the site or not. 93 | 94 | - This is very important when making changes that are not just edits to text content like documentation or a challenge description. Examples of changes that need local testing include JavaScript, CSS, or HTML, which could change the functionality or layout of a page. 95 | 96 | - If your PR affects the behaviour of a page, it should be accompanied by corresponding [Cypress integration tests](how-to-add-cypress-tests.md). 97 | 98 | ## Feedback on Pull Requests 99 | 100 | > :tada: Congratulations on making a PR and thanks a lot for taking the time to contribute. 101 | 102 | Our moderators will now take a look and leave you feedback. Please be patient with the fellow moderators and respect their time. All pull requests are reviewed in due course. 103 | 104 | And as always, feel free to ask questions on the ['Contributors' category on our forum](https://forum.freecodecamp.org/c/contributors) or [the contributors chat room](https://discord.gg/PRyKn3Vbay). 105 | 106 | > [!TIP] 107 | > If you are to be contributing more pull requests, we recommend you read the [making changes and syncing](how-to-setup-freecodecamp-locally.md#making-changes-locally) guidelines to avoid having to delete your fork. 108 | 109 | ## Conflicts on a Pull Request 110 | 111 | Conflicts can arise because many contributors work on the repository, and changes can break your PR which is pending a review and merge. 112 | 113 | Since we squash all commits, you may not need to do a rebase. However, if a rebase is requested, check our [For Usual Bug Fixes and Features](#for-usual-bug-fixes-and-features) or [For Upcoming Curriculum and Features](#for-upcoming-curriculum-and-features) guides to learn how to do this process for your corresponding PR. 114 | 115 | ### For Usual Bug Fixes and Features 116 | 117 | When you are working on regular bugs and features on our development branch `main`, you are able to do a simple rebase: 118 | 119 | 1. Rebase your local copy: 120 | 121 | ```bash 122 | git checkout <pr-branch> 123 | git pull --rebase upstream main 124 | ``` 125 | 126 | 2. Resolve any conflicts and add / edit commits 127 | 128 | ```bash 129 | # Either 130 | git add . 131 | git commit -m "chore: resolve conflicts" 132 | 133 | # Or 134 | git add . 135 | git commit --amend --no-edit 136 | ``` 137 | 138 | 3. Push back your changes to the PR 139 | 140 | ```bash 141 | git push --force origin <pr-branch> 142 | ``` 143 | 144 | ### For Upcoming Curriculum and Features 145 | 146 | When you are working on features for our upcoming curriculum `next-*` branches, you have to do a `cherry-pick`: 147 | 148 | 1. Make sure your upstream comes in sync with your local: 149 | 150 | ```bash 151 | git checkout main 152 | git fetch --all --prune 153 | git checkout next-python-projects 154 | git reset --hard upstream/next-python-projects 155 | ``` 156 | 157 | 2. Take a backup 158 | 159 | a. Either delete your local branch after taking a backup (if you still have it locally): 160 | 161 | ```bash 162 | git checkout <pr-branch-name> 163 | 164 | # example: 165 | # git checkout feat/add-numpy-video-question 166 | 167 | git checkout -b <backup-branch-name> 168 | 169 | # example: 170 | # git checkout -b backup-feat/add-numpy-video-question 171 | 172 | git branch -D <pr-branch-name> 173 | ``` 174 | 175 | b. Or just a backup of your PR branch (if you do not have it locally): 176 | 177 | ```bash 178 | git checkout -b <backup-branch-name> origin/<pr-branch-name> 179 | 180 | # example: 181 | # git checkout -b backup-feat/add-numpy-video-question origin/feat/add-numpy-video-question 182 | ``` 183 | 184 | 3. Start off with a clean slate: 185 | 186 | ```bash 187 | git checkout -b <pr-branch-name> next-python-projects 188 | git cherry-pick <commit-hash> 189 | ``` 190 | 191 | 4. Resolve any conflicts, cleanup, and install dependencies and run tests 192 | 193 | ```bash 194 | pnpm run clean 195 | 196 | pnpm install 197 | FCC_SUPERBLOCK='<superblock-name>' pnpm run test:curriculum 198 | 199 | # example: 200 | 201 | # FCC_SUPERBLOCK='python-for-everybody' pnpm run test:curriculum 202 | 203 | ``` 204 | 205 | 5. If everything looks good, push back to the PR 206 | 207 | ```bash 208 | git push --force origin <pr-branch-name> 209 | ``` 210 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-proofread-files.md: -------------------------------------------------------------------------------- 1 | # How to Proofread Translations 2 | 3 | Our proofreading team is responsible for ensuring that translations accurately reflect the source text. We trust our proofreaders to ensure that we have very high quality translations. 4 | 5 | All our translations are done by hand, by real humans. Proofreading ensures that there is a consistent tone across all our translated resources like the curriculum. 6 | 7 | To begin proofreading, visit [our translation platform](https://translate.freecodecamp.org) and login. Select "Go to console" in the top navigation bar to switch from the public view to the workspace view. 8 | 9 | ## Select a File 10 | 11 | You should see the list of projects you have been granted access to. Select the project that you would like to proofread, then select the language. 12 | 13 | ![Image - Proofreading File Tree](https://contribute.freecodecamp.org/images/crowdin/proof-file-tree.png) 14 | 15 | You should now see the list of available files. Choose your file by selecting the `Proofread` button on the right of that file, then choosing `Proofreading` from the drop-down menu that appears. 16 | 17 | > [!NOTE] 18 | > If you are in this workspace view, but want to work on [translating a file](how-to-translate-files.md) instead of proofreading, you may select `Crowdsourcing` from the dropdown menu instead. 19 | 20 | ## Proofread Translations 21 | 22 | ![Image - Proofreading View](https://contribute.freecodecamp.org/images/crowdin/proofread.png) 23 | 24 | <!--Add proofread/crowdsource button to the image--> 25 | 26 | Here you will see the list of strings in the selected file, with their related translations. The translation that is displayed here is the translation that has received the highest score (between upvotes and downvotes) from the translation community. 27 | 28 | While you can view _all_ proposed translations for a given string, the community scores (determined by the upvotes and downvotes) should be taken into consideration when choosing which translation to approve. The community can review proposed translations and recommend which one is most accurate and clear. 29 | 30 | 1. This is the original string (in English). 31 | 2. This is the matching translated string. The most popular translation proposal, based on upvotes and downvotes, will be displayed here. 32 | 3. Clicking this checkmark button will approve that translation. 33 | 4. Crowdin will display the status of each string. `Done` means a translation has been approved and will be downloaded on our next Crowdin pull. `Todo` means the string has not been proofread. `Hidden` means the string is locked and _should not be translated_. `Comment` means the string has a related comment. 34 | 5. Translations can be selected with the checkboxes and approved here in one bulk action. 35 | 6. You can view the community proposed translations, their popularity scores, and Crowdin suggested translations here. 36 | 7. This button shows/hides the right-hand side display pane, where you can view translations, comments, translation memory, and glossary terms. 37 | 8. Crowdin displays error messages here from the quality assurance checks. In other words, if something does not seem correct in the translation, Crowdin will notify you. These translations should be approved with care. 38 | 39 | No additional actions are required once a file has been proofread. 40 | 41 | > [!NOTE] 42 | > Approving a string in the proofreading view will mark it as complete and it will be downloaded in our next pull from Crowdin to GitHub. 43 | 44 | ## Becoming a Proofreader 45 | 46 | If you have any questions, or are interested in becoming a proofreader, feel free to reach out to us in our [contributors chat room](https://discord.gg/PRyKn3Vbay). We will typically grant you proofreading access if you have been contributing to freeCodeCamp for a while. 47 | 48 | Our staff team and community moderators teams are always looking for kind volunteers like you who help us make high quality translations available to the world. 49 | 50 | > [!NOTE] 51 | > Crowdin will allow you to approve your translations. In general, it is best to allow another proofreader to review your proposed translations as extra safety to ensure there are no errors. 52 | 53 | ## Creating a Channel on Chat for a World Language 54 | 55 | For the most part, we encourage you to use the [contributors chat](https://discord.gg/PRyKn3Vbay) room for all correspondence. However if the team of volunteer translators grows for a certain language, we can consider creating an additional break-out channel for the language. 56 | 57 | If you are already a proofreader and are interested in having a dedicated channel on our chat servers for a specific language, [fill out this form](https://forms.gle/XU5CyutrYCgDYaVZA). 58 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-setup-wsl.md: -------------------------------------------------------------------------------- 1 | # Set up freeCodeCamp on Windows Subsystem for Linux (WSL) 2 | 3 | > [!NOTE] 4 | > Before you follow these instructions make sure your system meets the requirements. 5 | > 6 | > **WSL 2**: Windows 10 64-bit (Version 2004, Build 19041 or higher) - available for all distributions including Windows 10 Home. 7 | > 8 | > **Docker Desktop for Windows**: See respective requirements for [Windows 10 Pro](https://docs.docker.com/docker-for-windows/install/#system-requirements) and [Windows 10 Home](https://docs.docker.com/docker-for-windows/install-windows-home/#system-requirements) 9 | 10 | This guide covers some common steps with the setup of WSL2. Once some of the common issues with WSL2 are addressed, you should be able to follow [this local setup guide](how-to-setup-freecodecamp-locally.md) to work with freeCodeCamp on Windows running a WSL distro like Ubuntu. 11 | 12 | ## Enable WSL 13 | 14 | Follow the instructions on the [official documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to install WSL2. 15 | 16 | ## Install Ubuntu 17 | 18 | 1. We recommended using Ubuntu-18.04 or above with WSL2. 19 | 20 | > [!NOTE] 21 | > 22 | > While you may use other non-Debian-based distributions, they all come with their own 'gotchas' that are beyond the scope of this guide. 23 | 24 | As of November 2023, Ubuntu and Debian are the only Linux distributions [officially supported by Playwright](https://playwright.dev/docs/intro#system-requirements), the end-to-end testing library used by freeCodeCamp. 25 | 26 | 2. Update the dependencies for the OS 27 | 28 | ```bash 29 | sudo apt update 30 | sudo apt upgrade -y 31 | 32 | # cleanup 33 | sudo apt autoremove -y 34 | ``` 35 | 36 | ## Set up Git 37 | 38 | Git comes pre-installed with Ubuntu 18.04, verify your Git version with `git --version`. 39 | 40 | ```output 41 | ~ 42 | ❯ git --version 43 | git version 2.25.1 44 | ``` 45 | 46 | (Optional but recommended) You can now proceed to [setting up your ssh keys](https://help.github.com/articles/generating-an-ssh-key) with GitHub. 47 | 48 | ## Installing a Code Editor 49 | 50 | We highly recommend installing [Visual Studio Code](https://code.visualstudio.com) on Windows 10. It has great support for WSL and automatically installs all the necessary extensions on your WSL distribution. 51 | 52 | Essentially, you will edit and store your code on Ubuntu-18.04 with VS Code installed on Windows. 53 | 54 | If you use [IntelliJ Idea](https://www.jetbrains.com/idea/), you may need to update your Node interpreter and npm package manager to what is installed on your WSL distro. 55 | 56 | You can check these settings by going to Settings > Languages & Frameworks > Node.js and npm. 57 | 58 | ## Installing Docker Desktop 59 | 60 | **Docker Desktop for Windows** allows you to install and run databases like MongoDB and other services like NGINX and more. This is useful to avoid common pitfalls with installing MongoDB or other services directly on Windows or WSL2. 61 | 62 | Follow the instructions on the [official documentation](https://docs.docker.com/docker-for-windows/install) and install Docker Desktop for your Windows distribution. 63 | 64 | There are some minimum hardware requirements for the best experience. 65 | 66 | ## Configure Docker Desktop for WSL 67 | 68 | Once Docker Desktop is installed, [follow these instructions](https://docs.docker.com/docker-for-windows/wsl) and configure it to use the Ubuntu-18.04 installation as a backend. 69 | 70 | This makes it so that the containers run on the WSL side instead of running on Windows. You will be able to access the services over `http://localhost` on both Windows and Ubuntu. 71 | 72 | ## Install MongoDB from Docker Hub 73 | 74 | Once you have configured Docker Desktop to work with WSL2, follow these steps to start a MongoDB service: 75 | 76 | 1. Launch a new Ubuntu terminal 77 | 78 | 2. Pull MongoDB from Docker Hub. Please refer to the [Prerequisites](how-to-setup-freecodecamp-locally.md#Prerequisites) table for the current version of MongoDB used by freeCodeCamp. For example, if the version number is `5.0.x`, replace `<x.y>` with `5.0` in the following two code snippets. 79 | 80 | ```bash 81 | docker pull mongo:<x.y> 82 | ``` 83 | 84 | 3. Start the MongoDB service at port `27017`, and configure it to run automatically on system restarts 85 | 86 | ```bash 87 | docker run -it \ 88 | -v mongodata:/data/db \ 89 | -p 27017:27017 \ 90 | --name mongodb \ 91 | --restart unless-stopped \ 92 | -d mongo:<x.y> 93 | ``` 94 | 95 | 4. You can now access the service from both Windows or Ubuntu at `mongodb://localhost:27017`. 96 | 97 | ## Installing Node.js and pnpm 98 | 99 | We recommend you install the LTS release for Node.js with a node version manager - [nvm](https://github.com/nvm-sh/nvm#installing-and-updating). 100 | 101 | Once installed use this command to install and use the latest Node.js LTS version: 102 | 103 | ```bash 104 | nvm install --lts 105 | ``` 106 | 107 | For instructions on installing and using a different version of Node.js, please refer to the [nvm docs](https://github.com/nvm-sh/nvm#usage). 108 | 109 | Node.js comes bundled with `npm`, which you can use to install `pnpm`: 110 | 111 | ```bash 112 | npm install -g pnpm 113 | ``` 114 | 115 | ## Set up freeCodeCamp Locally 116 | 117 | Now that you have installed the pre-requisites, follow [our local setup guide](how-to-setup-freecodecamp-locally.md) to clone, install and set up freeCodeCamp locally on your machine. 118 | 119 | > [!WARNING] 120 | > 121 | > Please note, at this time the setup for Cypress tests (and related GUI needs) is a work in progress. You should still be able to work on most of the codebase. 122 | 123 | ## Optimize Windows and WSL 124 | 125 | > [!NOTE] 126 | > 127 | > The following tips were collected from across the web and have not gone through vigorous testing. Your mileage may vary. 128 | 129 | ### Adjust processer scheduling for background services 130 | 131 | This may reduce incidents of Docker containers crashing due to lack of resources. 132 | 133 | Open the System Properties control panel by pressing <kbd>Win + R</kbd> and entering `sysdm.cpl` 134 | 135 | <details> 136 | <summary> 137 | Enter <code>sysdm.cpl</code> in the Run dialog (screenshot) 138 | </summary> 139 | <br> 140 | <img src="https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/wsl/run-sysdm.png" alt="Enter `sysdm.cpl` in the Run dialog"> 141 | </details> 142 | <br> 143 | 144 | Go to Advanced -> Performance -> Settings… 145 | 146 | <details> 147 | <summary> 148 | Performance Settings button under Advanced tab in System Properties (screenshot) 149 | </summary> 150 | <br> 151 | <img src="https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/wsl/advanced-performance-settings.png" alt="Performance Settings button under Advanced tab in System Properties"> 152 | </details> 153 | <br> 154 | 155 | Under Advanced -> Processor scheduling, choose "Background services". Do not close the window. Continue to the next tip. 156 | 157 | <details> 158 | <summary> 159 | Background services radio button under Advanced tab in Performance Options (screenshot) 160 | </summary> 161 | <br> 162 | <img src="https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/wsl/background-services.png" alt="Background services radio button under Advanced tab in Performance Options"> 163 | </details> 164 | 165 | ### Increase the size of Windows paging file for the system drive 166 | 167 | Under Advanced -> Virtual memory, click "Change…" 168 | 169 | <details> 170 | <summary> 171 | Change virtual memory button under Advanced tab in Performance Options (screenshot) 172 | </summary> 173 | <br> 174 | <img src="https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/wsl/advanced-virtual-memory.png" alt="Change virtual memory button under Advanced tab in Performance Options"> 175 | </details> 176 | <br> 177 | 178 | Choose "Custom size". Set the initial size to 1.5x and the maximum size to 3x of your physical memory. Then click "Set". 179 | 180 | <details> 181 | <summary> 182 | Set custom size button in Virtual Memory window (screenshot) 183 | </summary> 184 | <br> 185 | <img src="https://raw.githubusercontent.com/freeCodeCamp/freeCodeCamp/main/docs/images/wsl/set-custom-size.png" alt="Set custom size button in Virtual Memory window"> 186 | </details> 187 | 188 | ### Increase the size of memory allocated to WSL 189 | 190 | Create a [`.wslconfig` file](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#configuration-setting-for-wslconfig) in your [`%UserProfile%` directory](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#wslconfig) (typically `C:\Users\<UserName>\.wslconfig`). Please read the [WSL documentation](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#configuration-setting-for-wslconfig) carefully and replace `x` with values that suit your own needs: 191 | 192 | ```ini 193 | # Settings apply across all Linux distros running on WSL 2 194 | [wsl2] 195 | 196 | # How much memory to assign to the WSL 2 VM. The default value might not be enough 197 | memory=xGB 198 | 199 | # How much swap space to add to the WSL 2 VM, default is 25% of available RAM 200 | swap=xGB 201 | ``` 202 | 203 | ### Increase Node.js max old space size 204 | 205 | This fixes the ["JavaScript heap out of memory" error](https://stackoverflow.com/a/54456814) with ESLint. Add the following to your `~/.bashrc` or `~/.zshrc`: 206 | 207 | ```sh 208 | export NODE_OPTIONS="--max-old-space-size=4096" 209 | ``` 210 | 211 | ### Avoid `pnpm run test` 212 | 213 | Instead, use the script [appropriate to your PR](https://forum.freecodecamp.org/t/wsl-performance-issues-while-working-on-the-codebase/644215/2#:~:text=usually%2C%20you%20just%20want%20to%20test%20something%20specific%20to%20either%20the%20curriculum%20or%20the%20client%20or%20the%20api%20-%20almost%20never%20all%203.); either `pnpm run test:api`, `pnpm run test:curriculum`, or `pnpm run test-client`. 214 | 215 | ## Useful Links 216 | 217 | - [A WSL2 Dev Setup with Ubuntu 20.04, Node.js, MongoDB, VS Code, and Docker](https://hn.mrugesh.dev/wsl2-dev-setup-with-ubuntu-nodejs-mongodb-and-docker) - an article by Mrugesh Mohapatra (Staff Developer at freeCodeCamp.org) 218 | - Frequently asked questions on: 219 | - [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/faq) 220 | - [Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/faqs) 221 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-use-docker-on-windows-home.md: -------------------------------------------------------------------------------- 1 | # How to use Docker on Windows Home 2 | 3 | There are a few pitfalls to be avoided when setting up Docker on Windows Home. First of all, you have to use [Docker Toolbox](https://docs.docker.com/toolbox/toolbox_install_windows/) as Administrator. Unfortunately Windows Home does not support Docker for Windows Desktop, so Toolbox must be used instead. It has to be run as Administrator as the installation uses symlinks, which cannot be created otherwise. 4 | 5 | Once you've installed the toolbox, run Docker Quickstart Terminal as Administrator. This will create a `default` virtual machine if it does not already exist. Once that has happened, close the terminal and open VirtualBox (again as Administrator). You should be able to see the `default` machine. The site is quite resource-intensive, so stop the virtual machine and raise the settings as much as you can - memory in particular. It has been confirmed to work with 4GB of RAM. 6 | 7 | Once you're happy that Docker is working, clone the freeCodeCamp repository to a directory inside `C:\Users`. These directories are shared giving Docker access to the local directories, which it needs during installation. 8 | 9 | If you see messages like 10 | 11 | ```shell 12 | bash: change_volumes_owner.sh: No such file or directory 13 | ``` 14 | 15 | when you `pnpm run docker:init` this is likely the culprit. 16 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-work-on-localized-client-webapp.md: -------------------------------------------------------------------------------- 1 | # How to Work on Localized Client Webapp 2 | 3 | The React-based client web app that powers our learning platform is built using Gatsby. It is translated into various world languages using [react-i18next](https://react.i18next.com/) and [i18next](https://www.i18next.com/). 4 | 5 | You can learn more about setting up the client application locally for development by following [our local setup guide here](how-to-setup-freecodecamp-locally.md). By default, the application is available only in English. 6 | 7 | Once you have set up the project locally you should be able to follow this documentation to run the client in the language of your choice from the list of available languages. 8 | 9 | This could be helpful when you are working on a feature that specifically targets something that involves localization, and requires you to validate for instance a button's label in a different language. 10 | 11 | > [!TIP] 12 | > You do not need to follow this document to translate freeCodeCamp's curriculum or contributing documentation. Read [this guide here](how-to-translate-files.md) instead. 13 | 14 | Let's understand how the i18n frameworks and tooling work. 15 | 16 | ## File Structure 17 | 18 | Most of the files for translating the platform are located in the [`client/i18n`](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/client/i18n) folder. Each language has a directory that contains JSON files with the translations. 19 | 20 | ```bash 21 | config 22 | └── i18n.ts 23 | ... 24 | client/i18n 25 | ├── configForTests.js 26 | ├── config.js 27 | ├── locales 28 | │   ├── chinese 29 | │   │   ├── intro.json 30 | │   │   ├── links.json 31 | │   │   ├── meta-tags.json 32 | │   │   ├── motivation.json 33 | │   │   └── translations.json 34 | ... ... 35 | │   ├── dothraki 36 | │   │   ├── intro.json 37 | │   │   ├── links.json 38 | │   │   ├── meta-tags.json 39 | │   │   ├── motivation.json 40 | │   │   └── translations.json 41 | ... ... 42 | │   ├── english 43 | │   │   ├── intro.json 44 | │   │   ├── links.json 45 | │   │   ├── meta-tags.json 46 | │   │   ├── motivation.json 47 | │   │   └── translations.json 48 | │   └── espanol 49 | │   ├── intro.json 50 | │   ├── links.json 51 | │   ├── meta-tags.json 52 | │   ├── motivation.json 53 | │   └── translations.json 54 | ├── locales.test.js 55 | ├── schema-validation.js 56 | └── validate-keys.ts 57 | ``` 58 | 59 | Some of these files are translated on our translation platform (Crowdin) and some are translated or created via PRs on GitHub. 60 | 61 | **Files translated on our translation platform:** 62 | 63 | - The `translations.json` file contains the majority of the text that appears on the user interface elements. The keys are used in the codebase to get the correct text for whatever language is set. This file needs to have the same keys in all languages. 64 | 65 | - The `intro.json` file contains the key-value pairs for the introduction text on the certification pages. 66 | 67 | If you want to add/update translations for the keys please [read this guide here](how-to-translate-files.md). 68 | 69 | **Files NOT translated on our translations platform:** 70 | 71 | - The `motivation.json` files are not required to have the same quotes, compliments, or array length. Just the same JSON structure. 72 | 73 | - The `meta-tags.json` file contains the information for our website's meta tag information. 74 | 75 | Changes to these files are typically done by the staff team. If you see something out of the ordinary we recommend you reach us in the [contributors chat room](https://discord.gg/PRyKn3Vbay). 76 | 77 | ## Testing the Client App in a World Language 78 | 79 | You can test the client app in any language available in the [list of `availableLangs` here](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/shared/config/i18n.ts). 80 | 81 | ```js 82 | export const availableLangs = { 83 | client: [ 84 | Languages.English, 85 | Languages.Espanol, 86 | Languages.Chinese, 87 | Languages.ChineseTraditional, 88 | Languages.Italian, 89 | Languages.Portuguese, 90 | Languages.Ukrainian, 91 | Languages.Japanese, 92 | Languages.German, 93 | Languages.Arabic 94 | ], 95 | ... 96 | }; 97 | ``` 98 | 99 | If you are testing a new language, create a folder with the language name as the title next to the other languages and copy the JSON files from another language into your new folder. 100 | 101 | Add the new language to the `Languages` enum and the `client` array at the top of the [`shared/config/i18n.ts`](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/shared/config/i18n.ts) file. 102 | 103 | Next, follow the instructions in the comments in the same file to add/update the rest of the variables as needed. 104 | 105 | Finally, set the `CLIENT_LOCALE` variable in your `.env` file to the string of the locale you want to build from the `Languages` enum in the above file. 106 | 107 | ## How to Structure Components 108 | 109 | If you are working on a feature or a bug for the client web app, say for example adding new UI items on the settings page, you should follow the guidelines below. They will help you prepare the components for localization into all the supported world languages. 110 | 111 | ### Functional Component 112 | 113 | ```js 114 | import { useTranslation } from 'react-i18next'; 115 | 116 | // in the render method: 117 | const { t } = useTranslation(); 118 | 119 | // call the "t" function with a key from the JSON file: 120 | <p>{t('key')}</p>; // more details below 121 | ``` 122 | 123 | ### Class Component 124 | 125 | ```js 126 | import { withTranslation } from 'react-i18next'; 127 | 128 | // withTranslation adds the "t" function to props: 129 | const { t } = this.props; 130 | 131 | // call the "t" function with a key from the JSON file: 132 | <h1>{t('key')}</h1> // more details below 133 | 134 | // export without redux: 135 | export default withTranslation()(Component); 136 | 137 | // or with redux: 138 | export default connect(...)(withTranslation()(Component)); 139 | ``` 140 | 141 | ## Translate Using the "t" Function 142 | 143 | ### Basic Translation 144 | 145 | ```js 146 | // in the component: 147 | <p>{t('p1')}</p> 148 | 149 | // in the JSON file: 150 | { 151 | "p1": "My paragraph" 152 | } 153 | 154 | // output: 155 | <p>My paragraph</p> 156 | ``` 157 | 158 | ### With Dynamic Data 159 | 160 | ```js 161 | // in the component: 162 | const username = 'moT'; 163 | 164 | <p>{t('welcome', { username: username })}</p> 165 | 166 | // in the JSON file: 167 | { 168 | "welcome": "Welcome {{username}}" 169 | } 170 | 171 | // output: 172 | <p>Welcome moT</p> 173 | ``` 174 | 175 | The above example passes an object to the `t` function with a `username` variable. The variable will be used in the JSON value where `{{username}}` is. 176 | 177 | ## Translate with the `Trans` Component 178 | 179 | The general rule is to use the "t" function when you can. But there's a `Trans` component for when that isn't enough, usually when you have elements embedded in the text. You can use the `Trans` component with any type of react component. 180 | 181 | ### Basic Elements Nested 182 | 183 | ```js 184 | // in the component: 185 | import { Trans } from 'react-i18next' 186 | 187 | <p> 188 | <Trans>fcc.greeting</Trans> 189 | </p> 190 | 191 | // in the JSON file: 192 | { 193 | "fcc": { 194 | "greeting": "Welcome to <strong>freeCodeCamp</strong>" 195 | } 196 | } 197 | 198 | // output: 199 | <p>Welcome to <strong>freeCodeCamp</strong></p> 200 | ``` 201 | 202 | You can place the key inside the component tags like in the above example if the text contains "simple" tags with no attributes. `br`, `strong`, `i`, and `p` are the default, but that list can be expanded in the i18n config. 203 | 204 | ### Complex Elements Nested 205 | 206 | Other times, you will want to have certain text inside another element, an anchor tag is a good example: 207 | 208 | ```js 209 | // in the component: 210 | <p> 211 | <Trans i18nKey='check-forum'> 212 | <a href='https://forum.freecodecamp.org/'>placeholder</a> 213 | </Trans> 214 | </p> 215 | 216 | // in the JSON file: 217 | { 218 | "check-forum": "Check out <0>our forum</0>." 219 | } 220 | 221 | // output: 222 | <p>Check out <a href='https://forum.freecodecamp.org/'>our forum</a></p> 223 | ``` 224 | 225 | In the above example, the key is set in the attributes of the `Trans` component. The `<0>` and `</0>` in the JSON represent the first child of the component, in this case, the anchor element. If there were more children, they would just count up from there using the same syntax. You can find the children of a component in the react dev tools by inspecting it. `placeholder` is simply there because the linter complains about empty `<a>` elements. 226 | 227 | ### With a Variable 228 | 229 | ```js 230 | // in the component: 231 | const email = 'team@freecodecamp.org'; 232 | 233 | <p> 234 | <Trans email={email} i18nKey='fcc.email'> 235 | <a href={`mailto:${email}`}> 236 | {{ email }} 237 | </a> 238 | </Trans> 239 | </p> 240 | 241 | // in the JSON file: 242 | { 243 | "fcc": { 244 | "email": "Send us an email at: <0>{{email}}</0>" 245 | } 246 | } 247 | 248 | // output: 249 | <p>Send us an email at: <a href='mailto:team@freecodecamp.org'>team@freecodecamp.org</a><p> 250 | ``` 251 | 252 | In the above example, the key and a variable are set in the attributes of the `Trans` component. `{{ email }}` needs to be somewhere in the `Trans` component as well, it doesn't matter where. 253 | 254 | ## Changing Text 255 | 256 | To change text on the client side of things, go to the relevant `.json` file, find the key that is being used in the React component, and change the value to the new text you want. You should search the codebase for that key to make sure it isn't being used elsewhere. Or, if it is, that the changes make sense in all places. 257 | 258 | ## Adding Text 259 | 260 | If the text you want to add to the client exists in the relevant `.json` file, use the existing key. Otherwise, create a new key. 261 | 262 | The English file is the "source of truth" for all of the `.json` files sharing the same name. If you need to add a new key, add it there. Then, add the key to **all** of the `translations.json` files. 263 | 264 | > [!NOTE] 265 | > Use English text for all languages if the file is translated through Crowdin. The tests will fail if you don't. 266 | 267 | It would be nice to keep the keys in the same order across all the files as well. Also, try to put all punctuation, spacing, quotes, etc in the JSON files and not in the components or server files. 268 | 269 | > [!NOTE] 270 | > The underscore (`_`) is a reserved character for keys in the client-side files. See [the documentation](https://www.i18next.com/translation-function/plurals) for how they are used. 271 | 272 | ## Proposing a Pull Request (PR) 273 | 274 | After you've committed your changes, check here for [how to open a Pull Request](how-to-open-a-pull-request.md). 275 | 276 | ## Helpful Documentation 277 | 278 | - [react-i18next docs](https://react.i18next.com/latest/usetranslation-hook) 279 | - [i18next docs](https://www.i18next.com/translation-function/essentials) 280 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-work-on-practice-projects.md: -------------------------------------------------------------------------------- 1 | # How to Work on Practice Projects 2 | 3 | Our practice projects use a step-based approach to teach concepts to campers. A project will consist of multiple files, which we refer to as **"steps"**. These files are named by the challenge ID, to avoid issues with the translation flow. Unfortunately, this makes it difficult to find the file associated with a specific step. 4 | 5 | We've built a challenge editor tool that helps remedy this. This tool allows you to navigate the available projects, and the steps for each project (in order). There's also an embedded code editor you can use to work on the files directly. 6 | 7 | ## Using the Challenge Editor 8 | 9 | These instructions will tell you how to use our challenge editor tool to work on the practice projects. 10 | 11 | ### Starting the Editor 12 | 13 | To start the editor, make sure you are in the root freeCodeCamp directory. Then, run `pnpm run challenge-editor` to start both the client and the API that powers the editor. 14 | 15 | The client will run on port `3300`, so you can access it at `http://localhost:3300`. The API runs on port `3200`, to avoid conflicts with the learn client and server. This will allow you to run the freeCodeCamp application at the same time as the editor, so you can test your changes locally. 16 | 17 | ### Navigating the Editor 18 | 19 | The default view will list the available `superblocks` - these are the certifications. Click on the certification link you want to work on. 20 | 21 | This will take you to the list of blocks. These are the practice projects. Click on the project link you want to work on. 22 | 23 | This will take you to a list of steps for the project. If you are working on an existing step, you can click on the step link to open the editor. If you are adding or removing steps, click the `Use the step tools` link to switch to the step tools for that challenge. 24 | 25 | ### Editing Steps 26 | 27 | When you click on a step, you'll be taken to the editor. This is a basic text editor that offers syntax highlighting. 28 | 29 | After you have made your changes, click the `Save Changes` button to save your changes. You will get a browser alert letting you know that your changes are ready to commit. Note that you'll need to use `git` manually to stage and commit your files - this tool will not do that for you. 30 | 31 | ### Step Tools 32 | 33 | When you click the `Use the step tools` link, you'll be taken to the step tools page. This allows you to add or remove steps from the project. 34 | 35 | #### Create Next Step 36 | 37 | Clicking this button will add a new step at the end of the project. This step will use the previous step's code as the seed. 38 | 39 | #### Create Empty Steps 40 | 41 | Enter the number of steps you want to add in the input. Then, clicking the button will create many empty steps at the end of the project. 42 | 43 | #### Insert Step 44 | 45 | Enter the step number that you want to add. Then, click the `Insert Step` button to add the step. The following steps will be re-ordered. 46 | 47 | #### Delete Step 48 | 49 | Enter the step number you want to delete. Then click the `Delete Step` button to remove that step. This will automatically update the step numbers for the remaining steps. 50 | 51 | #### Update Step Titles 52 | 53 | You should not have to use this tool unless you've manually deleted or added steps. This tool will reorder the step numbers. 54 | 55 | ## Using the Scripts Manually 56 | 57 | If you want to work on the steps manually, in your local IDE, you can run the step management scripts directly. 58 | 59 | The `tools/challenge-helper-scripts` folder contains tools to help facilitate the creation and maintenance of the freeCodeCamp project-based curriculum. 60 | 61 | ### Create a New Project 62 | 63 | Change directory to `tools/challenge-helper-scripts` and run `pnpm run create-project`. This opens up a command line UI that guides you through the process. Once that has finished, there should be a new challenge in the English curriculum that you can use for the first step of the project. For example, if you created a project called `test-project` in the Responsive Web Design certification, it would be in `curriculum/challenges/english/01-responsive-web-design/test-project`. 64 | 65 | If you want to create new steps, the following tools simplify that process. 66 | 67 | ### create-next-step 68 | 69 | A one-off script that will automatically add the next step based on the last step in the project. The challenge seed code will use the previous step's challenge seed code. 70 | 71 | #### How to Run the Script 72 | 73 | 1. Change to the directory of the project. 74 | 2. Run the following command: 75 | 76 | ```bash 77 | pnpm run create-next-step 78 | ``` 79 | 80 | ### create-empty-steps 81 | 82 | A one-off script that automatically adds a specified number of steps. The challenge seed code for all steps created will be empty. 83 | 84 | **Note:** This script also runs [update-step-titles](#update-step-titles). 85 | 86 | #### How to Run the Script 87 | 88 | 1. Change to the directory of the project. 89 | 2. Run the following command: 90 | 91 | ```bash 92 | pnpm run create-empty-steps X # where X is the number of steps to create. 93 | ``` 94 | 95 | ### insert-step 96 | 97 | A one-off script that automatically adds a new step at a specified position, incrementing all subsequent steps (both their titles and in their meta.json). The challenge seed code will use the previous step's challenge seed code with the editable region markers (ERMs) removed. 98 | 99 | **Note:** This script also runs [update-step-titles](#update-step-titles). 100 | 101 | #### How to Run the Script 102 | 103 | 1. Change to the directory of the project. 104 | 2. Run the following command: 105 | 106 | ```bash 107 | pnpm run insert-step X # where X is the position to insert the new step. 108 | ``` 109 | 110 | ### delete-step 111 | 112 | A one-off script that deletes an existing step, decrementing all subsequent steps (both their titles and in their meta.json) 113 | 114 | **Note:** This script also runs [update-step-titles](#update-step-titles). 115 | 116 | #### How to Run the Script 117 | 118 | 1. Change to the directory of the project. 119 | 2. Run the following command: 120 | 121 | ```bash 122 | pnpm run delete-step X # where X is the step number to be deleted. 123 | ``` 124 | 125 | ### update-step-titles 126 | 127 | A one-off script that automatically updates the frontmatter in a project's markdown files so that they are consistent with the project's meta.json. It ensures that each step's title (and dashedName) matches the meta's `challengeOrder`. 128 | 129 | #### How to Run the Script 130 | 131 | 1. Change to the directory of the project. 132 | 2. Run the following command: 133 | 134 | ```bash 135 | pnpm run update-step-titles 136 | ``` 137 | 138 | ### repair-meta 139 | 140 | One-off script to parse the step names from the project and update the meta.json order to reflect those steps. Useful if you've accidentally lost the changes to the meta.json file when adding/removing steps. 141 | 142 | #### How to Run the Script 143 | 144 | 1. Change to the directory of the project. 145 | 2. Run the following command: 146 | 147 | ```bash 148 | pnpm run repair-meta 149 | ``` 150 | ## Proposing a Pull Request (PR) 151 | 152 | After you've committed your changes, check here for [how to open a Pull Request](how-to-open-a-pull-request.md). 153 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-work-on-the-component-library.md: -------------------------------------------------------------------------------- 1 | # How to Work on the Component Library 2 | 3 | Welcome to freeCodeCamp's `ui-components` library. The components are built mostly from scratch with basic HTML elements and [Tailwind CSS](https://tailwindcss.com/). 4 | 5 | > [!NOTE] 6 | > 7 | > freeCodeCamp has been using Bootstrap components in the UI. However, we are moving away from it and building our own component library, which helps standardize our UX/UI patterns and improve accessibility. The project is tracked in [this GitHub issue](https://github.com/freeCodeCamp/freeCodeCamp/issues/44668). 8 | 9 | The following steps are recommended when working on a new component: 10 | 11 | - Research and planning 12 | - Implement the component 13 | - Display the use cases on Storybook 14 | - Write unit tests 15 | 16 | ## Researching and Planning 17 | 18 | Before building a component, you need to research and document on how the existing version behaves and looks, to ensure that the new one has matching styles and supports all the current usages. In order to meet the web accessibility requirements, you should also pay attention to the accessibility aspect of the component, see which HTML elements and ARIA attributes are used under the hood. 19 | 20 | Once you have gathered enough information about the component, you can start thinking about the props interface. Ideally, the interface should be as similar to the current version as possible, to ease the adoption later on. Since we are using Bootstrap components, the simplest approach is to mimic [their implementation](https://github.com/react-bootstrap/react-bootstrap/tree/master/src). 21 | 22 | We prefer smaller pull requests rather than a large one, because they speed up the review time and reduce cognitive overload for the reviewers. For that reason, you should think about how you would break down the implementation and come up with a delivery plan. 23 | 24 | We recommend opening a separate GitHub issue for each component and include all the notes in the issue description. It can be used as a place to host all of your working notes, as well as a way to communicate the approach with the reviewers. We will use the issue thread for further discussion if needed. [The issue for Button component](https://github.com/freeCodeCamp/freeCodeCamp/issues/45357) can be used as a reference. 25 | 26 | ## Implementing the Component 27 | 28 | A new component can be created using the following command from the root directory: 29 | 30 | ```bash 31 | cd tools/ui-components 32 | 33 | pnpm run gen-component MyComponent 34 | ``` 35 | 36 | The command will generate a new folder inside the `ui-components` directory, with the following files: 37 | 38 | | File name | Purpose | 39 | | -------------------------- | ---------------------------------------------------------- | 40 | | `index.ts` | It is used for exporting the component and its types. | 41 | | `my-component.stories.tsx` | It is used for demoing the component on Storybook. | 42 | | `my-component.test.tsx` | It is a test file. | 43 | | `my-component.tsx` | It is where we implement the component. | 44 | | `types.ts` | It is where we locate the component's interface and types. | 45 | 46 | Each component is different, but in general, a component should: 47 | 48 | - Support forwarding ref 49 | - Be styled for both light and dark themes 50 | - Be styled internally based on their props (the consumers should not need to restyle the component with the `className` prop) 51 | - Utilize the built-in styling system from Tailwind instead of having custom styles 52 | 53 | ### Using Colors 54 | 55 | There are two color "layers" in the component library: 56 | 57 | - The base layer, where the color names describe what the colors are, e.g. `gray00`, `blue50` 58 | - The semantic layer, where the color names describe what the colors are for, e.g. `foreground-primary`, `background-danger` 59 | 60 | Generally, when using colors in a component, you should choose semantic variables over the base ones. There are exceptions, however, specifically when you are styling the component's states such as hover, active, disabled, etc. In these cases, we recommend using the base variables directly instead of creating new semantic variables, since each component can have different styles for its states. 61 | 62 | > [!NOTE] 63 | > Color definition can be found in the [`colors.css` file](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/tools/ui-components/src/colors.css). A color is only available for use if it is added to the [`tailwind.config.js` file](https://github.com/freeCodeCamp/freeCodeCamp/blob/main/tools/ui-components/tailwind.config.js) under the `colors` property. 64 | 65 | ### Useful Links 66 | 67 | - [Tailwind CSS Configuration](https://tailwindcss.com/docs/configuration) 68 | - [React Bootstrap v0.33 Docs](https://react-bootstrap-v3.netlify.app) 69 | - [Bootstrap 3.3.7 stylesheet](https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css) 70 | - [React Bootstrap current implementation](https://github.com/react-bootstrap/react-bootstrap/tree/master/src) 71 | - [React Bootstrap current tests](https://github.com/react-bootstrap/react-bootstrap/tree/master/test) 72 | 73 | ## Displaying the Use Cases on Storybook 74 | 75 | Use cases of the component should be added to the Storybook file (`.stories.tsx`). 76 | 77 | To start Storybook, run the following command from the root directory: 78 | 79 | ```bash 80 | pnpm run storybook 81 | ``` 82 | 83 | The Storybook page is available on [http://localhost:6006](http://localhost:6006). 84 | 85 | ## Writing Unit Tests 86 | 87 | We use [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/) to write unit tests. The tests should assert that the components behave as expected and are accessible. 88 | 89 | To run tests against the component library, run the following command from the root directory: 90 | 91 | ```bash 92 | pnpm run test-ui-components 93 | ``` 94 | 95 | ## Proposing a Pull Request (PR) 96 | 97 | After you've committed your changes, check here for [how to open a Pull Request](how-to-open-a-pull-request.md). 98 | 99 | ## Adding Packages to the UI-Component Library 100 | 101 | We restrict adding new packages to the UI Components to help with the project's maintainability. In the rare chance that you think a dependency is needed, please check with the maintainers first and then use the following command to add a package: 102 | 103 | ```bash 104 | cd tools/ui-components 105 | pnpm add package_name 106 | ``` 107 | 108 | ## Useful Links 109 | 110 | - [Testing for Accessibility](https://testing-library.com/docs/dom-testing-library/api-accessibility) 111 | - [Order of priority of React Testing Library's queries](https://testing-library.com/docs/queries/about/#priority) 112 | - [Common mistakes with React Testing Library](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library) 113 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-work-on-the-docs-theme.md: -------------------------------------------------------------------------------- 1 | # How to Work on Documentation 2 | 3 | ## Work on the Content of the Docs 4 | 5 | To work on the contributing guidelines, you can edit or add files in the `docs` directory [available here](https://github.com/freeCodeCamp/freeCodeCamp/tree/main/docs). When your changes are merged, they will be made available automatically at the documentation site. 6 | 7 | When adding a new file to the `docs` directory, you should evaluate if the file should also be added to the sidebar navigation. We typically create a link in the [`_sidebar.md`](_sidebar.md) file for new and independent guides. Alternatively, You may follow the instructions below on creating an internal link for supporting guides. 8 | 9 | ### How to Create an Internal Link 10 | 11 | If you want to create a link targeting a different section of the contributing guidelines, follow this format: 12 | 13 | ```md 14 | [Link text](target-file-name.md#target-section-heading-id) 15 | 16 | // If the target section is within the same page, you can omit the file name 17 | [Link text](#target-section-heading-id) 18 | ``` 19 | 20 | Make sure you include the file extension (`.md`). Don't specify the full URL or append `/` before the file name. 21 | 22 | This is necessary to make these links work for the translated version of the document. Otherwise, they will redirect to the English version of the page regardless of the language. 23 | 24 | #### Translating docs with internal links 25 | 26 | When you work on translating docs on Crowdin, make sure to replace the `#target-section-heading-id` with the id on the translated document. [Learn more about translating docs here](how-to-translate-files.md#translate-documentation). 27 | 28 | ## Work on the Docs Theme 29 | 30 | > [!NOTE] 31 | > A quick reminder that you do not need to set up anything for working on the content for the documentation site. 32 | > 33 | > To work on the contributing guidelines, see [work on the docs content](#work-on-the-docs-content) section. 34 | 35 | ### Structure of the Docs Website 36 | 37 | The site is generated using [`docsify`](https://docsify.js.org) and served using GitHub pages. 38 | 39 | Typically you would not need to change any configuration or build the site locally. In case you are interested, here is how it works: 40 | 41 | - The homepage's source for this site is available in [`docs/index.html`](index.html). 42 | - We serve this file as a SPA using `docsify` and GitHub Pages. 43 | - The `docsify` script generates the content of `markdown` files in the `docs` directory on demand. 44 | - The homepage is generated from the [`_coverpage.md`](_coverpage.md). 45 | - The sidebar navigation is generated from [`_sidebar.md`](_sidebar.md). 46 | 47 | ### Serving the Documentation Site Locally 48 | 49 | Install freeCodeCamp locally ([see the local setup guide](how-to-setup-freecodecamp-locally)), we bundled the CLI with the development tools so you can run the command below as needed from the root of the repo: 50 | 51 | ```bash 52 | pnpm run docs:serve 53 | ``` 54 | 55 | > The documentation site should be available at <http://localhost:3400> 56 | 57 | ## Proposing a Pull Request (PR) 58 | 59 | After you've committed your changes, check here for [how to open a Pull Request](how-to-open-a-pull-request.md). 60 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/how-to-work-on-tutorials-that-use-coderoad.md: -------------------------------------------------------------------------------- 1 | This page describes how to contribute to the freeCodeCamp tutorials and projects that are completed using the CodeRoad VS Code extension. 2 | 3 | ## How the Tutorials Work 4 | 5 | Each of the freeCodeCamp tutorials that use CodeRoad has its own repo under the freeCodeCamp GitHub organization. They all start with `learn-`. For example, `https://github.com/freeCodeCamp/learn-bash-by-building-a-boilerplate/`. 6 | 7 | Each tutorial repo has a `main` branch and a "version" branch, e.g. `v1.0.0`. 8 | 9 | The two main files on the `main` branch are `TUTORIAL.md` and `coderoad.yaml`. `TUTORIAL.md` contains all the instructions, hints, titles, and so on, for the tutorial. `coderoad.yaml` contains instructions for CodeRoad, such as what commands to run and when, what files to watch for changes, and what version branch to use for the steps. 10 | 11 | The "version" branch contains the commits that will be loaded on each step of a tutorial. The commit messages on this branch have to be specific. The first commit needs `INIT` for its message and contains all the files to load before the first lesson. 12 | 13 | Subsequent commit messages have to match the step number in `TUTORIAL.md` from the `main` branch. For example, the commit with the message `10.1` will be loaded when a user goes to step `10.1`. 14 | 15 | In order to make changes to commits on a version branch, you would need to rebase and edit the commits you want to change. This will rewrite the Git history, so we cannot accept PRs to these types of branches. Once a version branch is on the freeCodeCamp repo, it should never change. 16 | 17 | > [!WARNING] 18 | > 19 | > Never make or push changes to a version branch that is on one of the freeCodeCamp repos. Always create a new one 20 | 21 | ## How to Contribute 22 | 23 | ### Prerequisites 24 | 25 | Install the [CodeRoad CLI tools](https://www.npmjs.com/package/@coderoad/cli) with `npm install -g @coderoad/cli`. 26 | 27 | There have been some issues with the latest version. If `coderoad --version` doesn't work after installing, downgrade to `0.7.0` with `npm install -g @coderoad/cli@0.7.0`. 28 | 29 | ### Working on `main` 30 | 31 | This set of instructions is for PRs that only make minor changes on `main` to **existing lessons**. That mainly consists of typo, grammar, hint, and instructional changes or fixes in the `TUTORIAL.md` file. 32 | 33 | For everything else, including adding or deleting lessons, follow the [working on a version branch instructions](#working-on-version-branch). You will not need to create a new version branch for this - you can create a PR following the instructions below. 34 | 35 | > [!NOTE] 36 | > 37 | > These changes will use the existing version branch. If they are substantial, feel free to add them to `CHANGELOG.md`. Most of the time, a good commit message should work 38 | 39 | You never need to modify the `tutorial.json` file directly. That will be created with the CLI tools. 40 | 41 | If you are only making minor changes like fixing a typo or grammatical error, you don't have to test your changes. 42 | 43 | Follow these instructions to make a PR, keeping in mind that instructions usually use the lessons around them for context: 44 | 45 | - Create a copy of the latest version branch with `git branch vX.X.X upstream/vX.X.X` - you do not need to check this branch out, it just needs to exist. 46 | - Create and checkout a new branch off of `main` 47 | - Make **and commit** your changes. Reminder: You don't need to change anything in the `tutorial.json` file. You likely only need to make changes to `TUTORIAL.md` 48 | - Run `coderoad build` to recreate the `tutorial.json` file 49 | - Commit the changes with `update json` as the message 50 | - Make a PR 51 | 52 | ### Testing Changes on `main` 53 | 54 | If you want to test your changes to `main` after using the above instructions, follow these instructions: 55 | 56 | - Follow the instructions on the [rdb-alpha repo](https://github.com/freeCodeCamp/rdb-alpha) to run a container 57 | - Start the tutorial using the `tutorial.json` file on the new branch 58 | 59 | ### Reviewing PRs to `main` 60 | 61 | If reviewing a PR that only changes `main` with instructional or grammar issues as described above, the changes in `TUTORIAL.md` should match the changes in `tutorial.json`. 62 | 63 | The `tutorial.json` file should not have changes to commit hashes, or step/level ids. Startup or level commands or file watchers likely should not be changed either. There are exceptions if there's an issue with a step, but they should be treated with more caution. 64 | 65 | Also, keep in mind that instructions usually use the lessons around them for context, so make sure they make sense. 66 | 67 | ### Working on Version Branch 68 | 69 | > [!WARNING] 70 | > 71 | > Reminder: Never make or push changes to a version branch that is on one of the freeCodeCamp repos. Always create a new one 72 | 73 | There's no easy way to see exactly what changed between version branches since the Git history will be rewritten. Accepting new version branches to use will need to be done with careful consideration and testing. 74 | 75 | These instructions are for changing anything on a "version" branch, such as tests, test text, reset files, adding and deleting steps, among other things. 76 | 77 | Follow these instructions to create a new version: 78 | 79 | - Checkout the **latest** version branch with `git checkout -b vX.X.X upstream/vX.X.X` 80 | - Create a new branch off of that, incrementing the version, with `git checkout -b vX.X.Y` 81 | - Make your changes to the version branch. See more info in the [CodeRoad Documentation](https://coderoad.github.io/docs/edit-tutorial) for how to work with tutorials 82 | - Push the new branch to your fork with `git push -u origin vX.X.Y` 83 | - Checkout the `main` branch 84 | - Create a new branch off `main`. e.g. `feat/version-X.X.Y` 85 | - Change the `uri` in `coderoad.yaml` to your fork of the repo. This is so you and reviewers can test it before pushing it to the freeCodeCamp repo. Change the version to the new branch in the two spots of that file. Add your changes for the new version to `CHANGELOG.md`. Make any other changes you need. 86 | - Commit your changes with the message `feat: release version X.X.Y - <optional description>` 87 | - Run `coderoad build` to create a new `tutorial.json` file 88 | - Add and commit the file 89 | - Push the changes to your fork 90 | - Test your changes following the [testing instructions below](#testing-changes-to-a-version-branch). Make any additional changes and commit them as you just did, or, if you are satisfied, follow the rest of the instructions 91 | - Make a PR to `main` using your new `feat/version-X.X.Y` branch. Give it a title of `version X.X.Y ready for review`. This will not be merged, it is just to let reviewers know that there is a new version ready 92 | - Leave it here for reviewers 93 | 94 | ### Testing Changes to a Version Branch 95 | 96 | - Follow the instructions on the [rdb-alpha repo](https://github.com/freeCodeCamp/rdb-alpha) to run a container 97 | - Start the tutorial using the `tutorial.json` file on whatever fork the changes are on. Make sure to use the file on the `feat: version-X.X.Y` branch and not the `main` branch 98 | 99 | ### Pushing a New Version 100 | 101 | Before pushing a new version, view the new `feat/version-vX.X.Y` (will be merged to `main`) branch on the user's fork. Make sure there are additions to the `CHANGELOG.md` file that include the new changes, and the version in the two spots of `coderoad.yaml` matches the new version branch. 102 | 103 | If you have write access to the freeCodeCamp repo, have verified the `CHANGELOG` and `coderoad.yaml` files, have tested the changes using the instructions above, and want to push a new version of a tutorial: 104 | 105 | > [!WARNING] 106 | > 107 | > Reminder: Never make or push changes to a version branch that is on one of the freeCodeCamp repos. Always create a new one 108 | 109 | - If you don't have a remote to where the new changes exist, create a remote to the user's fork with `git remote add <users_fork>` 110 | - Delete any **local** branches that share a name with the new branches. Likely named either `vX.X.Y` or `feat/version-X.X.Y` 111 | - Checkout the new version branch with `git checkout -b vX.X.Y <remote>/vX.X.Y` 112 | - Push the new version branch to the freeCodeCamp repo with `git push -u upstream/vX.X.Y`. You need to push the new branch before you update `main` with the new `tutorial.json` file 113 | - Checkout the users branch that will be merged into `main` with `git checkout -b feat/version-X.X.Y <remote>/feat/version-X.X.Y` 114 | - Change the `uri` in `coderoad.yaml` back to the freeCodeCamp repo 115 | - Add and commit the changes 116 | - Run `coderoad build` to create the new `tutorial.json` file 117 | - Add and commit the file 118 | - Push the changes to your fork with `git push -u origin/feat/version-X.X.Y` 119 | - Make a PR to `main` on the freeCodeCamp repo 120 | - If you are satisfied, merge it or leave it and ask for a review from someone 121 | - After the PR is merged, open the tutorial by following the instructions on the [rdb-alpha repo](https://github.com/freeCodeCamp/rdb-alpha) to make sure it's loading properly, and that you can get through a few steps 122 | - Finally, if any PRs for this version exist, close them 123 | 124 | ### How to Revert to a Previous Version 125 | 126 | - Create a new branch off of the latest `main` with `git checkout -b revert/to-version-X.X.X` 127 | - Revert all commits on this branch up to and including the commit of the version after the one you want to revert to. For example, you may have commits that look like this: 128 | 129 | ``` 130 | fix: typo 131 | release: version 1.0.1 132 | fix: typo 133 | release: version 1.0.0 134 | ``` 135 | 136 | If you want to revert to v1.0.0, revert all the commits from `release: version 1.0.1` and after 137 | 138 | - Create a PR. Give it a title of `revert: to version X.X.X` 139 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/index.md: -------------------------------------------------------------------------------- 1 | The [freeCodeCamp.org](https://freecodecamp.org) community is possible thanks to thousands of kind volunteers like you. If you want to contribute your time and expertise, we would be excited to welcome you aboard. 2 | 3 | > [!NOTE] 4 | > Before you proceed, please take a quick 2 minutes to read our [Code of Conduct](https://www.freecodecamp.org/code-of-conduct). We strictly enforce it across our community so that contributing to freeCodeCamp.org is a safe, inclusive experience for everyone. 5 | 6 | You are welcome to create, update and fix bugs in our [curriculum](#curriculum), help us fix bugs in freeCodeCamp.org's [learning platform](#learning-platform), or [help us translate](#translations) freeCodeCamp.org to world languages. 7 | 8 | We answer the most common questions about contributing [in our contributor FAQ](FAQ.md). 9 | 10 | Happy contributing. 11 | 12 | --- 13 | 14 | ## Curriculum 15 | 16 | Our curriculum is curated by the global freeCodeCamp community. This way, we are able to incorporate expert knowledge from volunteers like you. 17 | 18 | You can help expand and improve the curriculum. You can also update project user stories to better-explain concepts. And you can improve our automated tests so that we can more accurately test people's code. 19 | 20 | **If you're interested in improving our curriculum, here's [how to contribute to the curriculum](how-to-work-on-coding-challenges.md).** 21 | 22 | ## Translations 23 | 24 | We are localizing freeCodeCamp.org to major world languages. 25 | 26 | Certifications are already live in some major world languages like below: 27 | 28 | - [Chinese (中文)](https://www.freecodecamp.org/chinese/learn) 29 | - [Spanish (Español)](https://www.freecodecamp.org/espanol/learn) 30 | - [Italian (Italiano)](https://www.freecodecamp.org/italian/learn) 31 | - [Portuguese (Português)](https://www.freecodecamp.org/portuguese/learn) 32 | - [Ukrainian (Українська)](https://www.freecodecamp.org/ukrainian/learn) 33 | - [Japanese (日本語)](https://www.freecodecamp.org/japanese/learn) 34 | - [German (Deutsch)](https://www.freecodecamp.org/german/learn) 35 | 36 | We encourage you to read the [announcement here](https://www.freecodecamp.org/news/help-translate-freecodecamp-language/) and share it with your friends to get them excited about this. 37 | 38 | **If you're interested in translating, here's [how to translate freeCodeCamp's resources](how-to-translate-files.md).** 39 | 40 | ## Learning Platform 41 | 42 | Our learning platform runs on a modern JavaScript stack. It has various components, tools, and libraries. These include Node.js, MongoDB, OAuth 2.0, React, Gatsby, Webpack, and more. 43 | 44 | Broadly, we have a Node.js based API server, a set of React-based client applications, testing scripts to evaluate camper-submitted curriculum projects, and more. If you want to productively contribute to the learning platform, we recommend some familiarity with these tools. 45 | 46 | **If you want to help us improve our codebase here's [how to set up freeCodeCamp](how-to-setup-freecodecamp-locally.md).** 47 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/language-lead-handbook.md: -------------------------------------------------------------------------------- 1 | # The Official freeCodeCamp Language Lead Handbook 2 | 3 | This handbook will help you set up and use the tools for your localization efforts. 4 | 5 | ## How to Invite New Contributors to Ghost 6 | 7 | Ghost allows you to set contributors with different levels of authorization. 8 | 9 | Most of your invites will be for the "Contributor" level. This level allows the user to create drafts. Select this role when inviting a new translator. 10 | 11 | The "Author" level allows the user to create Drafts and publish them. 12 | 13 | The "Editor" level allows the user to access all Drafts and publish them. Select this role when inviting a new proofreader. 14 | 15 | The "Administrator" level is reserved for freeCodeCamp staff and Language Leads. 16 | 17 | ### How are the Articles Built 18 | 19 | We use a [JAMStack](https://www.google.com/search?q=what+is+jamstack)-based approach to build and deploy the articles. This strategy makes for a speedy static site cached and served from a CDN. 20 | 21 | [Ghost](https://ghost.org) acts as our content management platform, and [11ty](https://11ty.dev) builds the articles into static assets – plain HTML, JavaScript, and CSS. Only these static assets are deployed to our servers. 22 | 23 | This process is automated and runs periodically. If you publish something now, it will be available on the news site in a few hours. 24 | 25 | You can find the up-to-date build schedules and status here: https://github.com/freeCodeCamp/news#build 26 | 27 | ## How to Mention the Original Author of a Translated Article 28 | 29 | The original author and the original article are linked automatically adding this code to the Code Injection -> head section in the Draft Settings on Ghost. 30 | 31 | ```html 32 | <script> 33 | const fccOriginalPost = 'link'; 34 | </script> 35 | ``` 36 | 37 | With `link` being the link of the original article. 38 | 39 | ## How to Update Trending Articles 40 | 41 | > [!TIP] 42 | > Changing the articles in the footer at least once a month means giving a boost to the linked articles on Google results. 43 | 44 | To update the trending articles in the footer, you need to update the [yaml file in the CDN repository](https://github.com/freeCodeCamp/cdn/tree/main/build/universal/trending) for your language. Both the curriculum and the publication reference this file. 45 | 46 | For example, here is the file content for the first 6 articles: 47 | 48 | ```yaml 49 | article0title: 'Unire CSV con Python' 50 | article0link: 'https://www.freecodecamp.org/italian/news/come-combinare-file-multipli-in-formato-csv-con-8-righe-di-codice/' 51 | article1title: 'Il comando Git push' 52 | article1link: 'https://www.freecodecamp.org/italian/news/il-comando-git-push-spiegato/' 53 | article2title: 'Centrare immagini in CSS' 54 | article2link: 'https://www.freecodecamp.org/italian/news/come-centrare-un-immagine-usando/' 55 | article3title: 'I codici Alt' 56 | article3link: 'https://www.freecodecamp.org/italian/news/codici-alt/' 57 | article4title: 'Tenere a bada il footer' 58 | article4link: 'https://www.freecodecamp.org/italian/news/come-mantenere-il-footer-al-suo-posto/' 59 | article5title: 'Cosa è API?' 60 | article5link: 'https://www.freecodecamp.org/italian/news/cose-un-api-in-italiano-per-favore/' 61 | ``` 62 | 63 | Each number represents one of the 30 articles in the footer. Make sure to match the title and the link correctly. 64 | 65 | For each article, you will need to create a shorter title to use in the footer. Each title must stay on a single line and not go to a new line. 66 | 67 | You will want to [build the translated client locally](how-to-enable-new-languages.md) to see if the titles have the right length. You can preview the changes by editing the `trending.json` file in your local environment: 68 | 69 | 1. Update your `.env` file to use your language for `CLIENT_LOCALE` and `CURRICULUM_LOCALE`. 70 | 71 | 2. Run `pnpm run create:shared`. This will automatically generate the `trending.json` file for your language under the `/client/i18n/locales/` directory. 72 | 73 | 3. Start the server by running `pnpm run develop:server` in one terminal window. 74 | 75 | 4. Edit the `trending.json` to contain the titles you want to preview. You may want to convert your `.yaml` file into JSON format with an automatic tool. 76 | 77 | 5. In another terminal window, run `pnpm run clean:client`, and then `pnpm run develop:client` 78 | 79 | ## How to Translate Articles in the Footer Links 80 | 81 | There are some links listed at the bottom of the footer (About, Alumni Network, Open Source, etc.) and some of them can be translated into your language in the same way as other articles. 82 | 83 | Articles that can be translated: 84 | 85 | - About 86 | - Support 87 | - Academic Honesty 88 | - Code of Conduct 89 | 90 | The following articles should **not** be translated: 91 | 92 | - Shop 93 | - Sponsors 94 | - Privacy Policy 95 | - Terms of Service 96 | - Copyright Policy 97 | 98 | The following links are pointing to external sites and cannot be translated: 99 | 100 | - Alumni Network 101 | - Open Source 102 | 103 | ### Change the Footer Links in the News 104 | 105 | Once you have translated and published the articles listed as "can be translated" above, you can update the links in the footer for `/news` by editing the file at `news/config/i18n/locales/<your language>/links.json` in the [freeCodeCamp/news](https://github.com/freeCodeCamp/news) repository. 106 | 107 | > [!NOTE] 108 | > Pull requests to this repository are currently limited to staff only. If you want to update this file, ask someone on the staff team for help. 109 | 110 | Update the following part in the file: 111 | 112 | ```json 113 | { 114 | ... 115 | "footer": { 116 | "about": "https://www.freecodecamp.org/news/about/", 117 | "support": "https://www.freecodecamp.org/news/support/", 118 | "honesty": "https://www.freecodecamp.org/news/academic-honesty-policy/", 119 | "coc": "https://www.freecodecamp.org/news/code-of-conduct/" 120 | } 121 | } 122 | ``` 123 | 124 | ### Change the Footer Links in the Curriculum 125 | 126 | When you have translated and published the articles listed as "can be translated" above, as well as when the curriculum in your language is ready for launch, you can update the links in the footer for `/learn` by editing the file at `client/i18n/locales/<your language>/links.json` in the [freeCodeCamp/freeCodeCamp](https://github.com/freeCodeCamp/freeCodeCamp) repository. 127 | 128 | > [!WARNING] 129 | > Only "About", "Support", "Academic Honesty", and "Code of Conduct" can be translated. Leave other URLs unchanged. 130 | 131 | Update the following part in the file: 132 | 133 | ```json 134 | { 135 | ... 136 | "footer": { 137 | "about-url": "https://www.freecodecamp.org/news/about/", 138 | "shop-url": "https://www.freecodecamp.org/shop/", 139 | "support-url": "https://www.freecodecamp.org/news/support/", 140 | "sponsors-url": "https://www.freecodecamp.org/news/sponsors/", 141 | "honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/", 142 | "coc-url": "https://www.freecodecamp.org/news/code-of-conduct/", 143 | "privacy-url": "https://www.freecodecamp.org/news/privacy-policy/", 144 | "tos-url": "https://www.freecodecamp.org/news/terms-of-service/", 145 | "copyright-url": "https://www.freecodecamp.org/news/copyright-policy/" 146 | }, 147 | ... 148 | } 149 | ``` 150 | 151 | ## How to Translate the Info Boxes Headers in the Documentation 152 | 153 | You can find these boxes all around the documentation: 154 | 155 | > [!NOTE] 156 | > I am a note box 157 | 158 | > [!TIP] 159 | > I am a tip box 160 | 161 | > [!WARNING] 162 | > I am a warning box 163 | 164 | > [!ATTENTION] 165 | > I am an attention box 166 | 167 | By default, their headers appear in English even in the translated docs. 168 | 169 | You can have the headers translated in the docs in your language by changing the file `docs/index.html`, in this way: 170 | 171 | Inside the `script` element there is an object, find the `flexibleAlerts` property, which has this shape: 172 | 173 | ```js 174 | flexibleAlerts: { 175 | note: { 176 | label: { 177 | '/': 'Note' 178 | } 179 | }, 180 | tip: { 181 | label: { 182 | '/': 'Tip' 183 | } 184 | }, 185 | warning: { 186 | label: { 187 | '/': 'Warning' 188 | } 189 | }, 190 | attention: { 191 | label: { 192 | '/': 'Attention' 193 | } 194 | } 195 | } 196 | ``` 197 | 198 | Inside the object of the label property, before the `'/'` property, you would add a new property for your language, like `/i18n/<language>/`. 199 | 200 | For example, adding the translations for Portuguese would appear like this: 201 | 202 | ```js 203 | flexibleAlerts: { 204 | note: { 205 | label: { 206 | '/i18n/portuguese/': 'Observação', 207 | '/': 'Note' 208 | } 209 | }, 210 | tip: { 211 | label: { 212 | '/i18n/portuguese/': 'Dica', 213 | '/': 'Tip' 214 | } 215 | }, 216 | warning: { 217 | label: { 218 | '/i18n/portuguese/': 'Aviso', 219 | '/': 'Warning' 220 | } 221 | }, 222 | attention: { 223 | label: { 224 | '/i18n/portuguese/': 'Atenção', 225 | '/': 'Attention' 226 | } 227 | } 228 | } 229 | ``` 230 | 231 | ## How to Translate the Motivational Quotes 232 | 233 | The motivational quotes can be found in the [curriculum repository](https://github.com/freeCodeCamp/freeCodeCamp/) in the `/client/i18n/locales/<language>/motivation.json` file. 234 | 235 | This file has a general structure of: 236 | 237 | ```json 238 | { 239 | "compliments": [], 240 | "motivationalQuotes": [] 241 | } 242 | ``` 243 | 244 | The compliments are the short sentences that appear at the completion of a challenge. 245 | 246 | You don't need to directly translate the sentences used in English, you can write a set of short sentences that are appropriate to show at the completion of a challenge. 247 | 248 | The `compliments` array is an array of strings. So, for example, you would write: 249 | 250 | ```json 251 | { 252 | "compliments": ["A tutta birra!", "Pikachu, scelgo te!"], 253 | "motivationalQuotes": [] 254 | } 255 | ``` 256 | 257 | > [!TIP] 258 | > You should start with at least a dozen compliments to have some variety when users complete challenges. 259 | 260 | The motivational quotes are the quotes that appear at https://freecodecamp.org/learn. 261 | 262 | The `motivationalQuotes` array is an array of objects, these objects should include a `quote` property and an `author` property. like this: 263 | 264 | ```json 265 | { 266 | "compliments": [], 267 | "motivationalQuotes": [ 268 | { 269 | "quote": "Se i costruttori costruissero come i programmatori programmano, il primo picchio che passa potrebbe distruggere la civiltà.", 270 | "author": "Artur Bloch, Seconda legge di Weinberg" 271 | }, 272 | { 273 | "quote": "I bravi programmatori sanno cosa scrivere. I migliori sanno cosa riscrivere.", 274 | "author": "Eric Steven Raymond" 275 | } 276 | ] 277 | } 278 | ``` 279 | 280 | > [!TIP] 281 | > You should start with at least a dozen quotes, to have some variety. A new quote is shown every time the user reloads the page. 282 | 283 | ## How to Update the Common Links 284 | 285 | We maintain a file of common links used throughout our [curriculum site](https://github.com/freecodecamp/freecodecamp) in the `/client/i18n/locales/<language>/links.json` file. 286 | 287 | Some of these links will not change - but you should update the `/news` article links to point to your language's translated version of that article when it is published. 288 | 289 | You should also update the `help` categories to point to your language's subforum (usually `language/category`, like `Italiano/HTML-CSS`). This will allow campers to create "help posts" in the correct forum location. 290 | 291 | ## How to Update the Site Meta-Data 292 | 293 | The site meta-data is in the `/client/i18n/locales/<language>/meta-tags.json` file. This file has five keys: `title`, `description`, `social-description`, `keywords`, and `youre-unsubscribed`. 294 | 295 | The `youre-unsubscribed` value should be directly translated. The other values will need to be translated as closely as possible, while also considering common search terms and phrases used in your language. 296 | 297 | If you need help with this, reach out to us in the [contributor chat](https://discord.gg/PRyKn3Vbay) 298 | 299 | ## Pre-Translate Workflow on Crowdin 300 | 301 | The Pre-Translate workflow can be used to apply translations from the Translation Memory to strings. 302 | 303 | > [!TIP] 304 | > Really useful to restore a lot of translations from the Translation Memory in bulk when a lot of files have been updated. 305 | 306 | You can find the Pre-Translation workflow at the top of the page in the console of a project. 307 | If you see "Go to console" in the upper right corner, click there first. 308 | 309 | ![go to console button](./images/crowdin/pre-translate2.png) 310 | 311 | ![pre-translate workflow](./images/crowdin/pre-translate1.png) 312 | 313 | You can choose "From Machine Translation" or "From Translation Memory". Choose "Translation Memory" to recover translations from memory. 314 | 315 | Then there are three steps to complete: 316 | 317 | 1. Files. Choose which files to translate, you can do all the projects, or specific folders or files. 318 | 2. Languages. Set your language here. 319 | 3. Existing Translations. The best combination here is "100% match" and "Apply to untranslated strings only". Do not approve automatically, as it's always best to have a human eye on things. 320 | 321 | ![pre-translate existing translations](./images/crowdin/pre-translate3.png) 322 | 323 | When you have finished setting this, press the Pre-Translate button and wait. It will alert you once it has finished. The time it takes depends on how many untranslated strings are in the chosen files. 324 | 325 | ## How to Update Crowdin Glossary 326 | 327 | > [!TIP] 328 | > An updated glossary helps in having a homogeneous translation of technical terms. 329 | 330 | The Crowdin Glossary is kept in the [crowdin-glossaries](https://github.com/freeCodeCamp/crowdin-glossaries) repository. 331 | 332 | In the `glossaries` folder, there are various `*.csv` (comma,separated values) files, one for each of the crowdin projects that have a glossary that can be updated from this workflow. 333 | 334 | The `client.csv` file is for the Learn User Interface project, the `curriculum.csv` file is for the Coding Curriculum project, the `docs.csv` file is for the Contributing Documentation project. 335 | 336 | To update the Crowdin Glossaries, you need to clone this repo locally. Open the `.csv` file with an appropriate program, for example, Microsoft Excel. 337 | 338 | In the `.csv` file you will find that the English language occupies the first three columns, `Term:English` is the column for the English term, `Description:English` is the column for the English description, and `Part:English` is for the part of speech (e.g., noun, verb etc.) of the term. 339 | 340 | Then, each target language has two columns. If you translate to Dothraki, you will be interested in the columns `Term:Dothraki` and `Description:Dothraki`. The column `Term:Dothraki` is for the translation of the term in Dothraki, and the column `Description:Dothraki` is for a description of the term in Dothraki. 341 | 342 | > [!TIP] 343 | > In programs like Microsoft Excel, you can hide the columns of the other languages to free up screen real-estate and see the English columns and the target language columns near each other. 344 | 345 | After you have made the changes and saved the file, you will need to make a PR with the proposed changes. After the PR is accepted, you will need to run the GitHub Action workflow to update the Crowdin Glossary. Your glossary changes will not have immediate effects, but they will come. 346 | 347 | ## How to Promote a Contributor to Proofreader 348 | 349 | If you consider that a contributor could become a Crowdin Proofreader, you can give the proofreader role to them this way: 350 | 351 | In Crowdin, individuate the `User management` on the left-hand side menu. 352 | 353 | This will open the user management tools, you will be able to see the list of all the users. 354 | 355 | Search for the user who will become a proofreader. Use the three dots menu on the user row to open a menu and select "Add to team". The proofreader teams have a standard name of `Proof Readers (<language>)`, you can search the team using the language name. Once you have selected the team, use the "ADD" button at the bottom of the page to finalize the thing. 356 | 357 | The user is now a proofreader. 358 | 359 | > [!TIP] 360 | > The newly promoted proofreader could benefit from reading the [How to Proofread Files](how-to-proofread-files.md) documentation. 361 | 362 | ## How to Add or Update a Language 363 | 364 | Check out the [how to enable new language](how-to-enable-new-languages.md) docs. If you are updating a language the section on [set translated superblocks](how-to-enable-new-languages.md#set-translated-superblocks) should be helpful. 365 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/moderator-onboarding-guide.md: -------------------------------------------------------------------------------- 1 | # The Official freeCodeCamp Moderator Onboarding Guide 2 | 3 | This guide will help new moderators get up and running with the processes and procedures followed by experienced moderators on the freeCodeCamp community forum and other official communities we foster. 4 | 5 | > [!NOTE] 6 | > If you haven't read [The Moderator Handbook](https://contribute.freecodecamp.org/#/moderator-handbook) yet, you should start there first. 7 | 8 | ## The Forum 9 | 10 | ### First Steps 11 | 12 | The first thing you may notice after being given moderator status on the forum is that your interface will look somewhat different, with new admin tools to explore and access to the Mod-Team subforum. 13 | 14 | Some of the new tools will appear inside a new menu item that looks like a wrench. Some will appear as new tabs or buttons, or even new enabled options within the forum menus. 15 | 16 | To get familiar with the new tools and powers, you can combine one or more of the following methods during your first week with this elevated role: 17 | 18 | > [!TIP] 19 | > The first two are the most important. 20 | 21 | ### Become Familiar with the Discourse Admin Tools 22 | 23 | The freeCodeCamp forum is a Discourse forum and follows many of the same guidelines of other forums built on Discourse. To begin to get familiar with Discourse and the moderation role, start by reading Discourse's [new user guide](https://meta.discourse.org/t/discourse-new-user-guide/96331) and Discourse's [new moderator guide](https://meta.discourse.org/t/discourse-moderation-guide/63116). 24 | 25 | ### Shadow a Mod 26 | 27 | All moderator actions can be followed by reviewing the [action logs](https://forum.freecodecamp.org/admin/logs/staff_action_logs). The actions taken by automated tools like `Akismet` or `system` can mostly be ignored until they result in a post that needs to be reviewed. Posts to be reviewed will show up in the [Review](https://forum.freecodecamp.org/review) area of the forum. 28 | 29 | For the first week or so you will want to pay attention to what is getting flagged and what is being reviewed, and compare that to the actions being taken upon the flagged posts. You may see the system account flag a post because the user created it too quickly. In many cases, the moderators will unflag the post by clicking on the "Approve Post" button or mark it as "Not Spam" (depending on the flag type). 30 | 31 | Commonly, spam flags can also be raised by members or moderators. Common duplicitous behavior would involve opening an account, making a post that seems harmless, then editing that post later on to add a link to an external site to advertise it. In this case, the member account is usually fairly new and has only made this one post thus far, which indicates that the account was opened solely for spamming the community. The decision should be made to delete the account after the first offense in this case. The same applies to accounts whose first post is deemed to be spam. 32 | 33 | You may notice moderators performing a procedure called 'split topic'. This may be a case where a moderator has split a post that was made erroneously on an existing topic into a new topic, or a moderator merged duplicate topics that a single user has created for the same question. Watching this procedure will highlight different actions and their causes. 34 | 35 | Another useful feature that becomes enabled for all moderators is the ability to post a "Canned Reply" which is a pre-written response that was worked out with the mod team to quickly respond to some well-known and repetitive scenarios. These include: 36 | 37 | - Welcoming a new forum member who has posted code without a question -> "Welcome - remind question" 38 | - Reminding members not to post code solutions but to provide hints and tips instead -> "Solutions Instead of Help" 39 | - Responding to a situation where someone's code works for you but not for them -> "Browser Issues" 40 | - Encouraging members to open GitHub issues when a possible bug is found -> "Bug Report" 41 | 42 | There are more, which you can read through to become familiar with their respective uses. You can also find discussions around the templates in the mod-team subforum, and you are welcome to ask questions if you aren't sure how a template should be used. 43 | 44 | ### Read Mod-Team Subforum Posts 45 | 46 | The Mod-Team subforum contains several posts from past and current moderators discussing the different requirements and/or challenges of moderating the forum. 47 | 48 | Reading back through these posts can help uncover some of the underlying goals and processes that concern forum moderators. Some of the threads may also shed some light on the handling of spam and inappropriate content on the forum. 49 | 50 | ## Where to Ask for Help 51 | 52 | To get help dealing with a situation that you are either uncomfortable with or unsure of how to handle, discuss with your fellow moderators on either the [Mod-Team Subforum](https://forum.freecodecamp.org/c/mod-team/4) or the [#mod-chat](https://discord.com/channels/692816967895220344/693157007418720277) on Discord. -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/reply-templates.md: -------------------------------------------------------------------------------- 1 | # Reply Templates 2 | 3 | These are some of the standard reply templates that you may use while reviewing pull requests and triaging issues/pull requests. 4 | 5 | > You can make your own saved replies with GitHub's built-in [saved replies](https://github.com/settings/replies/) feature or use the ones below. 6 | 7 | ## Thank You 8 | 9 | ```markdown 10 | Thank you for your contribution to the page! 👍 11 | We are happy to accept these changes and look forward to future contributions. 🎉 12 | ``` 13 | 14 | ## Thank you and congrats 15 | 16 | > For thanking and encouraging first-time contributors. 17 | 18 | ```markdown 19 | Hi @username. Congrats on your first pull request (PR)! 🎉 20 | 21 | Thank you for your contribution to the page! 👍 22 | We are happy to accept these changes and look forward to future contributions. 📝 23 | ``` 24 | 25 | ## Build Error 26 | 27 | ```markdown 28 | Hey @username 29 | 30 | We would love to be able to merge your changes but it looks like there is an error with the CI build. ⚠️ 31 | 32 | Once you resolve these issues, we will be able to review your PR and merge it. 😊 33 | 34 | --- 35 | 36 | Feel free to reference the [contributing guidelines](https://contribute.freecodecamp.org/#/how-to-work-on-coding-challenges.md?id=testing-challenges) for instructions on running the CI build locally. ✅ 37 | ``` 38 | 39 | ## Syncing Fork 40 | 41 | > When PR is not up to date with the `main` branch. 42 | 43 | ````markdown 44 | Hey @username 45 | 46 | We would love to be able to merge your changes, but it looks like the branch is not up to date. ⚠️ 47 | 48 | To resolve this error, you will have to sync the latest changes from the `main` branch of the `freeCodeCamp/freeCodeCamp` repo. 49 | 50 | Using the command line, you can do this in three easy steps: 51 | 52 | ```bash 53 | git remote add upstream git://github.com/freeCodeCamp/freeCodeCamp.git 54 | 55 | git fetch upstream 56 | 57 | git pull upstream main 58 | ``` 59 | 60 | If you're using a GUI, you can simply `Add a new remote...` and use the link `git://github.com/freeCodeCamp/freeCodeCamp.git` from above. 61 | 62 | Once you sync your fork and pass the build, we will be able to review your PR and merge it. 😊 63 | 64 | --- 65 | 66 | Feel free to reference the ["Syncing a fork"](https://help.github.com/articles/syncing-a-fork/) article on GitHub for more insight on how to keep your fork up-to-date with the upstream repository. 🔄 67 | ```` 68 | 69 | ## Merge Conflicts 70 | 71 | > When PR has merge conflicts that need to be resolved.¹ 72 | 73 | ```markdown 74 | Hey @username 75 | 76 | We would love to be able to merge your changes, but it looks like you have some merge conflicts. ⚠️ 77 | 78 | Once you resolve these conflicts, we will be able to review your PR and merge it. 😊 79 | 80 | --- 81 | 82 | If you're not familiar with the merge conflict process, feel free to look over GitHub's guide on ["Resolving a merge conflict"](https://help.github.com/articles/resolving-a-merge-conflict-on-github/). 🔍️ 83 | 84 | Also, it's good practice on GitHub to write a brief description of your changes when creating a PR. 📝 85 | ``` 86 | 87 | ¹ If a first-time-contributor has a merge conflict, maintainers will resolve the conflict for them. 88 | 89 | ## Duplicate 90 | 91 | > When PR is repetitive or a duplicate. 92 | 93 | ```markdown 94 | Hey @username 95 | 96 | This PR seems to make similar changes as the existing PR <#number>. As such, we are going to close this as a duplicate. 97 | 98 | If you feel you have additional changes to expand upon this PR, please feel free to push your commits and request this PR be reopened. 99 | 100 | Thanks again! 😊 101 | 102 | --- 103 | 104 | If you have any questions, feel free to ask questions on the ["Contributors" category on our forum](https://forum.freecodecamp.org/c/contributors) or [the contributors chat room](https://discord.gg/PRyKn3Vbay). 105 | ``` 106 | 107 | ## Closing Invalid Pull Requests 108 | 109 | > When PR is invalid. 110 | 111 | ```markdown 112 | Hey @username 113 | 114 | Thank you for opening this pull request. 115 | 116 | This is a standard message notifying you that we've reviewed your pull request and have decided not to merge it. We would welcome future pull requests from you. 117 | 118 | Thank you and happy coding. 119 | ``` 120 | 121 | > When PR adds links to external resources. 122 | 123 | ```markdown 124 | Thank you for your pull request. 125 | 126 | We are closing this pull request. Please suggest links and other details to add the challenge's corresponding guide post through [a forum topic](https://forum.freecodecamp.org/new-topic?category=Contributors&title=&body=**What%20is%20your%20hint%20or%20solution%20suggestion%3F**%0A%0A%0A%0A%0A**Challenge%3A**%0A%0A%0A**Link%20to%20the%20challenge%3A**) instead. 127 | 128 | If you think we're wrong in closing this issue, please request for it to be reopened and add further clarification. Thank you and happy coding. 129 | ``` 130 | 131 | ## Adding Comment About Newbie Mistakes 132 | 133 | ```markdown 134 | Hello, 135 | 136 | Firstly, thank you for submitting this pull request! 137 | 138 | As you navigate through the process, we have a PR checklist to ensure consistency and quality in our contributions. We kindly ask that you genuinely follow through with each point. This not only facilitates the review process but also demonstrates a mutual respect for the community's efforts. 139 | 140 | If you're unfamiliar with certain aspects, our [contributing guidelines](https://contribute.freecodecamp.org) are a helpful resource to get you up to speed. 141 | 142 | <details> 143 | <summary>**Friendly Pointers (click to expand)**</summary> 144 | 145 | 1. **Editing on GitHub:** While it's possible to edit files directly on GitHub, it's typically better not to. This helps avoid inadvertent mistakes like typos that can disrupt tests. 146 | 147 | 2. **Linking Issues:** Please ensure you link issues using the designated method. Simply update the `XXXXXX` in the PR description to include the issue number. This keeps our records organized and clear. 148 | 149 | 3. **Engaging with the Team:** We know you're eager, but kindly keep mentions and review requests limited. Our maintainers are always on the lookout and will attend to PRs in the order they come in. 150 | 151 | 4. **Branch Management:** It's a good practice not to work directly off your `main` branch. Creating separate branches for different changes allows you to smoothly update your PR even as the main repository progresses. 152 | 153 | </details> 154 | 155 | Please note, there's no need to close this PR. If you have questions or need guidance refining your contribution, don't hesitate to ask. Our community is here to assist. 156 | 157 | Thank you for your enthusiasm in contributing to our project. We eagerly await more contributions from you! 158 | 159 | **Happy Contributing!** 🌟 160 | ``` 161 | 162 | ## Issue Not Triaged 163 | 164 | > When a PR is opened for an issue that hasn't been triaged and marked as ready for contribution. 165 | 166 | ```markdown 167 | Hi there, 168 | 169 | Thanks for creating this pull request. 170 | 171 | The linked issue has not been triaged yet, and a solution has not been agreed upon. Once the issue is open for contribution, you are welcome to update this pull request to reflect the issue consensus. Until the issue is open for contribution, we will not be able to review your pull request. 172 | ``` 173 | 174 | ## Closing Invalid Issues 175 | 176 | > When an issue relates to the camper's code. 177 | 178 | ```markdown 179 | Thank you for reporting this issue. 180 | 181 | This is a standard message notifying you that this issue seems to be a request for help. Instead of asking for help here, please click the **"Get Help"** button on the challenge on freeCodeCamp and choose the **"Ask for help"** option, which will help you create a question in the right part of the forum. Volunteers on the forum usually respond to questions within a few hours and can help determine if there is an issue with your code or the challenge's tests. 182 | 183 | If the forum members determine there is nothing wrong with your code, you can request this issue to be reopened. 184 | 185 | Thank you and happy coding. 186 | ``` 187 | 188 | > When an issue is a duplicate of an earlier issue. 189 | 190 | ```markdown 191 | Thank you for reporting this issue. 192 | 193 | This is a standard message notifying you that this issue appears to be very similar to issue #XXXXX, so we are closing it as a duplicate. 194 | 195 | If you think we're wrong in closing this issue, please request for it to be reopened and add further clarification. Thank you and happy coding. 196 | ``` 197 | 198 | > When an issue is fixed in staging. 199 | 200 | ```markdown 201 | Thank you for reporting this issue. 202 | 203 | This is a standard message notifying you that the problem you mentioned here is present in production, but that it has already been fixed in staging. This means that the next time we push our staging branch to production, this problem should be fixed. Because of this, we're closing this issue. 204 | 205 | If you think we're wrong in closing this issue, please request for it to be reopened and add further clarification. Thank you and happy coding. 206 | ``` 207 | 208 | ## `first timer only` Issues 209 | 210 | > When an issue is deemed to be eligible for first-time code contributors. 211 | 212 | ```markdown 213 | Thanks for opening this issue. 214 | 215 | This looks like something that can be fixed by "first-time" code contributors to this repository. Here are the files that you should be looking at to work on a fix: 216 | 217 | List of files: 218 | 219 | 1. ... 220 | 2. ... 221 | 3. ... 222 | 223 | Please make sure you read our [guidelines for contributing](https://contribute.freecodecamp.org/#/), we prioritize contributors following the instructions in our guides. Join us in our [chat room](https://discord.gg/PRyKn3Vbay) or our [forum](https://forum.freecodecamp.org/c/contributors/3) if you need help contributing; our moderators will guide you through this. 224 | 225 | Sometimes we may get more than one pull request. We typically accept the most quality contribution followed by the one that is made first. 226 | 227 | Happy contributing. 228 | ``` 229 | 230 | ## Requests for Assignment 231 | 232 | ```md 233 | We typically do not assign issues. Instead, we accept the first pull request that comprehensively solves the issue. 234 | 235 | Issues labeled with `help wanted` or `first timers only` are open for contributions. 236 | 237 | Please make sure you read [our guidelines for contributing](https://contribute.freecodecamp.org/#/). We prioritize contributors following the instructions in our guide. Join us in [our chat room](https://discord.gg/PRyKn3Vbay) or [the forum](https://forum.freecodecamp.org/c/contributors/3) if you need help contributing - our community will be happy to assist you. 238 | ``` 239 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/security-hall-of-fame.md: -------------------------------------------------------------------------------- 1 | # Responsible Disclosure - Hall of Fame 2 | 3 | We appreciate any responsible disclosure of vulnerabilities that might impact the integrity of our platforms and users. If you are interested in contributing to the security of our platform, please read our [security policy outlined here](security.md). 4 | 5 | While we do not offer any bounties or swags at the moment, we are grateful to these awesome people for helping us keep the platform safe for everyone: 6 | 7 | - Mehul Mohan from [codedamn](https://codedamn.com) ([@mehulmpt](https://twitter.com/mehulmpt)) - [Vulnerability Fix](https://github.com/freeCodeCamp/freeCodeCamp/blob/bb5a9e815313f1f7c91338e171bfe5acb8f3e346/client/src/components/Flash/index.js) 8 | - Peter Samir https://www.linkedin.com/in/peter-samir/ 9 | - Laurence Tennant ([@hyperreality](https://github.com/hyperreality)) working with IncludeSecurity.com - [GHSA-cc3r-grh4-27gj](https://github.com/freeCodeCamp/freeCodeCamp/security/advisories/GHSA-cc3r-grh4-27gj) 10 | - Michal Biesiada ([@mbiesiad](https://github.com/mbiesiad)) - [GHSA-6c37-r62q-7xf4](https://github.com/freeCodeCamp/freeCodeCamp/security/advisories/GHSA-6c37-r62q-7xf4) 11 | 12 | > **Thank you for your contributions :pray:** 13 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/security.md: -------------------------------------------------------------------------------- 1 | # freeCodeCamp.org's Security Policy 2 | 3 | This document outlines our security policy for the codebases, platforms that we operate, and how to report vulnerabilities. 4 | 5 | ## Reporting a Vulnerability 6 | 7 | > [!NOTE] 8 | > If you think you have found a vulnerability, **please report it responsibly**. Do not create GitHub issues for security issues. Instead, follow this guide. 9 | 10 | ### Guidelines 11 | 12 | We appreciate responsible disclosure of vulnerabilities that might impact the integrity of our platforms and users. In the interest of saving everyone time, we encourage you to report vulnerabilities with these in mind: 13 | 14 | 1. Ensure that you are using the **latest**, **stable**, and **updated** versions of the Operating System and Web Browser(s) available to you on your machine. 15 | 2. We consider using tools & online utilities to report issues with SPF & DKIM configs, SSL Server tests, etc., in the category of ["beg bounties"](https://www.troyhunt.com/beg-bounties) and are unable to respond to these reports. 16 | 3. While we do not offer any bounties or swags at the moment, we'll be happy to list your name in our [Hall of Fame](security-hall-of-fame.md) list, provided the reports are not low-effort. 17 | 18 | ### Reporting 19 | 20 | After confirming the above guidelines, please feel free to send an email to `possible-security-issue [at] freecodecamp.org`. You can also send us a PGP encrypted message at `flowcrypt.com/me/freecodecamp`. 21 | 22 | Once you report a vulnerability, we will look into it and ensure that it is not a false positive. If we need to clarify any details, we will get back to you. You can submit separate reports for each issue you find. Please note that we will not be able to respond to any issues that we think are outside the guidelines. 23 | 24 | ## Platforms and Codebases 25 | 26 | Here is a list of the platforms and codebases we are accepting reports for: 27 | 28 | ### Learn Platform 29 | 30 | | Version | Branch | Supported | Website active | 31 | | ----------- | -------------- | --------- | ------------------------ | 32 | | production | `prod-current` | Yes | `freecodecamp.org/learn` | 33 | | staging | `prod-staging` | Yes | `freecodecamp.dev/learn` | 34 | | development | `main` | No | | 35 | 36 | ### Publication Platform 37 | 38 | | Version | Supported | Website active | 39 | | ---------- | --------- | ---------------------------------- | 40 | | production | Yes | `freecodecamp.org/news` | 41 | | localized | Yes | `freecodecamp.org/<language>/news` | 42 | 43 | ### Mobile App 44 | 45 | | Version | Supported | Website active | 46 | | ---------- | --------- | ---------------------------------------------------------------- | 47 | | production | Yes | `https://play.google.com/store/apps/details?id=org.freecodecamp` | 48 | 49 | ### Other Platforms 50 | 51 | Apart from the above, we are also accepting reports for repositories hosted on GitHub under the freeCodeCamp organization. 52 | 53 | ### Other Self-hosted Applications 54 | 55 | We self-host some of our platforms using open-source software like Ghost & Discourse. If you are reporting a vulnerability, please ensure that it is not a bug in the upstream software. 56 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/troubleshooting-development-issues.md: -------------------------------------------------------------------------------- 1 | If you are facing an issue, there is a high chance that the resolution is in this documentation. 2 | 3 | ## Issues with Installing the Recommended Prerequisites 4 | 5 | We regularly develop on the latest or most popular operating systems like macOS 10.15 or later, Ubuntu 18.04 or later, and Windows 10 (with WSL2). 6 | 7 | It is recommended to research your specific issue on resources such as Google, Stack Overflow, and Stack Exchange. There is a good chance that someone has faced the same issue and there is already an answer to your specific query. 8 | 9 | If you are on a different OS or are still facing issues, see [getting help](#getting-help). 10 | 11 | > [!WARNING] 12 | > 13 | > Please avoid creating GitHub issues for problems with the prerequisite technologies. They are out of the scope of this project. 14 | 15 | ## Issues with Missing UI, Fonts, Language Strings, or Build Errors 16 | 17 | When you build the client, Gatsby will cache the Fonts, language strings, and UI. If one of them isn't cached, run the following: 18 | 19 | ```bash 20 | pnpm run clean 21 | pnpm install 22 | pnpm run seed 23 | pnpm run develop 24 | ``` 25 | 26 | OR 27 | 28 | Use the shortcut 29 | 30 | ``` 31 | pnpm run clean-and-develop 32 | ``` 33 | 34 | If you continue to face issues with the build, cleaning up the workspace is recommended. 35 | 36 | Use `git clean` in interactive mode: 37 | 38 | ``` 39 | git clean -ifdX 40 | ``` 41 | 42 | <details> 43 | <summary> 44 | How to clean git untracked files (screenshot) 45 | </summary> 46 | <br> 47 | <img src="https://user-images.githubusercontent.com/1884376/94270515-ca579400-ff5d-11ea-8ff1-152cade31654.gif" alt="How to clean git untracked files"> 48 | </details> 49 | 50 | ## Issues with API, login, Challenge Submissions, etc. 51 | 52 | If you can't sign in, and instead you see a banner with an error message saying that the error will be reported to freeCodeCamp, please double-check that your local port `3000` is not in use by a different program. 53 | 54 | #### **From Terminal:** 55 | ```bash 56 | netstat -a | grep "3000" 57 | 58 | tcp4 0 0 0.0.0.0:3000 DESKTOP LISTEN 59 | ``` 60 | 61 | 62 | ## Issues Signing Out while Navigating 63 | 64 | While in development, your session is stored as cookies. Clearing them will sign you out of your development account. 65 | 66 | Running `pnpm run seed:certified-user` will log you out, too. It will overwrite the development user in your local database. 67 | 68 | ## Issue Getting 404 when Navigating Profile Page 69 | 70 | When you try to navigate to http://localhost:8000/developmentuser to view the profile page, Gatsby takes over serving the client-side pages and hence you will get a 404 page for the user profile when working. 71 | 72 | There is a "Preview Custom 404 Page" button, click it to see the profile. 73 | 74 | ## Issues Installing Dependencies 75 | 76 | If you get errors while installing the dependencies, please make sure that you are not in a restricted network or your firewall settings do not prevent you from accessing resources. 77 | 78 | The first time setup can take a while depending on your network bandwidth. Be patient, and if you are still stuck we recommend using Gitpod instead of an offline setup. 79 | 80 | > [!NOTE] 81 | > If you are using Apple Devices with M1 Chip to run the application locally, it is suggested to use Node v14.7 or above. You might run into issues with dependencies like Sharp otherwise. 82 | 83 | ## Working With Other Languages 84 | 85 | To see how the client renders in another language go to [testing the client app in a world language.](how-to-work-on-localized-client-webapp.md#Testing-the-Client-App-in-a-World-Language) 86 | 87 | ## Getting Help 88 | 89 | If you are stuck and need help, feel free to ask questions in the ['Contributors' category on our forum](https://forum.freecodecamp.org/c/contributors) or [the contributors chat room](https://discord.gg/PRyKn3Vbay). 90 | 91 | There might be an error in the console of your browser or in Bash / Terminal / Command Line that will help identify the problem. Provide this error message in your problem description so others can more easily identify the issue and help you find a resolution. 92 | -------------------------------------------------------------------------------- /project-three/_assets/fcc_docs/user-token-workflow.md: -------------------------------------------------------------------------------- 1 | # How the User Token Workflow Works 2 | 3 | User tokens are used to identify users to third parties so challenges completed using those services can be saved to a user's account. 4 | 5 | ## How they are Created 6 | 7 | At the moment, the tokens are only used to submit the Relational Database challenges. A token gets created when a signed-in user clicks the "Click here to start the course" or "Click here to start the project" buttons to start one of the Relational Database courses or projects. 8 | 9 | ## When they Get Deleted 10 | 11 | A user token will be deleted when a user signs out of freeCodeCamp, resets their progress, deletes their account, or manually deletes the token using the widget on the settings page. 12 | 13 | ## How they Work 14 | 15 | Tokens are stored in a `UserToken` collection in the database. Each record has a unique `_id`, which is the token, and a `user_id` that links to the user's account from the `user` collection. The token is encoded using JWT and sent to the client when it's created. That encoded token is then given to third-party services that need it and sent to our API by them when a challenge is completed. When our API gets it, it is decoded so we can identify the user submitting a challenge and save the completed challenge to their `completedChallenges`. 16 | -------------------------------------------------------------------------------- /project-three/_assets/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "mappings": { 3 | "dynamic": true, 4 | "fields": { 5 | "embedding": { 6 | "dimensions": 1536, 7 | "similarity": "cosine", 8 | "type": "knnVector" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /project-three/_assets/questions.txt: -------------------------------------------------------------------------------- 1 | What is the best way to help with freeCodeCamp.org?? 2 | How do I setup freeCodeCamp to run locally? 3 | What type of license is the freeCodeCamp codebase released under? -------------------------------------------------------------------------------- /project-three/app/api/chat/route.ts: -------------------------------------------------------------------------------- 1 | import { StreamingTextResponse, LangChainStream, Message } from 'ai'; 2 | import { ChatOpenAI } from 'langchain/chat_models/openai'; 3 | import { AIMessage, HumanMessage } from 'langchain/schema'; 4 | 5 | export const runtime = 'edge'; 6 | 7 | export async function POST(req: Request) { 8 | const { messages } = await req.json(); 9 | const currentMessageContent = messages[messages.length - 1].content; 10 | 11 | const vectorSearch = await fetch("http://localhost:3000/api/vectorSearch", { 12 | method: "POST", 13 | headers: { 14 | "Content-Type": "application/json", 15 | }, 16 | body: currentMessageContent, 17 | }).then((res) => res.json()); 18 | 19 | const TEMPLATE = `You are a very enthusiastic freeCodeCamp.org representative who loves to help people! Given the following sections from the freeCodeCamp.org contributor documentation, answer the question using only that information, outputted in markdown format. If you are unsure and the answer is not explicitly written in the documentation, say "Sorry, I don't know how to help with that." 20 | 21 | Context sections: 22 | ${JSON.stringify(vectorSearch)} 23 | 24 | Question: """ 25 | ${currentMessageContent} 26 | """ 27 | `; 28 | 29 | messages[messages.length -1].content = TEMPLATE; 30 | 31 | const { stream, handlers } = LangChainStream(); 32 | 33 | const llm = new ChatOpenAI({ 34 | modelName: "gpt-3.5-turbo", 35 | streaming: true, 36 | }); 37 | 38 | llm 39 | .call( 40 | (messages as Message[]).map(m => 41 | m.role == 'user' 42 | ? new HumanMessage(m.content) 43 | : new AIMessage(m.content), 44 | ), 45 | {}, 46 | [handlers], 47 | ) 48 | .catch(console.error); 49 | 50 | return new StreamingTextResponse(stream); 51 | } 52 | -------------------------------------------------------------------------------- /project-three/app/api/vectorSearch/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIEmbeddings } from "langchain/embeddings/openai"; 2 | import { MongoDBAtlasVectorSearch } from "langchain/vectorstores/mongodb_atlas"; 3 | import mongoClientPromise from '@/app/lib/mongodb'; 4 | 5 | export async function POST(req: Request) { 6 | const client = await mongoClientPromise; 7 | const dbName = "docs"; 8 | const collectionName = "embeddings"; 9 | const collection = client.db(dbName).collection(collectionName); 10 | 11 | const question = await req.text(); 12 | 13 | const vectorStore = new MongoDBAtlasVectorSearch( 14 | new OpenAIEmbeddings({ 15 | modelName: 'text-embedding-ada-002', 16 | stripNewLines: true, 17 | }), { 18 | collection, 19 | indexName: "default", 20 | textKey: "text", 21 | embeddingKey: "embedding", 22 | }); 23 | 24 | const retriever = vectorStore.asRetriever({ 25 | searchType: "mmr", 26 | searchKwargs: { 27 | fetchK: 20, 28 | lambda: 0.1, 29 | }, 30 | }); 31 | 32 | const retrieverOutput = await retriever.getRelevantDocuments(question); 33 | 34 | return Response.json(retrieverOutput); 35 | } -------------------------------------------------------------------------------- /project-three/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/vector-search-tutorial/f9d70ca770716d1ef76ad6eec444de82f00649ab/project-three/app/favicon.ico -------------------------------------------------------------------------------- /project-three/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /project-three/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './globals.css'; 2 | import { Inter } from 'next/font/google'; 3 | 4 | const inter = Inter({ subsets: ['latin'] }); 5 | 6 | export const metadata = { 7 | title: 'freeCodeCamp.org Contributor Docs', 8 | description: 'Contributing to freeCodeCamp.org.', 9 | }; 10 | 11 | export default function RootLayout({ 12 | children, 13 | }: { 14 | children: React.ReactNode; 15 | }) { 16 | return ( 17 | <html lang="en"> 18 | <body className={inter.className}>{children}</body> 19 | </html> 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /project-three/app/lib/mongodb.ts: -------------------------------------------------------------------------------- 1 | import { MongoClient } from "mongodb"; 2 | 3 | const uri = process.env.MONGODB_ATLAS_URI as string; // your mongodb connection string 4 | const options = {}; 5 | 6 | let client; 7 | let mongoClientPromise: Promise<any>; 8 | 9 | declare global { 10 | var _mongoClientPromise: Promise<any>; 11 | } 12 | 13 | if (!uri) { 14 | throw new Error("Please add your Mongo URI to .env.local"); 15 | } 16 | 17 | if (process.env.NODE_ENV === "development") { 18 | // In development mode, use a global variable so that the value 19 | // is preserved across module reloads caused by HMR (Hot Module Replacement). 20 | if (!global._mongoClientPromise) { 21 | client = new MongoClient(uri, options); 22 | global._mongoClientPromise = client.connect(); 23 | } 24 | mongoClientPromise = global._mongoClientPromise; 25 | } else { 26 | // In production mode, it's best to not use a global variable. 27 | client = new MongoClient(uri, options); 28 | mongoClientPromise = client.connect(); 29 | } 30 | 31 | // Export a module-scoped MongoClient promise. By doing this in a 32 | // separate module, the client can be shared across functions. 33 | export default mongoClientPromise; 34 | -------------------------------------------------------------------------------- /project-three/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useChat } from "ai/react"; 4 | import ReactMarkdown from "react-markdown"; 5 | 6 | export default function Chat() { 7 | const { messages, input, handleInputChange, handleSubmit } = useChat(); 8 | 9 | return ( 10 | <div className="mx-auto w-full max-w-md py-24 flex flex-col stretch"> 11 | {messages.length > 0 12 | ? messages.map((m) => ( 13 | <div key={m.id} className="whitespace-pre-wrap"> 14 | {m.role === "user" ? "User: " : "AI: "} 15 | <ReactMarkdown>{m.content}</ReactMarkdown> 16 | </div> 17 | )) 18 | : null} 19 | 20 | <form onSubmit={handleSubmit}> 21 | <input 22 | className="fixed w-full max-w-md bottom-0 border border-gray-300 rounded mb-8 shadow-xl p-2" 23 | value={input} 24 | placeholder="Say something..." 25 | onChange={handleInputChange} 26 | /> 27 | </form> 28 | </div> 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /project-three/createEmbeddings.mjs: -------------------------------------------------------------------------------- 1 | import { promises as fsp } from "fs"; 2 | import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; 3 | import { MongoDBAtlasVectorSearch } from "langchain/vectorstores/mongodb_atlas"; 4 | import { OpenAIEmbeddings } from "langchain/embeddings/openai"; 5 | import { MongoClient } from "mongodb"; 6 | import "dotenv/config"; 7 | 8 | const client = new MongoClient(process.env.MONGODB_ATLAS_URI || ""); 9 | const dbName = "docs"; 10 | const collectionName = "embeddings"; 11 | const collection = client.db(dbName).collection(collectionName); 12 | 13 | const docs_dir = "_assets/fcc_docs"; 14 | const fileNames = await fsp.readdir(docs_dir); 15 | console.log(fileNames); 16 | for (const fileName of fileNames) { 17 | const document = await fsp.readFile(`${docs_dir}/${fileName}`, "utf8"); 18 | console.log(`Vectorizing ${fileName}`); 19 | 20 | const splitter = RecursiveCharacterTextSplitter.fromLanguage("markdown", { 21 | chunkSize: 500, 22 | chunkOverlap: 50, 23 | }); 24 | const output = await splitter.createDocuments([document]); 25 | 26 | await MongoDBAtlasVectorSearch.fromDocuments( 27 | output, 28 | new OpenAIEmbeddings(), 29 | { 30 | collection, 31 | indexName: "default", 32 | textKey: "text", 33 | embeddingKey: "embedding", 34 | } 35 | ); 36 | } 37 | 38 | console.log("Done: Closing Connection"); 39 | await client.close(); 40 | -------------------------------------------------------------------------------- /project-three/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | module.exports = nextConfig; 5 | -------------------------------------------------------------------------------- /project-three/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs-vector-search-demo", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "embed": "node createEmbeddings.mjs" 11 | }, 12 | "dependencies": { 13 | "ai": "2.2.14", 14 | "dotenv": "^16.3.1", 15 | "langchain": "^0.0.129", 16 | "mongodb": "^5.9.0", 17 | "next": "13.4.12", 18 | "react": "18.2.0", 19 | "react-dom": "^18.2.0", 20 | "react-markdown": "^9.0.1" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^17.0.12", 24 | "@types/react": "18.2.8", 25 | "@types/react-dom": "18.2.4", 26 | "autoprefixer": "^10.4.14", 27 | "eslint": "^7.32.0", 28 | "eslint-config-next": "13.4.12", 29 | "postcss": "^8.4.23", 30 | "tailwindcss": "^3.3.2", 31 | "typescript": "5.1.3" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /project-three/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /project-three/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './app/**/*.{js,ts,jsx,tsx,mdx}', 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 12 | 'gradient-conic': 13 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | }; 19 | -------------------------------------------------------------------------------- /project-three/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "paths": { 23 | "@/*": ["./*"] 24 | } 25 | }, 26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 27 | "exclude": ["node_modules"] 28 | } 29 | -------------------------------------------------------------------------------- /project-two/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | App_* 10 | 11 | node_modules 12 | .DS_Store 13 | dist 14 | dist-ssr 15 | coverage 16 | *.local 17 | 18 | /cypress/videos/ 19 | /cypress/screenshots/ 20 | 21 | # Editor directories and files 22 | .vscode/* 23 | !.vscode/extensions.json 24 | .idea 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | -------------------------------------------------------------------------------- /project-two/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /project-two/README.md: -------------------------------------------------------------------------------- 1 | # Listings AI vector search demo 2 | 3 | This is a small web application to show case [Atlas Vector search](https://www.mongodb.com/products/platform/atlas-vector-search) with GPT-4 filter building out of free text search. 4 | 5 | To work with this front end please follow: [Leveraging OpenAI and MongoDB Atlas for Improved Search Functionality](https://www.mongodb.com/developer/products/atlas/atlas-vector-search-openai-filtering/) 6 | 7 | 8 | ## Recommended IDE Setup 9 | 10 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 11 | 12 | ## Customize configuration 13 | 14 | See [Vite Configuration Reference](https://vitejs.dev/config/). 15 | 16 | ## Project Setup 17 | 18 | Build the relevent API endpoints and point the front end applicaiton to it: 19 | 20 | `src/App.vue`: 21 | ``` 22 | /* 23 | TODO: REPLACE WITH YOURS 24 | <ENDPOINT_APP_SERVICES> is the endpoint of your app services 25 | */ 26 | const response = await axios.get( 27 | '<ENDPOINT_APP_SERVICES>', 28 | { params } 29 | ); 30 | ``` 31 | 32 | ### Install 33 | 34 | 35 | ```sh 36 | npm install 37 | ``` 38 | 39 | ### Compile and Hot-Reload for Development 40 | 41 | ```sh 42 | npm run dev 43 | ``` 44 | 45 | ### Compile and Minify for Production 46 | 47 | ```sh 48 | npm run build 49 | ``` 50 | -------------------------------------------------------------------------------- /project-two/index.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html lang="en"> 3 | <head> 4 | <meta charset="UTF-8"> 5 | <link rel="icon" href="/favicon.ico"> 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 | <title>Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /project-two/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vsearch", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "axios": "^1.4.0", 12 | "vue": "^3.2.36", 13 | "vue-range-slider": "^0.6.0" 14 | }, 15 | "devDependencies": { 16 | "@vitejs/plugin-vue": "^4.2.3", 17 | "@vitejs/plugin-vue-jsx": "^3.0.1", 18 | "vite": "^4.3.9" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /project-two/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beaucarnes/vector-search-tutorial/f9d70ca770716d1ef76ad6eec444de82f00649ab/project-two/public/favicon.ico -------------------------------------------------------------------------------- /project-two/src/App.vue: -------------------------------------------------------------------------------- 1 | 84 | 85 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /project-two/src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | /* font-weight: normal; */ 59 | } 60 | 61 | body { 62 | min-height: 100vh; 63 | color: var(--color-text); 64 | background: var(--color-background); 65 | transition: color 0.5s, background-color 0.5s; 66 | line-height: 1.6; 67 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 68 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 69 | font-size: 15px; 70 | text-rendering: optimizeLegibility; 71 | -webkit-font-smoothing: antialiased; 72 | -moz-osx-font-smoothing: grayscale; 73 | } 74 | -------------------------------------------------------------------------------- /project-two/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /project-two/src/assets/main.css: -------------------------------------------------------------------------------- 1 | @import './base.css'; 2 | 3 | #app { 4 | /* max-width: 1280px; */ 5 | /* margin: 0 auto; */ 6 | width: 100%; 7 | padding: 2rem; 8 | /* 9 | font-weight: normal; */ 10 | } 11 | 12 | a, 13 | .green { 14 | text-decoration: none; 15 | color: hsla(160, 100%, 37%, 1); 16 | transition: 0.4s; 17 | } 18 | 19 | @media (hover: hover) { 20 | a:hover { 21 | background-color: hsla(160, 100%, 37%, 0.2); 22 | } 23 | } 24 | 25 | @media (min-width: 1024px) { 26 | body { 27 | display: flex; 28 | place-items: center; 29 | } 30 | 31 | #app { 32 | /* display: grid; 33 | grid-template-columns: 1fr 1fr; */ 34 | padding: 0 2rem; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /project-two/src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /project-two/src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /project-two/src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /project-two/src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /project-two/src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /project-two/src/main.js: -------------------------------------------------------------------------------- 1 | import './assets/main.css' 2 | 3 | import { createApp } from 'vue' 4 | import App from './App.vue' 5 | 6 | createApp(App).mount('#app') 7 | -------------------------------------------------------------------------------- /project-two/vite.config.js: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | import vueJsx from '@vitejs/plugin-vue-jsx' 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [ 10 | vue(), 11 | vueJsx(), 12 | ], 13 | resolve: { 14 | alias: { 15 | '@': fileURLToPath(new URL('./src', import.meta.url)) 16 | } 17 | } 18 | }) 19 | --------------------------------------------------------------------------------