CryptoTracker ― это одностраничное React-приложение для отслеживания актуальных цен криптовалют, управления портфелем и просмотра последних новостей из мира криптоиндустрии.
В проекте используются:
- React (Vite)
- TypeScript
- Tailwind CSS для стилизации
- Context API для управления темой, данными портфеля и данными криптовалют
- Axios для HTTP-запросов к CoinGecko и CryptoPanic
- Vite proxy для обхода CORS при обращении к внешним API
- Функционал
- Технологии
- Структура проекта
- Установка и настройка
- Скрипты командной строки
- Описание компонентов
- Context API
- Сборка и деплой
- Лицензия
-
Реальное время (Real-Time Prices)
- Отображает список топ-50 криптовалют по капитализации (CoinGecko).
- Показаны: название, символ, текущая цена, изменение за 24h, рыночная капитализация, объём торгов, график за последние 7 дней.
-
График цены (Price Chart)
- При клике на криптовалюту (в таблице) отображается подробный график изменения цены за выбранный период (по умолчанию 7 дней).
- Исторические данные запрашиваются с CoinGecko (эндпоинт
/coins/{id}/market_chart).
-
Портфолио (Portfolio)
- Пользователь может добавлять/удалять позиции (монеты + количество).
- Подсчитывается общая стоимость портфеля и отображается список позиций.
- Данные хранятся в
localStorage, чтобы информация сохранялась между перезагрузками страницы.
-
Новости (Crypto News)
- В разделе «Crypto News» отображаются новости из CryptoPanic (если указан API-ключ), либо запасные «fallback»-статьи при отсутствии ключа или при ошибке.
- Отображаются: заголовок, источник, дата публикации, краткое описание (summary).
-
Тёмная/светлая тема (Theme Switcher)
- Переключение между светлой и тёмной темой оформления.
- Выбор темы сохраняется в
localStorage.
-
Навигация по секциям (Header)
- Фиксированная шапка (
Header) с меню-скроллом по разделам: Home, Prices, Chart, Portfolio, News. - Активная секция подсвечивается при прокрутке страницы (скролл-spy).
- Фиксированная шапка (
- React + TypeScript
- Vite
- Tailwind CSS
- Axios для HTTP-запросов
- Context API (React) для управления состоянием:
ThemeContext― тема светлая/тёмнаяPortfolioContext― данные портфеляCryptoDataContext― данные криптовалют (список, график)
- react-hot-toast для всплывающих уведомлений (добавление/удаление позиций)
- Vite Proxy для обхода CORS при запросах к CoinGecko/CryptoPanic
- ESLint/Prettier (рекомендуется) для форматирования и проверки кода
crypto-tracker/
├── public/
│ └── index.html
├── src/
│ ├── api/
│ │ └── api.ts # Логика работы с CoinGecko и CryptoPanic
│ ├── components/
│ │ ├── layout/
│ │ │ ├── Header.tsx # Шапка сайта, меню навигации
│ │ │ └── Footer.tsx # Футер
│ │ ├── crypto/
│ │ │ ├── CryptoTable.tsx # Таблица с топ‐50 криптовалютами
│ │ │ ├── CryptoChart.tsx # Компонент с графиком (Recharts / Chart.js)
│ │ │ ├── Portfolio.tsx # UI для управления портфелем
│ │ │ └── News.tsx # Список новостей (CryptoPanic / fallback)
│ ├── context/
│ │ ├── ThemeContext.tsx # Провайдер для темы (light/dark)
│ │ ├── PortfolioContext.tsx # Провайдер данных портфеля
│ │ └── CryptoDataContext.tsx # Провайдер данных криптовалют (fetch + cache)
│ ├── types/
│ │ └── index.ts # Определения Typescript‐типов (CryptoCoin, NewsItem и т.д.)
│ ├── App.tsx # Главный компонент приложения
│ ├── main.tsx # Точка входа (рендер в DOM)
│ └── index.css # Tailwind CSS, глобальные стили
├── .env # Переменные окружения (API-ключи)
├── vite.config.ts # Конфиг Vite (proxy для CORS, плагины)
├── package.json
├── tsconfig.json
└── README.md # Вы сейчас читаете
git clone https://github.com/ваш-логин/crypto-tracker.git
cd crypto-trackernpm install
# или
yarn installСоздайте в корне проекта файл .env (обычно копируется от .env.example, если он есть) и пропишите туда:
# .env
# -----------------------------------------
# Если у вас есть Pro-ключ CoinGecko, его нужно передать в эту переменную.
# Без ключа можно работать в публичном режиме, но не все эндпоинты будут доступны (401, 429).
VITE_CG_API_KEY=ваш_CoinGecko_Pro_API_KEY
# (Опционально) Если хотите подтягивать новости из КryptoPanic, укажите ключ:
VITE_CP_API_KEY=ваш_CryptoPanic_API_KEY
# -----------------------------------------Почему переменные называются
VITE_...:
Vite по умолчанию «подключает» в клиентскую часть только переменные окружения с префиксомVITE_.
При сборке они будут внедрены в код.
Если вы не собираетесь получать новости из CryptoPanic, можете оставить VITE_CP_API_KEY пустым ― будет использован «fallback» (запасные) новости.
В файле vite.config.ts должны быть прописаны правила проксирования запросов:
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
proxy: {
// ====== CoinGecko (GET /coins/markets, GET /coins/{id}/market_chart) ======
'/api/coins': {
target: 'https://api.coingecko.com/api/v3',
changeOrigin: true,
secure: true,
rewrite: (path) => path.replace(/^\/api\/coins/, '/coins'),
},
// ====== CryptoPanic (GET /posts/) ======
'/api/posts': {
target: 'https://cryptopanic.com/api/v1',
changeOrigin: true,
secure: true,
rewrite: (path) => path.replace(/^\/api\/posts/, '/posts'),
},
},
},
});- Любой запрос к
/api/coins/...автоматически будет перенаправляться наhttps://api.coingecko.com/api/v3/coins/.... - Любой запрос к
/api/posts/...будет идти наhttps://cryptopanic.com/api/v1/posts/....
Благодаря этому в браузере не возникает ошибок CORS, поскольку все запросы «выглядят» как запросы на тот же origin (localhost:5173).
В package.json прописаны стандартные команды:
{
"scripts": {
"dev": "vite", // Запуск dev-сервера (http://localhost:5173)
"build": "vite build", // Сборка приложения для продакшена
"preview": "vite preview", // Локальный режим «превью» собранного бандла
"lint": "eslint src --ext .ts,.tsx", // Запуск ESLint по коду (по желанию)
"format": "prettier --write .", // Форматирование кода (Prettier)
...
}
}-
npm run dev(илиyarn dev)
Запускает dev-сервер наhttp://localhost:5173. Автообновление при изменениях кода. -
npm run build(илиyarn build)
Создаёт оптимизированный бандл в папкеdist/(готовый к деплою). -
npm run preview(илиyarn preview)
Локальный HTTP-сервер, раздающий содержимоеdist/, чтобы проверить после сборки. -
npm run lint
Проверяет файлы вsrc/на соответствие правилам ESLint (если настроен). -
npm run format
Форматирует весь проект с помощью Prettier (если настроен).
- Фиксированная шапка (fixed-top), содержащая:
- Логотип/название проекта.
- Меню навигации по секциям: Home, Prices, Chart, Portfolio, News.
- Кнопка переключения темы (светлая/тёмная).
- Получает пропс
activeSection: stringи подсвечивает текущую активную ссылку.
- Простой футер с авторскими правами, ссылками на репозиторий и контактами (опционально).
- Отображает таблицу с топ-50 криптовалютами по капитализации:
- Номер (rank), название (с иконкой), символ, текущая цена, изменение за 24 ч (с цветом), рыночная капитализация, объём торгов за 24 ч, мини-график за 7 дней (sparkline).
- При клике на строку таблицы ― выставляет выбранную монету в
CryptoDataContext, чтобыCryptoChartмог отобразить её график.
- Отображает линейный/свечной график (Recharts/Chart.js) для выбранной монеты:
- Получает идентификатор выбранной монеты из
CryptoDataContext. - Запрашивает исторические данные через
fetchCoinDetails(coinId, days). - Позволяет переключать период (7 дней, 30 дней, 90 дней, год, max).
- При ошибке (401, 429) показывает сообщение о невозможности загрузить данные.
- Получает идентификатор выбранной монеты из
- Компонент для управления «виртуальным» портфелем:
- Форма добавления новой позиции (выбор монеты, ввод количества).
- Список текущих позиций (название, символ, количество, текущая стоимость, изменение стоимости).
- Кнопка удаления позиции.
- Итоговая стоимость портфеля.
- Данные хранятся в
localStorageчерезPortfolioContext.
- Компонент для отображения списка новостей:
- Если указан
VITE_CP_API_KEY, делает запрос к CryptoPanic/api/posts/?auth_token=.... - Если нет ключа или пришла ошибка, рендерятся заранее заготовленные «fallback» статьи.
- Для каждой новости показывается заголовок (ссылка), источник, дата публикации, и, если доступно, краткое описание (summary).
- Если указан
- Провайдер темы:
- Хранит состояние
theme: 'light' | 'dark'. - Функция
toggleTheme()для переключения. - Текущая тема сохраняется в
localStorageи подтягивается при загрузке.
- Хранит состояние
- Провайдер портфеля:
- Состояние
portfolio: Array<{ coinId: string; amount: number }>(или более сложная структура). - Функции:
addPosition(coinId: string, amount: number)removePosition(coinId: string)updatePosition(coinId: string, newAmount: number)
- Данные хранятся/читаются из
localStorage, чтобы сохранялись при перезагрузке страницы.
- Состояние
- Провайдер данных криптовалют:
- Состояние:
coins: CryptoCoin[]― массив с данными топ-50 монет.selectedCoinId: string | null― текущая монета для графика.historicalData: any― данные для графика (массива точек).isLoading: boolean/error: string | null.
- Функции:
refreshData()― получить актуальный списокcoinsчерезfetchCryptoData().getHistoricalData(coinId: string, days: string)― получить черезfetchCoinDetails(coinId, days).- Автообновление списка монет в заданном интервале (например, каждые 30 с).
- Подписка компонентов
CryptoTableиCryptoChartна данные из этого контекста.
- Состояние:
- Убедитесь, что в
.envпрописаны ваши ключи (VITE_CG_API_KEY,VITE_CP_API_KEY) перед сборкой. - Запустите:
npm run build # или yarn build - После успешной сборки всё содержимое будет лежать в папке
dist/.
Деплой:- Можно раздать
dist/на любом статическом хостинге (Netlify, Vercel, GitHub Pages, Firebase Hosting и т.д.). - Если деплойите на свой сервер (Nginx, Apache), убедитесь, что настроена корректная отдача
index.htmlдля всех путей (SPA).
- Можно раздать
Важно:
- На продакшене proxy не работает так, как в режиме
dev. Поэтому в продакшн-окружении обязательно нужно:
- Либо выполнять запросы к внешним API с собственного бэкенда (например, node/express),
- Либо настраивать сервер (Nginx) на проксирование внешних запросов,
- Либо пользоваться публичными прокси/функциями (Serverless),
- Либо напрямую обращаться к API CoinGecko (если они поддерживают CORS для продакшена ― к сожалению, без Pro-ключа уже отказано CORS’ом).
Этот проект распространяется под лицензией MIT. См. файл LICENSE для подробностей.
Автор:
Дмитрий Красных
Email: dimathedevoloper@gmail.com
GitHub: github.com/DmitriyKrasnyh
Спасибо за использование CryptoTracker! 🚀 Если у вас возникнут вопросы или предложения — создавайте issue в репозитории или пишите прямо в Pull Request.