From e3caba4dfbea78eedbcc7898aed637e2d353eca7 Mon Sep 17 00:00:00 2001 From: Jessica Mulein Date: Wed, 27 Nov 2024 20:52:33 +0000 Subject: [PATCH] Improve discriminator setup --- chili-and-cilantro-api/src/application.ts | 2 +- .../src/controllers/api/game.ts | 19 +- .../src/controllers/api/user.ts | 2 +- .../src/controllers/base.ts | 2 +- chili-and-cilantro-api/src/routers/api.ts | 11 +- chili-and-cilantro-api/src/services/action.ts | 208 +++++++++++------- chili-and-cilantro-api/tsconfig.app.json | 6 +- chili-and-cilantro-node-lib/src/index.ts | 2 + .../src/lib/discriminators/action.ts | 56 ++--- .../src/lib/interfaces/application.ts | 2 + .../interfaces/discriminator-collections.ts | 7 + .../src/lib}/interfaces/route-config.ts | 0 .../src/lib/interfaces/schema-data.ts | 5 +- chili-and-cilantro-node-lib/src/lib/schema.ts | 65 +++--- chili-and-cilantro-react/src/styles.scss | 26 +-- chili-and-cilantro-react/src/theme.tsx | 26 ++- 16 files changed, 240 insertions(+), 199 deletions(-) create mode 100644 chili-and-cilantro-node-lib/src/lib/interfaces/discriminator-collections.ts rename {chili-and-cilantro-api/src => chili-and-cilantro-node-lib/src/lib}/interfaces/route-config.ts (100%) diff --git a/chili-and-cilantro-api/src/application.ts b/chili-and-cilantro-api/src/application.ts index 90a6556..97e9cef 100644 --- a/chili-and-cilantro-api/src/application.ts +++ b/chili-and-cilantro-api/src/application.ts @@ -137,7 +137,7 @@ export class App implements IApplication { // init all middlewares and routes Middlewares.init(this.expressApp); - this._apiRouter = new ApiRouter(this.getModel, this.db.connection); + this._apiRouter = new ApiRouter(this); this._appRouter = new AppRouter(this._apiRouter); this._appRouter.init(this.expressApp, debug); // if none of the above handle the request, pass it to error handler diff --git a/chili-and-cilantro-api/src/controllers/api/game.ts b/chili-and-cilantro-api/src/controllers/api/game.ts index 3a89081..b5a2fa4 100644 --- a/chili-and-cilantro-api/src/controllers/api/game.ts +++ b/chili-and-cilantro-api/src/controllers/api/game.ts @@ -1,17 +1,18 @@ import { CardType, - GetModelFunction, IUserDocument, ModelName, TurnAction, UserNotFoundError, ValidationError, } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import { RouteConfig } from 'chili-and-cilantro-api/src/interfaces/route-config'; +import { + IApplication, + RouteConfig, +} from '@chili-and-cilantro/chili-and-cilantro-node-lib'; import { Request, Response } from 'express'; import { InvalidTokenError } from 'express-oauth2-jwt-bearer'; import { body } from 'express-validator'; -import { Connection } from 'mongoose'; import { ActionService } from '../../services/action'; import { ChefService } from '../../services/chef'; import { GameService } from '../../services/game'; @@ -24,13 +25,13 @@ export class GameController extends BaseController { private readonly playerService; private readonly gameService; - constructor(getModel: GetModelFunction, connection: Connection) { - super(getModel); - this.actionService = new ActionService(getModel, connection); - this.chefService = new ChefService(getModel); - this.playerService = new PlayerService(getModel); + constructor(application: IApplication) { + super(application.getModel); + this.actionService = new ActionService(application); + this.chefService = new ChefService(application.getModel); + this.playerService = new PlayerService(application.getModel); this.gameService = new GameService( - getModel, + application.getModel, this.actionService, this.chefService, this.playerService, diff --git a/chili-and-cilantro-api/src/controllers/api/user.ts b/chili-and-cilantro-api/src/controllers/api/user.ts index eeb46f0..e79d0d8 100644 --- a/chili-and-cilantro-api/src/controllers/api/user.ts +++ b/chili-and-cilantro-api/src/controllers/api/user.ts @@ -14,10 +14,10 @@ import { IUserResponse, ModelName, } from '@chili-and-cilantro/chili-and-cilantro-lib'; +import { RouteConfig } from '@chili-and-cilantro/chili-and-cilantro-node-lib'; import { Request, Response } from 'express'; import { body, query } from 'express-validator'; import { MongooseValidationError } from '../../errors/mongoose-validation-error'; -import { RouteConfig } from '../../interfaces/route-config'; import { findAuthToken } from '../../middlewares/authenticate-token'; import { JwtService } from '../../services/jwt'; import { RequestUserService } from '../../services/request-user'; diff --git a/chili-and-cilantro-api/src/controllers/base.ts b/chili-and-cilantro-api/src/controllers/base.ts index 7fefc38..1252d3e 100644 --- a/chili-and-cilantro-api/src/controllers/base.ts +++ b/chili-and-cilantro-api/src/controllers/base.ts @@ -7,6 +7,7 @@ import { IMongoErrors, IRequestUser, } from '@chili-and-cilantro/chili-and-cilantro-lib'; +import { RouteConfig } from '@chili-and-cilantro/chili-and-cilantro-node-lib'; import { NextFunction, Request, Response, Router } from 'express'; import { matchedData, @@ -14,7 +15,6 @@ import { ValidationError, validationResult, } from 'express-validator'; -import { RouteConfig } from '../interfaces/route-config'; import { authenticateToken } from '../middlewares/authenticate-token'; export abstract class BaseController { diff --git a/chili-and-cilantro-api/src/routers/api.ts b/chili-and-cilantro-api/src/routers/api.ts index 4659df9..69c9016 100644 --- a/chili-and-cilantro-api/src/routers/api.ts +++ b/chili-and-cilantro-api/src/routers/api.ts @@ -1,5 +1,4 @@ -import { GetModelFunction } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import { Connection } from 'mongoose'; +import { IApplication } from '@chili-and-cilantro/chili-and-cilantro-node-lib'; import { GameController } from '../controllers/api/game'; import { UserController } from '../controllers/api/user'; import { BaseRouter } from './base'; @@ -10,10 +9,10 @@ import { BaseRouter } from './base'; export class ApiRouter extends BaseRouter { private readonly userController: UserController; private readonly gameController: GameController; - constructor(getModel: GetModelFunction, connnection: Connection) { - super(getModel); - this.userController = new UserController(getModel); - this.gameController = new GameController(getModel, connnection); + constructor(application: IApplication) { + super(application.getModel); + this.userController = new UserController(application.getModel); + this.gameController = new GameController(application); this.router.use('/user', this.userController.router); this.router.use('/game', this.gameController.router); } diff --git a/chili-and-cilantro-api/src/services/action.ts b/chili-and-cilantro-api/src/services/action.ts index 1c15781..dd26a6a 100644 --- a/chili-and-cilantro-api/src/services/action.ts +++ b/chili-and-cilantro-api/src/services/action.ts @@ -37,17 +37,28 @@ import { IUserDocument, ModelName, } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import { ActionDiscriminatorsByActionType } from '@chili-and-cilantro/chili-and-cilantro-node-lib'; -import { Connection, Model } from 'mongoose'; +import { IApplication } from '@chili-and-cilantro/chili-and-cilantro-node-lib'; +import { Model } from 'mongoose'; export class ActionService { private readonly getModel: GetModelFunction; - private readonly actionDiscriminators: { [key in ActionType]: Model }; + private readonly actionDiscriminatorsByType: Record< + ActionType, + Model + >; - constructor(getModel: GetModelFunction, connection: Connection) { - this.getModel = getModel; - this.actionDiscriminators = ActionDiscriminatorsByActionType(connection); + constructor(application: IApplication) { + this.getModel = application.getModel; + this.actionDiscriminatorsByType = application.schemaMap.Action + .discriminators.byType as Record>; } + private async createAction( + action: ActionType, + data: U, + ): Promise { + return this.actionDiscriminatorsByType[action].create(data) as Promise; + } + public async getGameHistoryAsync(game: IGameDocument): Promise { const ActionModel = this.getModel(ModelName.Action); return ActionModel.find({ gameId: game._id }).sort({ @@ -59,97 +70,118 @@ export class ActionService { chef: IChefDocument, user: IUserDocument, ): Promise { - return this.actionDiscriminators.CREATE_GAME.create({ - gameId: game._id, - chefId: chef._id, - userId: user._id, - type: ActionType.CREATE_GAME, - details: {} as ICreateGameDetails, - round: constants.NONE, - } as ICreateGameAction); + return this.createAction( + ActionType.CREATE_GAME, + { + gameId: game._id, + chefId: chef._id, + userId: user._id, + type: ActionType.CREATE_GAME, + details: {} as ICreateGameDetails, + round: constants.NONE, + } as ICreateGameAction, + ); } public async joinGameAsync( game: IGameDocument, chef: IChefDocument, user: IUserDocument, ): Promise { - return this.actionDiscriminators.JOIN_GAME.create({ - gameId: game._id, - chefId: chef._id, - userId: user._id, - type: ActionType.JOIN_GAME, - details: {} as IJoinGameDetails, - round: constants.NONE, - } as IJoinGameAction); + return this.createAction( + ActionType.JOIN_GAME, + { + gameId: game._id, + chefId: chef._id, + userId: user._id, + type: ActionType.JOIN_GAME, + details: {} as IJoinGameDetails, + round: constants.NONE, + } as IJoinGameAction, + ); } public async startGameAsync( game: IGameDocument, ): Promise { - return this.actionDiscriminators.START_GAME.create({ - gameId: game._id, - chefId: game.hostChefId, - userId: game.hostUserId, - type: ActionType.START_GAME, - details: {} as IStartGameDetails, - round: game.currentRound, - } as IStartGameAction); + return this.createAction( + ActionType.START_GAME, + { + gameId: game._id, + chefId: game.hostChefId, + userId: game.hostUserId, + type: ActionType.START_GAME, + details: {} as IStartGameDetails, + round: game.currentRound, + } as IStartGameAction, + ); } public async expireGameAsync( game: IGameDocument, ): Promise { - return this.actionDiscriminators.EXPIRE_GAME.create({ - gameId: game._id, - chefId: game.hostChefId, - userId: game.hostUserId, - type: ActionType.EXPIRE_GAME, - details: {} as IExpireGameDetails, - round: game.currentRound, - } as IExpireGameAction); + return this.createAction( + ActionType.EXPIRE_GAME, + { + gameId: game._id, + chefId: game.hostChefId, + userId: game.hostUserId, + type: ActionType.EXPIRE_GAME, + details: {} as IExpireGameDetails, + round: game.currentRound, + } as IExpireGameAction, + ); } public async sendMessageAsync( game: IGameDocument, chef: IChefDocument, message: string, ): Promise { - return this.actionDiscriminators.MESSAGE.create({ - gameId: game._id, - chefId: chef._id, - userId: chef.userId, - type: ActionType.MESSAGE, - details: { - message: message, - } as IMessageDetails, - round: game.currentRound, - } as IMessageAction); + return this.createAction( + ActionType.MESSAGE, + { + gameId: game._id, + chefId: chef._id, + userId: chef.userId, + type: ActionType.MESSAGE, + details: { + message: message, + } as IMessageDetails, + round: game.currentRound, + } as IMessageAction, + ); } public async startBiddingAsync( game: IGameDocument, chef: IChefDocument, bid: number, ): Promise { - return this.actionDiscriminators.START_BIDDING.create({ - gameId: game._id, - chefId: chef._id, - userId: chef.userId, - type: ActionType.START_BIDDING, - details: { - bid: bid, - } as IStartBiddingDetails, - round: game.currentRound, - } as IStartBiddingAction); + return this.createAction( + ActionType.START_BIDDING, + { + gameId: game._id, + chefId: chef._id, + userId: chef.userId, + type: ActionType.START_BIDDING, + details: { + bid: bid, + } as IStartBiddingDetails, + round: game.currentRound, + } as IStartBiddingAction, + ); } public async passAsync( game: IGameDocument, chef: IChefDocument, ): Promise { - return this.actionDiscriminators.PASS.create({ - gameId: game._id, - chefId: chef._id, - userId: chef.userId, - type: ActionType.PASS, - details: {} as IPassDetails, - round: game.currentRound, - } as IPassAction); + return this.createAction( + ActionType.PASS, + { + gameId: game._id, + chefId: chef._id, + userId: chef.userId, + type: ActionType.PASS, + details: {} as IPassDetails, + round: game.currentRound, + } as IPassAction, + ); } public async placeCardAsync( game: IGameDocument, @@ -157,30 +189,36 @@ export class ActionService { cardType: CardType, position: number, ): Promise { - return this.actionDiscriminators.PLACE_CARD.create({ - gameId: game._id, - chefId: chef._id, - userId: chef.userId, - type: ActionType.PLACE_CARD, - details: { - cardType: cardType, - position: position, - } as IPlaceCardDetails, - round: game.currentRound, - } as IPlaceCardAction); + return this.createAction( + ActionType.PLACE_CARD, + { + gameId: game._id, + chefId: chef._id, + userId: chef.userId, + type: ActionType.PLACE_CARD, + details: { + cardType: cardType, + position: position, + } as IPlaceCardDetails, + round: game.currentRound, + } as IPlaceCardAction, + ); } public async quitGameAsync( game: IGameDocument, chef: IChefDocument, ): Promise { - return this.actionDiscriminators.QUIT_GAME.create({ - gameId: game._id, - chefId: chef._id, - userId: chef.userId, - type: ActionType.QUIT_GAME, - details: {} as IQuitGameDetails, - round: game.currentRound, - } as IQuitGameAction); + return this.createAction( + ActionType.QUIT_GAME, + { + gameId: game._id, + chefId: chef._id, + userId: chef.userId, + type: ActionType.QUIT_GAME, + details: {} as IQuitGameDetails, + round: game.currentRound, + } as IQuitGameAction, + ); } } diff --git a/chili-and-cilantro-api/tsconfig.app.json b/chili-and-cilantro-api/tsconfig.app.json index 98cefcb..ca8a402 100644 --- a/chili-and-cilantro-api/tsconfig.app.json +++ b/chili-and-cilantro-api/tsconfig.app.json @@ -6,5 +6,9 @@ "types": ["node"] }, "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], - "include": ["src/**/*.ts", "src/types/express.d.ts"] + "include": [ + "src/**/*.ts", + "src/types/express.d.ts", + "../chili-and-cilantro-node-lib/src/lib/interfaces/route-config.ts" + ] } diff --git a/chili-and-cilantro-node-lib/src/index.ts b/chili-and-cilantro-node-lib/src/index.ts index 847bf90..d40f774 100644 --- a/chili-and-cilantro-node-lib/src/index.ts +++ b/chili-and-cilantro-node-lib/src/index.ts @@ -1,6 +1,8 @@ export * from './lib/action-schema-map'; export * from './lib/discriminators/action'; export * from './lib/interfaces/application'; +export * from './lib/interfaces/discriminator-collections'; +export * from './lib/interfaces/route-config'; export * from './lib/interfaces/schema-data'; export * from './lib/interfaces/schema-model-data'; export * from './lib/models/action'; diff --git a/chili-and-cilantro-node-lib/src/lib/discriminators/action.ts b/chili-and-cilantro-node-lib/src/lib/discriminators/action.ts index 87ab42b..19eeb2e 100644 --- a/chili-and-cilantro-node-lib/src/lib/discriminators/action.ts +++ b/chili-and-cilantro-node-lib/src/lib/discriminators/action.ts @@ -3,28 +3,17 @@ import { ActionTypeRecordMap, IActionDocument, } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import mongoose, { Connection, Model, Schema } from 'mongoose'; +import { Model, Schema } from 'mongoose'; import { ActionSchemas } from '../action-schema-map'; +import { IDiscriminatorCollections } from '../interfaces/discriminator-collections'; -const BaseActionSchema = new Schema( - {}, - { discriminatorKey: 'type', timestamps: true }, -); -const BaseActionModel = (connection: Connection) => - connection.model('BaseAction', BaseActionSchema); - -function generateDiscriminators( - connection: Connection, - actionEnum: Record, - actionSchemas: Record, - // actionDocumentTypeMap: ActionDocumentTypes, -): { - discriminatorRecords: Record>; - discriminatorArray: Array>; -} { - const baseModel = BaseActionModel(connection); - const discriminatorRecords: Record> = {}; - const discriminatorArray: Array> = []; +function generateDiscriminators( + baseModel: Model, + actionEnum: Record, + actionSchemas: Record, +): IDiscriminatorCollections { + const discriminatorRecords: Record> = {}; + const discriminatorArray: Array> = []; Object.keys(actionEnum).forEach((actionKey) => { const action = actionEnum[actionKey as keyof typeof actionEnum]; @@ -32,30 +21,15 @@ function generateDiscriminators( //const type = actionDocumentTypeMap[action]; // Ensure the correct type is inferred here - const discriminator = baseModel.discriminator(action, schema); + const discriminator = baseModel.discriminator(action, schema); discriminatorRecords[action] = discriminator; discriminatorArray.push(discriminator); }); - return { discriminatorRecords, discriminatorArray }; + return { byType: discriminatorRecords, array: discriminatorArray }; } -const ActionDiscriminators = (connection: Connection) => - generateDiscriminators( - connection, - ActionTypeRecordMap, - ActionSchemas, - // ActionDocumentTypesMap, - ); -const ActionDiscriminatorsByActionType = ( - connection: Connection, -): { [key in ActionType]: Model } => - ActionDiscriminators(connection).discriminatorRecords as { - [key in ActionType]: Model; - }; - -export { - ActionDiscriminators, - ActionDiscriminatorsByActionType, - BaseActionModel, -}; +export const ActionDiscriminators = ( + baseModel: Model, +): IDiscriminatorCollections => + generateDiscriminators(baseModel, ActionTypeRecordMap, ActionSchemas); diff --git a/chili-and-cilantro-node-lib/src/lib/interfaces/application.ts b/chili-and-cilantro-node-lib/src/lib/interfaces/application.ts index 3635f4c..8ca244a 100644 --- a/chili-and-cilantro-node-lib/src/lib/interfaces/application.ts +++ b/chili-and-cilantro-node-lib/src/lib/interfaces/application.ts @@ -1,4 +1,5 @@ import { GetModelFunction } from '@chili-and-cilantro/chili-and-cilantro-lib'; +import { SchemaMap } from 'chili-and-cilantro-node-lib/src/types/shared-types'; import mongoose from 'mongoose'; export interface IApplication { @@ -6,4 +7,5 @@ export interface IApplication { get ready(): boolean; start(): Promise; getModel: GetModelFunction; + get schemaMap(): SchemaMap; } diff --git a/chili-and-cilantro-node-lib/src/lib/interfaces/discriminator-collections.ts b/chili-and-cilantro-node-lib/src/lib/interfaces/discriminator-collections.ts new file mode 100644 index 0000000..8c6cba7 --- /dev/null +++ b/chili-and-cilantro-node-lib/src/lib/interfaces/discriminator-collections.ts @@ -0,0 +1,7 @@ +import { IBaseDocument } from '@chili-and-cilantro/chili-and-cilantro-lib'; +import { Model } from 'mongoose'; + +export interface IDiscriminatorCollections> { + byType: Record>; + array: Array>; +} diff --git a/chili-and-cilantro-api/src/interfaces/route-config.ts b/chili-and-cilantro-node-lib/src/lib/interfaces/route-config.ts similarity index 100% rename from chili-and-cilantro-api/src/interfaces/route-config.ts rename to chili-and-cilantro-node-lib/src/lib/interfaces/route-config.ts diff --git a/chili-and-cilantro-node-lib/src/lib/interfaces/schema-data.ts b/chili-and-cilantro-node-lib/src/lib/interfaces/schema-data.ts index 4023e03..e2400e9 100644 --- a/chili-and-cilantro-node-lib/src/lib/interfaces/schema-data.ts +++ b/chili-and-cilantro-node-lib/src/lib/interfaces/schema-data.ts @@ -3,7 +3,8 @@ import { ModelName, ModelNameCollection, } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import { Model, Schema } from 'mongoose'; +import { Schema } from 'mongoose'; +import { IDiscriminatorCollections } from './discriminator-collections'; export interface ISchemaData> { name: ModelName; @@ -11,5 +12,5 @@ export interface ISchemaData> { collection: ModelNameCollection; schema: Schema; path: string; - discriminators?: Array>; + discriminators?: IDiscriminatorCollections; } diff --git a/chili-and-cilantro-node-lib/src/lib/schema.ts b/chili-and-cilantro-node-lib/src/lib/schema.ts index 4ccc0d7..03fcb9e 100644 --- a/chili-and-cilantro-node-lib/src/lib/schema.ts +++ b/chili-and-cilantro-node-lib/src/lib/schema.ts @@ -13,7 +13,7 @@ import { ModelName, ModelNameCollection, } from '@chili-and-cilantro/chili-and-cilantro-lib'; -import { Connection, Schema as MongooseSchema } from 'mongoose'; +import { Connection, Model, Schema as MongooseSchema } from 'mongoose'; import { SchemaMap } from '../types/shared-types'; import { ActionDiscriminators } from './discriminators/action'; import { ISchemaData } from './interfaces/schema-data'; @@ -71,13 +71,21 @@ export const Schema: { [key in ModelName]: ISchemaData> } = { export function getSchemaModel, D>( modelName: ModelName, connection: Connection, -) { + discriminatorCallback?: (model: Model) => void, +): ISchemaModelData { const value = Schema[modelName]; - return connection.model( + const newModel = connection.model( modelName, value.schema as MongooseSchema, value.collection, ); + return { + ...value, + model: newModel, + ...(discriminatorCallback + ? { discriminators: discriminatorCallback(newModel) } + : {}), + }; } /** @@ -85,35 +93,28 @@ export function getSchemaModel, D>( * This includes the name, description, plural name, and api name of each model. */ export function getSchemaMap(connection: Connection): SchemaMap { - const { discriminatorArray: actionDiscriminatorArray } = - ActionDiscriminators(connection); return { - [ModelName.Action]: { - ...Schema[ModelName.Action], - model: getSchemaModel( - ModelName.Action, - connection, - ), - discriminators: actionDiscriminatorArray, - } as ISchemaModelData, - [ModelName.Chef]: { - ...Schema[ModelName.Chef], - model: getSchemaModel(ModelName.Chef, connection), - } as ISchemaModelData, - [ModelName.EmailToken]: { - ...Schema[ModelName.EmailToken], - model: getSchemaModel( - ModelName.EmailToken, - connection, - ), - } as ISchemaModelData, - [ModelName.Game]: { - ...Schema[ModelName.Game], - model: getSchemaModel(ModelName.Game, connection), - } as ISchemaModelData, - [ModelName.User]: { - ...Schema[ModelName.User], - model: getSchemaModel(ModelName.User, connection), - } as ISchemaModelData, + [ModelName.Action]: getSchemaModel( + ModelName.Action, + connection, + (baseModel: Model) => + ActionDiscriminators(baseModel), + ), + [ModelName.Chef]: getSchemaModel( + ModelName.Chef, + connection, + ), + [ModelName.EmailToken]: getSchemaModel( + ModelName.EmailToken, + connection, + ), + [ModelName.Game]: getSchemaModel( + ModelName.Game, + connection, + ), + [ModelName.User]: getSchemaModel( + ModelName.User, + connection, + ), }; } diff --git a/chili-and-cilantro-react/src/styles.scss b/chili-and-cilantro-react/src/styles.scss index 33a331d..3ae8203 100644 --- a/chili-and-cilantro-react/src/styles.scss +++ b/chili-and-cilantro-react/src/styles.scss @@ -7,19 +7,19 @@ $red-chili: #ff081f; $red-chili-shadow: #9c0020; // Theme colors -$primary-dark: #1b1b1f; // Dark slate (primary dark background) -$secondary-dark: #292a2f; // Lighter dark shade (card background, headers) -$highlight-color: #f39c12; // Spicy yellow-orange (highlight, links, buttons) -$accent-color: #8e44ad; // Bold purple (secondary accents, decorative elements) -$text-color: #eaeaea; // Light gray for readability -$text-muted: #b3b3b3; // Muted gray for secondary text -$danger-color: #e74c3c; // Chili danger red (warnings, alerts) -$success-color: #27ae60; // Cilantro green (success feedback) -$border-color: #3c3c43; // Subtle borders and dividers -// -$primary-color: $primary-dark; -$light-color: $logo-background-color; // Light background color -$background-color: $logo-background-color; // Light background color +$primary-dark: #333333; // Darker shade for text +$secondary-dark: #666666; // Medium gray for secondary text +$highlight-color: #7edb0e; // Green chili as highlight +$accent-color: #ff081f; // Red chili as accent +$text-color: #000000; // Black text for readability +$text-muted: #666666; // Muted gray for secondary text +$danger-color: #ff081f; // Red chili for danger/alerts +$success-color: #7edb0e; // Green chili for success feedback +$border-color: #e0e0e0; // Light gray for borders + +$primary-color: $green-chili; +$light-color: #ffffff; // White background color +$background-color: #ffffff; // White background color // Button hover effects $highlight-hover: lighten($highlight-color, 10%); diff --git a/chili-and-cilantro-react/src/theme.tsx b/chili-and-cilantro-react/src/theme.tsx index f9bec53..afde261 100644 --- a/chili-and-cilantro-react/src/theme.tsx +++ b/chili-and-cilantro-react/src/theme.tsx @@ -6,34 +6,46 @@ const theme = createTheme({ primary: { main: '#7EDB0E', // green-chili dark: '#0E683C', // green-chili-shadow - contrastText: '#FFFDD0', // background-color + contrastText: '#FFFFFF', // white for better contrast }, secondary: { main: '#FF081F', // red-chili dark: '#9C0020', // red-chili-shadow - contrastText: '#FFFDD0', // background-color + contrastText: '#FFFFFF', // white for better contrast }, background: { - default: '#FFFDD0', // background-color - paper: '#FFFDD0', + default: '#FFFFFF', // white background + paper: '#FFFFFF', }, text: { primary: '#000000', - secondary: '#000000', + secondary: '#333333', }, }, components: { MuiAppBar: { styleOverrides: { root: { - color: '#FFFDD0', // background-color for contrast + backgroundColor: '#7EDB0E', // green-chili for AppBar + color: '#FFFFFF', // white text for contrast + }, + }, + }, + MuiButton: { + styleOverrides: { + root: { + backgroundColor: '#7EDB0E', // green-chili for buttons + color: '#FFFFFF', // white text for contrast + '&:hover': { + backgroundColor: '#0E683C', // darker green on hover + }, }, }, }, MuiInputLabel: { styleOverrides: { root: { - color: 'inherit', + color: '#333333', // darker text for better readability }, }, },