-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat(React) Added files to new project
- Loading branch information
0 parents
commit 2f669f7
Showing
39 changed files
with
11,812 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
VITE_API_TEST=Hello,world |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module.exports = { | ||
root: true, | ||
env: { browser: true, es2020: true }, | ||
extends: [ | ||
'eslint:recommended', | ||
'plugin:react/recommended', | ||
'plugin:react/jsx-runtime', | ||
'plugin:react-hooks/recommended', | ||
'prettier' | ||
], | ||
ignorePatterns: ['dist', '.eslintrc.cjs'], | ||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, | ||
settings: { react: { version: '18.2' } }, | ||
plugins: ['react-refresh'], | ||
rules: { | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: Build and deploy to GitHub Pages | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
env: | ||
VITE_API_TEST: ${{secrets.VITE_API_TEST}} | ||
|
||
jobs: | ||
build-and-deploy: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout 🛎️ | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install, build 🔧 | ||
run: | | ||
npm install | ||
npm run build | ||
cp ./dist/index.html ./dist/404.html | ||
- name: Deploy 🚀 | ||
uses: JamesIves/[email protected] | ||
with: | ||
branch: gh-pages | ||
folder: dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/bin/sh | ||
. "$(dirname "$0")/_/husky.sh" | ||
|
||
npx lint-staged |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"src/**/*.{json,css,scss,md}": ["prettier --write"], | ||
"src/**/*.{js,jsx,ts,tsx}": ["prettier --write", "eslint --fix"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"printWidth": 80, | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"semi": true, | ||
"singleQuote": true, | ||
"trailingComma": "all", | ||
"bracketSpacing": true, | ||
"jsxBracketSameLine": false, | ||
"arrowParens": "avoid", | ||
"proseWrap": "always" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# React + Vite template | ||
|
||
Цей проєкт було створено за допомогою [Create Vite](https://vitejs.dev/). Для | ||
знайомства і налаштування додаткових можливостей | ||
[звернися до документації](https://vitejs.dev/guide/). | ||
|
||
## Створення репозиторію за шаблоном | ||
|
||
Використовуй цей репозиторій організації GoIT як шаблон для створення | ||
репозиторію свого проєкту. Для цього натисни на кнопку `"Use this template"` і | ||
обери опцію `"Create a new repository"`, як показано на зображенні. | ||
|
||
![Creating repo from a template step 1](./src/assets/template-step-1.png) | ||
|
||
На наступному кроці відкриється сторінка створення нового репозиторію. Заповни | ||
поле його імені, переконайся що репозиторій публічний, після чого натисни кнопку | ||
`"Create repository from template"`. | ||
|
||
![Creating repo from a template step 2](./src/assets/template-step-2.png) | ||
|
||
Після того як репозиторій буде створено, необхідно перейти в налаштування | ||
створеного репозиторію на вкладку `Settings` > `Actions` > `General` як показано | ||
на зображенні. | ||
|
||
![Settings GitHub Actions permissions step 1](./src/assets/gh-actions-perm-1.png) | ||
|
||
Проскроливши сторінку до самого кінця, у секції `"Workflow permissions"` вибери | ||
опцію `"Read and write permissions"` і постав галочку в чекбоксі. Це необхідно | ||
для автоматизації процесу деплою проєкту. | ||
|
||
![Settings GitHub Actions permissions step 2](./src/assets/gh-actions-perm-2.png) | ||
|
||
Тепер у тебе є особистий репозиторій проєкту, зі структурою файлів і папок | ||
репозиторія-шаблону. Далі працюй з ним як з будь-яким іншим особистим | ||
репозиторієм, клонуй його собі на комп'ютер, пиши код, роби комміти і відправляй | ||
їх на GitHub. | ||
|
||
## Підготовка до роботи | ||
|
||
1. Переконайся, що на комп'ютері встановлена LTS-версія Node.js. | ||
[Скачай і встанови](https://nodejs.org/en/) її якщо необхідно. | ||
2. Встановіть базові залежності проекту командою `npm install`. | ||
3. Запустіть режим розробки, виконавши команду `npm run dev`. | ||
4. Перейди в браузері за адресою, що зазначено в терміналі. | ||
|
||
## Деплой | ||
|
||
Продакшн версія проєкту буде автоматично збиратися і деплоїтися на GitHub Pages, | ||
у гілку `gh-pages`, щоразу, коли оновлюється гілка `main`. Наприклад, після | ||
прямого пушу або прийнятого пул-реквесту. Для цього необхідно у файлі | ||
`vite.config.js` відредагувати поле `base`, замінивши `react_vite` на свою назву | ||
репозиторію `"/your_repo_name"`, і відправити зміни на GitHub. | ||
|
||
Далі необхідно зайти в налаштування GitHub-репозиторію (`Settings` > `Pages`) і | ||
виставити роздачу продакшн версії файлів із папки `/root` гілки `gh-pages`, якщо | ||
це не було зроблено автоматично. | ||
|
||
![GitHub Pages settings](./src/assets/repo-settings.png) | ||
|
||
### Статус деплоя | ||
|
||
Статус деплою крайнього коміту відображається іконкою біля його ідентифікатора. | ||
|
||
- **Жовтий колір** - виконується збірка і деплой проєкту. | ||
- **Зелений колір** - деплой завершився успішно. | ||
- **Червоний колір** - під час збирання або деплою сталася помилка. | ||
|
||
Детальнішу інформацію про статус можна подивитися, клікнувши на іконку, і в | ||
випадаючому вікні перейти за посиланням `Details`. | ||
|
||
![Deployment status](./src/assets/deploy-status.png) | ||
|
||
### Жива сторінка | ||
|
||
Через якийсь час, зазвичай кілька хвилин, живу сторінку можна буде подивитися за | ||
адресою, вказаною в налаштуваннях GitHub-репозиторію (`Settings` > `Pages`). | ||
|
||
![GitHub-pages URL](./src/assets/gh-pages-url.png) | ||
|
||
Якщо відкривається порожня сторінка, переконайся що у вкладці `Console` немає | ||
помилок пов'язаних із неправильними шляхами до CSS і JS файлів проекту | ||
(**404**). Швидше за все найімовірніше, у тебе неправильне значення поля `base` | ||
у файлі `vite.config.js`. | ||
|
||
### Маршрутизація | ||
|
||
Якщо додаток використовує бібліотеку `react-router-dom` для маршрутизації, | ||
необхідно додатково налаштувати компонент `<BrowserRouter>`, передавши в пропе | ||
`basename` точну назву твого репозиторію. Слеш на початку рядка обов'язковий. | ||
|
||
```jsx | ||
<BrowserRouter basename="/your_repo_name"> | ||
<App /> | ||
</BrowserRouter> | ||
``` | ||
### Додавання змінних в .env | ||
Для зберігання конфігураційних даних, таких як API ключі, адреси серверів, порти та інші змінні використовуйте файл `.env`. Для цього необхідно з назви файлу `.env.template` видалити зайві ".template",після чого файл відповідатиме умовам файлу `.ignore` і буде зберігатися лише локально, не публікуючись на віддаленому репозиторії з метою безпеки. Задля використання змінних на GitHub-pages усі змінні, передбачені файлом .env, слід додати до файлу `.github/workflows/deploy.yml`, а також до налаштувань репозиторію. Для цього слід перейти (`Settings` > `Secrets and variables` > `Actions`) | ||
|
||
![Add enviroments from .env](./src/assets/secrets.png) | ||
|
||
## Як це працює | ||
|
||
1. Після кожного пушу в гілку `main` GitHub-репозиторію, запускається | ||
спеціальний скрипт (GitHub Action) з файлу `.github/workflows/deploy.yml`. | ||
2. Усі файли репозиторію копіюються на сервер, де проєкт ініціалізується і | ||
проходить збірку перед деплоєм. 3 Якщо всі кроки пройшли успішно, зібрана | ||
продакшн-версія файлів проєкту відправляється в гілку `gh-pages`. В іншому | ||
випадку, в логах виконання скрипта буде вказано в чому проблема. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import axios from 'axios'; | ||
import { createAsyncThunk } from '@reduxjs/toolkit'; | ||
import { | ||
signIn, | ||
signOut, | ||
getUser, | ||
getRefreshToken, | ||
updateBalance, | ||
} from '../services'; | ||
import { | ||
fetchIncomeCategories, | ||
fetchExpenseCategories, | ||
fetchIncome, | ||
fetchExpense, | ||
} from '../redux/transactionsOperations'; | ||
import { showErrorMessage } from '../components/Toasters'; | ||
|
||
const token = { | ||
set(token) { | ||
axios.defaults.headers.common.Authorization = `Bearer ${token}`; | ||
}, | ||
unset() { | ||
axios.defaults.headers.common.Authorization = ''; | ||
}, | ||
}; | ||
|
||
export const logIn = createAsyncThunk( | ||
'auth/logIn', | ||
async function (credentials, { rejectWithValue, dispatch }) { | ||
try { | ||
const { data } = await signIn(credentials); | ||
token.set(data.accessToken); | ||
sessionStorage.setItem('token', data.accessToken); | ||
sessionStorage.setItem('refreshToken', data.refreshToken); | ||
sessionStorage.setItem('sid', data.sid); | ||
dispatch(fetchIncomeCategories()); | ||
dispatch(fetchExpenseCategories()); | ||
return data; | ||
} catch (error) { | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
|
||
export const logInGoogle = createAsyncThunk( | ||
'auth/logIn', | ||
async function (response, { rejectWithValue, dispatch }) { | ||
try { | ||
token.set(response.accessToken); | ||
sessionStorage.setItem('token', response.accessToken); | ||
sessionStorage.setItem('refreshToken', response.refreshToken); | ||
sessionStorage.setItem('sid', response.sid); | ||
await dispatch(getCurrentUser()); | ||
return response; | ||
} catch (error) { | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
|
||
export const logOut = createAsyncThunk( | ||
'auth/logOut', | ||
async function (_, { rejectWithValue, dispatch }) { | ||
try { | ||
sessionStorage.removeItem('token'); | ||
sessionStorage.removeItem('sid'); | ||
sessionStorage.removeItem('refreshToken'); | ||
await signOut(); | ||
token.unset(); | ||
} catch (error) { | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
|
||
export const getCurrentUser = createAsyncThunk( | ||
'auth/getCurrentUser', | ||
async function (_, { rejectWithValue, dispatch }) { | ||
try { | ||
const accessToken = sessionStorage.getItem('token'); | ||
token.set(accessToken); | ||
const response = await getUser(); | ||
if (response.data) { | ||
dispatch(fetchIncome()); | ||
dispatch(fetchExpense()); | ||
} | ||
return response.data; | ||
} catch (error) { | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
export const updateUserBalance = createAsyncThunk( | ||
'auth/updateUserBalance', | ||
async function (balance, { rejectWithValue, dispatch }) { | ||
try { | ||
const response = await updateBalance(balance); | ||
return response.data; | ||
} catch (error) { | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
|
||
export const refresh = createAsyncThunk( | ||
'auth/refresh', | ||
async function (_, { rejectWithValue, dispatch, getState }) { | ||
const sid = sessionStorage.getItem('sid'); | ||
const refreshToken = sessionStorage.getItem('refreshToken'); | ||
try { | ||
const response = await getRefreshToken({ refreshToken, sid }); | ||
token.set(response.data.newAccessToken); | ||
dispatch(getCurrentUser()); | ||
return response.data; | ||
} catch (error) { | ||
sessionStorage.removeItem('token'); | ||
sessionStorage.removeItem('sid'); | ||
sessionStorage.removeItem('refreshToken'); | ||
token.unset(); | ||
showErrorMessage(error.message); | ||
return rejectWithValue(error.message); | ||
} | ||
}, | ||
); | ||
|
||
const authOperations = { | ||
logIn, | ||
logInGoogle, | ||
logOut, | ||
getCurrentUser, | ||
updateUserBalance, | ||
refresh, | ||
}; | ||
|
||
export default authOperations; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vite + React</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.jsx"></script> | ||
</body> | ||
</html> |
Oops, something went wrong.