Skip to content
Open
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/member-delimiter-style': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/explicit-module-boundary-types': 'off',
'react/no-unknown-property': ['error', { ignore: ['jsx', 'global'] }],
},
settings: {
react: 'detect',
react: {
version: 'detect',
},
},
overrides: [
{
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/deploy-github-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Deploy to GitHub Pages

on:
push:
branches:
- master
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build static site
run: npm run export
env:
GITHUB_ACTIONS: true
GITHUB_REPOSITORY: ${{ github.repository }}
# Set CUSTOM_DOMAIN=true when using custom domain (e.g., opentechschool.org)
CUSTOM_DOMAIN: true

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./out

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
66 changes: 0 additions & 66 deletions .github/workflows/deploy.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ node_modules
src/.next
.env
src/out/
out/
.DS_Store
npm-debug.log
next-env.d.ts
.next
.vercel
.claude/
71 changes: 49 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ If you want to contribute but don't know on what to work on, check our github is

If you are beginner, search for the label `good first issues`.<br />
Assign the issue to your self and when you are done, make a PR to review.<br />
Always feel free to reach out for help. You can write in the issue it self, you can open a PR as draft and ask suggestion about your code or you can contact us on [slack](https://opentechschool-slack.herokuapp.com) in the #website-dev channel.
Always feel free to reach out for help. You can write in the issue itself, you can open a PR as draft and ask suggestion about your code.

### Requisit:
### Requirements:

`Node version > 9`
`Node version >= 12` (recommended: Node 18+ or 20+)

`npm`

Expand Down Expand Up @@ -71,9 +71,8 @@ WrappedIcon.muiName = Icon.muiName;

## Cities data

Markdown for city can be found in data/cities.<br />
Inside this folder you will find subfolders based on language. Each city must have at least english language to be visible.<br />
Add as many language as you wish for your city. The files must have always the same name: `city-name.md`.<br />
Markdown for city can be found in `data/cities/en/`.<br />
Each city file should be named `city-name.md` and placed in the English directory.<br />
If you want to add a city that is currently inactive, just add `is_inactive` to the markdown.

Each city **MUST HAVE**:
Expand Down Expand Up @@ -116,26 +115,21 @@ members:

### Translation

Translation are located in `translations/`. Here there are some configuration and typescript file needed to make translation works but most important there are `json` files for each language.<br />
Those are translation for all the website except the city page.<br />
If you create new content, please remember to add your text to those files, at least to the english translation.
Translations are located in `translations/` directory. The website currently supports English only after the conversion to static site generation.<br />
If you create new content, please remember to add your text to the `en.json` translation file.

If you add a new language add a `yourLanguage.json` file in the `translations/` directory and remember to add your language to the `config.ts` files to make it available to the `<LocalSwitcher />`
To use translations in a component, use the `t()` function from the `useTranslation` hook:

If you want to use translation in a file, you can use the `t()` function, which it takes as a argument the string to translate from the language jons file.<br />
Example:
In my `en.json` i have such string:
```javascript
import useTranslation from '../hooks/useTranslation'

```
"about": {
"title": "About OTS"
const MyComponent = () => {
const { t } = useTranslation()
return <h1>{t('about.title')}</h1>
}
```

in my `about.tsx` page i can use the `t` function like that: `t('about.title')`.
`t()` function always fall back to english. If the translation doesn't exists even in the `en.json` file, you will see printed the string of your translation (i.e. `about.title`) and a warning will show up in your console.

`t()` function can be extracted form the `useTranslation` hook and in order to be effective in a page, the page must be wrapped with the `WithLocale()` HOC.
The `t()` function takes a key from the `en.json` file and falls back to displaying the key if translation is missing.

### Conventions

Expand All @@ -151,7 +145,40 @@ Yet, we avoid using javascript-in-css as much as possible therefore it will be e

## Deployment

This website is being deployed to [Zeit.co](https://zeit.co/) on the free team account https://zeit.co/opentechschool. Every push to master goes live automatically via their Github integration.
This website is deployed to GitHub Pages. Every push to the `github-pages-new` branch automatically triggers the GitHub Actions workflow that builds and deploys the static site.

### Building for GitHub Pages Locally

To test the GitHub Pages build locally with the correct basePath configuration:

Note: We are using `out` instead of `websitenext`, but the github action will copy files from `out` to `websitenext`

```bash
# Build and export with GitHub Pages environment variables
GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/out npm run build
GITHUB_ACTIONS=true GITHUB_REPOSITORY=OpenTechSchool/out npx next export

# The static files will be generated in the 'out' directory
# All asset paths (images, fonts, links) will include the /out basePath
```

**Important:** When building for GitHub Pages, the build process:

- Adds `/websitenext` basePath to all asset URLs
- Configures static export for proper GitHub Pages deployment
- Ensures fonts, images, and internal links work correctly with the repository's subpath

For local development without basePath, use the standard commands:

```bash
npm run dev # Development server
npm run build # Production build (local)
npm run export # Static export (local)
```

### Using a custom domain

Set `CUSTOM_DOMAIN` to true in `deploy-github-pages.yml` when using a custom domain e.g. opentechschool.org

## Contact

Expand All @@ -161,4 +188,4 @@ Feel free to open a new issue here on github. Try to label it as best as you can
Have an idea and already know how to develop it? Go ahead and make a PR, we are very happy to review it.

Have an idea but would like to talk to someone to know how to better proceed?
Join us on [slack](https://opentechschool-slack.herokuapp.com): channel #website-dev
Feel free to open a GitHub issue to discuss your ideas and get guidance on implementation.
4 changes: 3 additions & 1 deletion components/CityHero/CityHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import { mediaquery } from '../../style/style'
// import Link from 'next/link'
// import OutlineButton from '../Button/OutlineButton'
import useTranslation from '../../hooks/useTranslation'
import { useAssetPath } from '../../utils/assetPath'

function CityHero({ cityName, title, tagline, meetupName, credits }) {
const { t } = useTranslation()
const assetPath = useAssetPath()
const [members, setMembers] = useState()

useEffect(() => {
Expand All @@ -30,7 +32,7 @@ function CityHero({ cityName, title, tagline, meetupName, credits }) {
return (
<div>
<section>
<div style={{ backgroundImage: `url(/${cityName}_cityBg.jpg)` }}>
<div style={{ backgroundImage: `url(${assetPath(`/${cityName}_cityBg.jpg`)})` }}>
<h1>{title}</h1>
<p className='tagline'>
<i>&quot;{tagline}&quot;</i>
Expand Down
14 changes: 8 additions & 6 deletions components/Meta.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import PropTypes from 'prop-types'
import Head from 'next/head'
import useTranslation from '../hooks/useTranslation'
import { useAssetPath } from '../utils/assetPath'

export default function Meta({ pageTitle, pageDescription, pageImage }) {
const { t } = useTranslation()
const assetPath = useAssetPath()
pageTitle = `${pageTitle} | OpenTechSchool`
return (
<>
Expand All @@ -22,30 +24,30 @@ export default function Meta({ pageTitle, pageDescription, pageImage }) {
<meta
property='og:image'
content={`https://www.opentechschool.org${
pageImage || '/sharing-images/website-into-sharing.png?1'
pageImage || assetPath('/sharing-images/website-into-sharing.png?1')
}`}
/>
<meta name='twitter:card' content='summary_large_image' />
<meta name='twitter:site' content='@OpenTechSchool' />
<link
rel='apple-touch-icon'
sizes='180x180'
href='/apple-touch-icon.png'
href={assetPath('/apple-touch-icon.png')}
/>
<link rel='shortcut icon' href='/favicon.ico' />
<link rel='shortcut icon' href={assetPath('/favicon.ico')} />
<link
rel='icon'
type='image/png'
href='/favicon-32x32.png'
href={assetPath('/favicon-32x32.png')}
sizes='32x32'
/>
<link
rel='icon'
type='image/png'
href='/favicon-96x96.png'
href={assetPath('/favicon-96x96.png')}
sizes='96x96'
/>
<link rel='manifest' href='/site.webmanifest' />
<link rel='manifest' href={assetPath('/site.webmanifest')} />
</Head>
</>
)
Expand Down
4 changes: 3 additions & 1 deletion components/Team/MarkdownTeam.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types'
import Grid from '@material-ui/core/Grid'
import { useAssetPath } from '../../utils/assetPath'

function chunkArray(array, size) {
const chunkedArray = []
Expand All @@ -12,6 +13,7 @@ function chunkArray(array, size) {
}

const TeamSection = ({ members }) => {
const assetPath = useAssetPath()
const chunksOfFour = chunkArray(members, 4)

return (
Expand All @@ -35,7 +37,7 @@ const TeamSection = ({ members }) => {
key={key}
item
>
<img src={`/members/${Object.keys(member)[0]}.jpg`} />
<img src={assetPath(`/members/${Object.keys(member)[0]}.jpg`)} />
<p className='name'>{Object.values(member)}</p>
</Grid>
)
Expand Down
19 changes: 1 addition & 18 deletions containers/withLocale.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,13 @@ interface LangProps {

const WithLocale = (WrappedPage: NextPage<any>) => {
const WithLocale: NextPage<any, LangProps> = ({ ...pageProps }) => {
// if (!locale) {
// return <Error statusCode={404} />
// }

return (
<LocaleProvider lang={'en' /*locale*/}>
<LocaleProvider lang={'en'}>
<WrappedPage {...pageProps} />
</LocaleProvider>
)
}

WithLocale.getInitialProps = async ctx => {
let pageProps = {}
if (WrappedPage.getInitialProps) {
pageProps = await WrappedPage.getInitialProps(ctx)
}

if (typeof ctx.query.lang !== 'string' || !isLocale(ctx.query.lang)) {
return { ...pageProps, locale: undefined }
}

return { ...pageProps, locale: ctx.query.lang }
}

return WithLocale
}

Expand Down
Loading
Loading