Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 39 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,49 @@ export default defineConfig({
starlight({
title: 'Contribute | freeCodeCamp.org',
description: 'Contribute to freeCodeCamp.org',
locales: {
root: {
label: 'English',
lang: 'en'
},
es: {
label: 'Español',
lang: 'es'
},
de: {
label: 'German',
lang: 'de'
},
it: {
label: 'Italian',
lang: 'it'
},
jp: {
label: 'Japanese',
lang: 'jp'
},
pt: {
label: 'Portuguese',
lang: 'pt'
},
uk: {
label: 'Ukrainian',
lang: 'uk'
},
zh: {
label: 'Chinese',
lang: 'zh'
},
'zh-Tw': {
label: 'Chinese Traditional',
lang: 'zh-TW'
}
},
logo: {
src: './public/icons/icon-96x96.png',
replacesTitle: true
},
tableOfContents: true,
defaultLocale: 'en',
editLink: {
baseUrl: 'https://github.com/freeCodeCamp/contribute/edit/main/'
},
Expand All @@ -37,6 +74,7 @@ export default defineConfig({
]
})
],

output: 'hybrid',
adapter: cloudflare({
imageService: 'passthrough'
Expand Down
2 changes: 2 additions & 0 deletions src/components/FCCHeader.astro
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import FCCThemeSelect from './FCCThemeSelect.astro';
* Render the `Search` component if Pagefind is enabled or the default search component has been overridden.
*/
const shouldRenderSearch = true;

//config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
---

Expand All @@ -32,6 +33,7 @@ const shouldRenderSearch = true;
</div>
<FCCThemeSelect {...Astro.props} />
<LanguageSelect {...Astro.props} />

</div>
</div>

Expand Down
14 changes: 11 additions & 3 deletions src/content/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { defineCollection } from 'astro:content';
import { docsSchema } from '@astrojs/starlight/schema';
import { defineCollection, z } from 'astro:content';
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';

export const collections = {
docs: defineCollection({ schema: docsSchema() })
docs: defineCollection({ schema: docsSchema() }),
i18n: defineCollection({
type: 'data',
schema: i18nSchema({
extend: z.object({
'custom.label': z.string().optional()
})
})
})
};
29 changes: 29 additions & 0 deletions src/content/docs/de/authors-analytics-manual.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Authors Analytics Manual
---

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.

## Search by Language

To search for engagement reports in a specific language:

![Image - Show steps to search by language on googla analytics](https://contribute.freecodecamp.org/images/google-analytics/search-by-language.png)

1. From the top dropdown menu, select `News`.
1. From the sidebar, click on `Reports`.
1. From the secondary sidebar, select `Engagement`.
1. Click on `Pages and Screens`.
1. In the search bar, type the subpath for the desired language.
1. From the dropdown under the search bar, choose `Page path and screen class`.

## Filter Reports by Author

After arriving at the `Pages and Screens` reports mentioned above, use the following steps to filter the results by specific authors.

![Image - Show steps to search by language on googla analytics](https://contribute.freecodecamp.org/images/google-analytics/filter-by-author.png)

1. Click on the `Add filter` button.
1. From the side navigation include `Author`.
1. From the `Dimensions values` dropdown, choose an author's name.
1. Click on the `Apply` button to apply changes.
192 changes: 192 additions & 0 deletions src/content/docs/de/codebase-best-practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
title: Best Practices für die Codebasis
---

## Styling a component

We recommend styling components using our [design style guide](https://design-style-guide.freecodecamp.org/).

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).

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.

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.

### RTL support

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 to be mindful of how to style components. Here are some quick rules of thumb to follow:

- Don't use `float` properties
- Use Flexbox and Grid layouts instead, as they have RTL support already built-in, and those will be easier to maintain and review.
- 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.
- 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.
- 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.

## General JavaScript

In most cases, our [linter](how-to-setup-freecodecamp-locally#follow-these-steps-to-get-your-development-environment-ready) will warn of any formatting which goes against this codebase's preferred practice.

It is encouraged to use functional components over class-based components.

## Specific TypeScript

### Migrating a JavaScript File to TypeScript

#### Beibehalten des Git-Dateiverlaufs

Sometimes changing the file from `<filename>.js` to `<filename>.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.

The best bet at achieving this is to:

1. Umbenennen der Datei
2. Commit mit dem Flag `--no-verify`, damit Husky sich nicht über die Lint-Fehler beschwert
3. Refactoring zu TypeScript für die Migration, in einem separaten Commit

:::note
Editoren wie VSCode zeigen dir wahrscheinlich trotzdem an, dass die Datei gelöscht und eine neue erstellt wurde. Wenn du die CLI für `git add .` verwendest, zeigt VSCode die Datei als umbenannt im Stage an
:::

### Naming Conventions

#### Schnittstellen und Typen

For the most part, it is encouraged to use interface declarations over type declarations.

React Component Props - suffix with `Props`

```typescript
interface MyComponentProps {}
// type MyComponentProps = {};
const MyComponent = (props: MyComponentProps) => {};
```

React Stateful Components - suffix with `State`

```typescript
interface MyComponentState {}
// type MyComponentState = {};
class MyComponent extends Component<MyComponentProps, MyComponentState> {}
```

Default - object name in PascalCase

```typescript
interface MyObject {}
// type MyObject = {};
const myObject: MyObject = {};
```

<!-- #### Redux Actions -->

<!-- TODO: Once refactored to TS, showcase naming convention for Reducers/Actions and how to type dispatch funcs -->

## Redux

### Action Definitions

```typescript
enum AppActionTypes = {
actionFunction = 'actionFunction'
}

export const actionFunction = (
arg: Arg
): ReducerPayload<AppActionTypes.actionFunction> => ({
type: AppActionTypes.actionFunction,
payload: arg
});
```

### How to Reduce

```typescript
// Base reducer action without payload
type ReducerBase<T> = { type: T };
// Logic for handling optional payloads
type ReducerPayload<T extends AppActionTypes> =
T extends AppActionTypes.actionFunction
? ReducerBase<T> & {
payload: AppState['property'];
}
: ReducerBase<T>;

// Switch reducer exported to Redux combineReducers
export const reducer = (
state: AppState = initialState,
action: ReducerPayload<AppActionTypes>
): AppState => {
switch (action.type) {
case AppActionTypes.actionFunction:
return { ...state, property: action.payload };
default:
return state;
}
};
```

### How to Dispatch

Within a component, import the actions and selectors needed.

```tsx
// Add type definition
interface MyComponentProps {
actionFunction: typeof actionFunction;
}
// Connect to Redux store
const mapDispatchToProps = {
actionFunction
};
// Example React Component connected to store
const MyComponent = ({ actionFunction }: MyComponentProps): JSX.Element => {
const handleClick = () => {
// Dispatch function
actionFunction();
};
return <button onClick={handleClick}>freeCodeCamp is awesome!</button>;
};

export default connect(null, mapDispatchToProps)(MyComponent);
```

<!-- ### Redux Types File -->
<!-- The types associated with the Redux store state are located in `client/src/redux/types.ts`... -->

## API

### Testing

The `api/` tests are split into two parts:

1. Unit tests
2. Integration tests

#### Unit Tests

Unit tests isolate a single function or component. The tests do not need mocking, but will require fixtures.

The unit tests are located in a new file adjacent to the file exporting that is being tested:

```text
api/
├── src/
│ ├── utils.ts
│ ├── utils.test.ts
```

#### Integration Tests

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 for authentication.

Typically, each integration test file will be directly related to a route. The integration tests are located in the `api/tests/` directory:

```text
api/
├── tests/
│ ├── settings.ts
```

## Further Literature

- [TypeScript Docs](https://www.typescriptlang.org/docs/)
- [TypeScript with React CheatSheet](https://github.com/typescript-cheatsheets/react#readme)
43 changes: 43 additions & 0 deletions src/content/docs/de/courses-vscode-extension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: Kurse VSCode Erweiterung
---

Dies beschreibt die Wartungsrichtlinien für das [freeCodeCamp/courses-vscode-extension](https://github.com/freeCodeCamp/courses-vscode-extension) Repository, das den Quellcode für die [freeCodeCamp - Courses](https://marketplace.visualstudio.com/items?itemName=freeCodeCamp.freecodecamp-courses) Erweiterung enthält.

## Veröffentlichung der Erweiterung

Eine GitHub-Aktion veröffentlicht automatisch die Erweiterung im Visual Studio Marketplace bei der Veröffentlichung einer neuen GitHub-Version.

1. Packe eine neue Version der Erweiterung:

```bash
npm run pack -- <tag_type>
```

Dabei ist `<tag_type>` eines von: `major`, `minor`, `patch`.

2. Schiebe die neue Version nach `main`:

```bash
git commit -am "<tag_type>(<version>): <description>"
git push
```

Optional kannst du direkt zu `upstream/main` pushen, aber es wird empfohlen, einen neuen PR zu eröffnen, um die Richtigkeit zu überprüfen.

3. Erstelle eine neues GitHub-Release über die GitHub-Benutzeroberfläche:

- Erhöhe die Versionsnummer korrekt, wenn du einen neuen Tag erstellst.
- Lade die `.vsix`-Datei mit dem Release hoch.
- Veröffentliche das Release und bestätige, dass die Aktion erfolgreich war.

> [!NOTE] Das Erstellen einer Version erfordert Schreibzugriff auf das `freeCodeCamp/courses-vscode-extension` Repository.

## Manuelles Veröffentlichen der Erweiterung

Ein manueller Upload auf den Visual Studio Marketplace kann mit den folgenden Schritten durchgeführt werden:

1. Besuche https://marketplace.visualstudio.com/ und melde dich an
2. Navigiere zur [freeCodeCamp Publisher Seite](https://marketplace.visualstudio.com/manage/publishers/freecodecamp)
3. Wähle die entsprechende Erweiterung aus und wähle `Update`
4. Lade die Datei aus deinen lokalen Dateien hoch
Loading