feat: implement complete Phase 2 frontend foundation with React 18
Major milestone: Frontend implementation complete for Shattered Void MMO FRONTEND IMPLEMENTATION: - React 18 + TypeScript + Vite development environment - Tailwind CSS with custom dark theme for sci-fi aesthetic - Zustand state management with authentication persistence - Socket.io WebSocket client with auto-reconnection - Protected routing with authentication guards - Responsive design with mobile-first approach AUTHENTICATION SYSTEM: - Login/register forms with comprehensive validation - JWT token management with localStorage persistence - Password strength validation and user feedback - Protected routes and authentication guards CORE GAME INTERFACE: - Colony management dashboard with real-time updates - Resource display with live production tracking - WebSocket integration for real-time game events - Navigation with connection status indicator - Toast notifications for user feedback BACKEND ENHANCEMENTS: - Complete Research System with technology tree (23 technologies) - Fleet Management System with ship designs and movement - Enhanced Authentication with email verification and password reset - Complete game tick integration for all systems - Advanced WebSocket events for real-time updates ARCHITECTURE FEATURES: - Type-safe TypeScript throughout - Component-based architecture with reusable UI elements - API client with request/response interceptors - Error handling and loading states - Performance optimized builds with code splitting Phase 2 Status: Frontend foundation complete (Week 1-2 objectives met) Ready for: Colony management, fleet operations, research interface Next: Enhanced gameplay features and admin interface 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8d9ef427be
commit
d41d1e8125
130 changed files with 33588 additions and 14817 deletions
|
|
@ -10,8 +10,8 @@ const serviceLocator = require('../../services/ServiceLocator');
|
|||
|
||||
// Create resource service with WebSocket integration
|
||||
function getResourceService() {
|
||||
const gameEventService = serviceLocator.get('gameEventService');
|
||||
return new ResourceService(gameEventService);
|
||||
const gameEventService = serviceLocator.get('gameEventService');
|
||||
return new ResourceService(gameEventService);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -19,31 +19,31 @@ function getResourceService() {
|
|||
* GET /api/player/resources
|
||||
*/
|
||||
const getPlayerResources = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
|
||||
logger.info('Player resources request received', {
|
||||
correlationId,
|
||||
playerId
|
||||
});
|
||||
logger.info('Player resources request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const resources = await resourceService.getPlayerResources(playerId, correlationId);
|
||||
const resourceService = getResourceService();
|
||||
const resources = await resourceService.getPlayerResources(playerId, correlationId);
|
||||
|
||||
logger.info('Player resources retrieved', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resourceCount: resources.length
|
||||
});
|
||||
logger.info('Player resources retrieved', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resourceCount: resources.length,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources retrieved successfully',
|
||||
data: {
|
||||
resources
|
||||
},
|
||||
correlationId
|
||||
});
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources retrieved successfully',
|
||||
data: {
|
||||
resources,
|
||||
},
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -51,31 +51,31 @@ const getPlayerResources = asyncHandler(async (req, res) => {
|
|||
* GET /api/player/resources/summary
|
||||
*/
|
||||
const getPlayerResourceSummary = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
|
||||
logger.info('Player resource summary request received', {
|
||||
correlationId,
|
||||
playerId
|
||||
});
|
||||
logger.info('Player resource summary request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const summary = await resourceService.getPlayerResourceSummary(playerId, correlationId);
|
||||
const resourceService = getResourceService();
|
||||
const summary = await resourceService.getPlayerResourceSummary(playerId, correlationId);
|
||||
|
||||
logger.info('Player resource summary retrieved', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resourceTypes: Object.keys(summary)
|
||||
});
|
||||
logger.info('Player resource summary retrieved', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resourceTypes: Object.keys(summary),
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource summary retrieved successfully',
|
||||
data: {
|
||||
resources: summary
|
||||
},
|
||||
correlationId
|
||||
});
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource summary retrieved successfully',
|
||||
data: {
|
||||
resources: summary,
|
||||
},
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -83,31 +83,31 @@ const getPlayerResourceSummary = asyncHandler(async (req, res) => {
|
|||
* GET /api/player/resources/production
|
||||
*/
|
||||
const getResourceProduction = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
|
||||
logger.info('Resource production request received', {
|
||||
correlationId,
|
||||
playerId
|
||||
});
|
||||
logger.info('Resource production request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const production = await resourceService.calculatePlayerResourceProduction(playerId, correlationId);
|
||||
const resourceService = getResourceService();
|
||||
const production = await resourceService.calculatePlayerResourceProduction(playerId, correlationId);
|
||||
|
||||
logger.info('Resource production calculated', {
|
||||
correlationId,
|
||||
playerId,
|
||||
productionData: production
|
||||
});
|
||||
logger.info('Resource production calculated', {
|
||||
correlationId,
|
||||
playerId,
|
||||
productionData: production,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource production retrieved successfully',
|
||||
data: {
|
||||
production
|
||||
},
|
||||
correlationId
|
||||
});
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource production retrieved successfully',
|
||||
data: {
|
||||
production,
|
||||
},
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -115,51 +115,51 @@ const getResourceProduction = asyncHandler(async (req, res) => {
|
|||
* POST /api/player/resources/add
|
||||
*/
|
||||
const addResources = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const { resources } = req.body;
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const { resources } = req.body;
|
||||
|
||||
// Only allow in development environment
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
logger.warn('Resource addition attempted in production', {
|
||||
correlationId,
|
||||
playerId
|
||||
});
|
||||
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: 'Resource addition not allowed in production',
|
||||
correlationId
|
||||
});
|
||||
}
|
||||
|
||||
logger.info('Resource addition request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resources
|
||||
// Only allow in development environment
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
logger.warn('Resource addition attempted in production', {
|
||||
correlationId,
|
||||
playerId,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const updatedResources = await resourceService.addPlayerResources(
|
||||
playerId,
|
||||
resources,
|
||||
correlationId
|
||||
);
|
||||
|
||||
logger.info('Resources added successfully', {
|
||||
correlationId,
|
||||
playerId,
|
||||
updatedResources
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
message: 'Resource addition not allowed in production',
|
||||
correlationId,
|
||||
});
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources added successfully',
|
||||
data: {
|
||||
updatedResources
|
||||
},
|
||||
correlationId
|
||||
});
|
||||
logger.info('Resource addition request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
resources,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const updatedResources = await resourceService.addPlayerResources(
|
||||
playerId,
|
||||
resources,
|
||||
correlationId,
|
||||
);
|
||||
|
||||
logger.info('Resources added successfully', {
|
||||
correlationId,
|
||||
playerId,
|
||||
updatedResources,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources added successfully',
|
||||
data: {
|
||||
updatedResources,
|
||||
},
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -167,41 +167,41 @@ const addResources = asyncHandler(async (req, res) => {
|
|||
* POST /api/player/resources/transfer
|
||||
*/
|
||||
const transferResources = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const { fromColonyId, toColonyId, resources } = req.body;
|
||||
const correlationId = req.correlationId;
|
||||
const playerId = req.user.playerId;
|
||||
const { fromColonyId, toColonyId, resources } = req.body;
|
||||
|
||||
logger.info('Resource transfer request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
resources
|
||||
});
|
||||
logger.info('Resource transfer request received', {
|
||||
correlationId,
|
||||
playerId,
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
resources,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const result = await resourceService.transferResourcesBetweenColonies(
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
resources,
|
||||
playerId,
|
||||
correlationId
|
||||
);
|
||||
const resourceService = getResourceService();
|
||||
const result = await resourceService.transferResourcesBetweenColonies(
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
resources,
|
||||
playerId,
|
||||
correlationId,
|
||||
);
|
||||
|
||||
logger.info('Resources transferred successfully', {
|
||||
correlationId,
|
||||
playerId,
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
transferResult: result
|
||||
});
|
||||
logger.info('Resources transferred successfully', {
|
||||
correlationId,
|
||||
playerId,
|
||||
fromColonyId,
|
||||
toColonyId,
|
||||
transferResult: result,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources transferred successfully',
|
||||
data: result,
|
||||
correlationId
|
||||
});
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resources transferred successfully',
|
||||
data: result,
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -209,35 +209,35 @@ const transferResources = asyncHandler(async (req, res) => {
|
|||
* GET /api/player/resources/types
|
||||
*/
|
||||
const getResourceTypes = asyncHandler(async (req, res) => {
|
||||
const correlationId = req.correlationId;
|
||||
const correlationId = req.correlationId;
|
||||
|
||||
logger.info('Resource types request received', {
|
||||
correlationId
|
||||
});
|
||||
logger.info('Resource types request received', {
|
||||
correlationId,
|
||||
});
|
||||
|
||||
const resourceService = getResourceService();
|
||||
const resourceTypes = await resourceService.getResourceTypes(correlationId);
|
||||
const resourceService = getResourceService();
|
||||
const resourceTypes = await resourceService.getResourceTypes(correlationId);
|
||||
|
||||
logger.info('Resource types retrieved', {
|
||||
correlationId,
|
||||
count: resourceTypes.length
|
||||
});
|
||||
logger.info('Resource types retrieved', {
|
||||
correlationId,
|
||||
count: resourceTypes.length,
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource types retrieved successfully',
|
||||
data: {
|
||||
resourceTypes
|
||||
},
|
||||
correlationId
|
||||
});
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: 'Resource types retrieved successfully',
|
||||
data: {
|
||||
resourceTypes,
|
||||
},
|
||||
correlationId,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
getPlayerResources,
|
||||
getPlayerResourceSummary,
|
||||
getResourceProduction,
|
||||
addResources,
|
||||
transferResources,
|
||||
getResourceTypes
|
||||
};
|
||||
getPlayerResources,
|
||||
getPlayerResourceSummary,
|
||||
getResourceProduction,
|
||||
addResources,
|
||||
transferResources,
|
||||
getResourceTypes,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue