diff --git a/api/apiBaseRouter.js b/api/apiBaseRouter.js new file mode 100644 index 0000000000000000000000000000000000000000..ebf3692bfd9c1afd30137ed0ea24b123ded6d3cc --- /dev/null +++ b/api/apiBaseRouter.js @@ -0,0 +1,14 @@ +const healthCheckRouter = require('./health-check/routes'); +const layoutRouter = require('./layout/routes'); +const apiBaseRouter = require('express').Router(); + +// Exposed endpoints +apiBaseRouter.use('/health-check', healthCheckRouter); + +// apiBaseRouter.use('/pan', panRouter); + +// apiBaseRouter.use('/otp', otpRouter); + +apiBaseRouter.use('/widget', layoutRouter); + +module.exports = apiBaseRouter; diff --git a/api/health-check/controller.js b/api/health-check/controller.js new file mode 100644 index 0000000000000000000000000000000000000000..2fda039dd9ae20e9eb671958065d56bbbd64ebe9 --- /dev/null +++ b/api/health-check/controller.js @@ -0,0 +1,17 @@ + + +const healthCheck = (req, res, next) => { + try { + + + + return res.sendStatus(200); + } catch (error) { + + console.log(error) + } +}; + +module.exports = { + healthCheck, +}; diff --git a/api/health-check/routes.js b/api/health-check/routes.js new file mode 100644 index 0000000000000000000000000000000000000000..adbcd23400b9c9b5c0437905a9452a330707752f --- /dev/null +++ b/api/health-check/routes.js @@ -0,0 +1,7 @@ +const healthCheckRouter = require('express').Router(); +const { healthCheck } = require('./controller'); + +healthCheckRouter.get('/', healthCheck); + + +module.exports = healthCheckRouter; diff --git a/api/layout/business.js b/api/layout/business.js new file mode 100644 index 0000000000000000000000000000000000000000..ece8010705cbba631da3ffeaf8968b24477936ca --- /dev/null +++ b/api/layout/business.js @@ -0,0 +1,33 @@ +/* eslint-disable prefer-promise-reject-errors */ +/* eslint-disable no-throw-literal */ +// const logger = require('utils/logger'); +const getAllWidgetService = require('../layout/service'); + + + +const getAllWidget = async (page) => { + try { + const response = await getAllWidgetService.getAllWidget(page); + return { status: '200', response } + } catch (error) { + throw error + } + +}; + +const createWidget = async (data) => { + try { + const response = await getAllWidgetService.createWidget(data); + return { status: '200', response } + } catch (error) { + throw error + } + +}; + + + +module.exports = { + getAllWidget, + createWidget +}; diff --git a/api/layout/controller.js b/api/layout/controller.js new file mode 100644 index 0000000000000000000000000000000000000000..b543c6954facf1618bfa48b12095248242c05156 --- /dev/null +++ b/api/layout/controller.js @@ -0,0 +1,30 @@ +// const logger = require('utils/logger'); +const layoutBusiness = require('./business'); +// const Joi = require('joi'); + +const getAllWidget = async (req, res, next) => { + try { + console.log("comign here") + const { page } = req.params; + const response = await layoutBusiness.getAllWidget(page); + return res.status(response.status).json({ data: response }); + } catch (error) { + throw error + } +}; +const createWidget = async (req, res, next) => { + try { + console.log("comign createWidget") + + const response = await layoutBusiness.createWidget(req.body); + return res.status(response.status).json({ data: response }); + } catch (error) { + throw error + } +}; + + +module.exports = { + getAllWidget, + createWidget +}; \ No newline at end of file diff --git a/api/layout/routes.js b/api/layout/routes.js new file mode 100644 index 0000000000000000000000000000000000000000..157994b1cf9b9d77f0eb638151748814afed2555 --- /dev/null +++ b/api/layout/routes.js @@ -0,0 +1,8 @@ +const layoutRouter = require('express').Router(); +const { getAllWidget,createWidget} = require('./controller'); + +layoutRouter.get('/allLayout/:page', getAllWidget); + +layoutRouter.post('/createWidget', createWidget); + +module.exports = layoutRouter; \ No newline at end of file diff --git a/api/layout/service.js b/api/layout/service.js new file mode 100644 index 0000000000000000000000000000000000000000..6a3529f444c40b8d0d5806ad7371372fa66e202c --- /dev/null +++ b/api/layout/service.js @@ -0,0 +1,34 @@ +// const logger = require('utils/logger'); + +const Widget = require("../models/widget"); +const Template = require("../models/template") + +const getAllWidget = async (page) => { + try { + const template = await Template.findOne({ name: page}).populate('widgets.widgetId'); + if (!template) { + return res.status(404).json({ error: 'Template not found' }); + } + res.status(200).json(template); + } catch (error) { + throw error + } + +}; + +const createWidget = async (data) => { + try { + console.log("in service") + const widget = new Widget(data); + await widget.save(); + return { status: 201, id: widget._id, message: 'Widget created successfully' }; + } catch (error) { + throw error + } + +}; + +module.exports = { + getAllWidget, + createWidget +}; \ No newline at end of file diff --git a/api/models/template.js b/api/models/template.js new file mode 100644 index 0000000000000000000000000000000000000000..98426ca9bfbcf2b0828eebb1b286412f91a933d5 --- /dev/null +++ b/api/models/template.js @@ -0,0 +1,22 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +// Define schema for widgets within a template or page +const WidgetRefSchema = new Schema({ + widgetId: { type: mongoose.Schema.Types.ObjectId, ref: 'Widget', required: true }, // Reference to the Widget model + position: { type: Number, required: true }, + startTime: { type: Date, required: true }, + endTime: { type: Date, required: true } +}); + +// Define main Template schema +const TemplateSchema = new Schema({ + name: { type: String, required: true }, + desc: { type: String }, + widgets: [WidgetRefSchema], + hashId: { type: String, unique: true, required: true }, + createdAt: { type: Date, default: Date.now }, + updatedAt: { type: Date, default: Date.now } +}); + +module.exports = mongoose.model('Template', TemplateSchema); diff --git a/api/models/widget.js b/api/models/widget.js new file mode 100644 index 0000000000000000000000000000000000000000..106c3d86420ede8d950c0f481d16999e5a111489 --- /dev/null +++ b/api/models/widget.js @@ -0,0 +1,44 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +// Define schema for the button data +const ButtonDataSchema = new Schema({ + url: { type: String, required: true }, + title: { type: String, required: true } +}); + +// Define schema for banner data +const BannerDataSchema = new Schema({ + imageName: { type: String, default: '' }, + headingText: { type: String, required: true }, + subHeadingText: { type: String, required: true }, + landingUrl: { type: String, required: true }, + timerPosition: { type: String, default: null }, + timerColor: { type: String, default: null } +}); + +// Define schema for list items +const ListItemSchema = new Schema({ + bannerData: { type: BannerDataSchema, required: true }, + display_order: { type: Number, required: true }, + dimension: { + length: { type: Number, required: true }, + breadth: { type: Number, required: true } + }, + banner_title: { type: String, required: true } +}); + +// Define main Widget schema +const WidgetSchema = new Schema({ + title: { type: String, required: true }, + widget: { type: String, required: true }, + enable: { type: Boolean, default: true }, + buttonData: [ButtonDataSchema], + sectionHeadingText: { type: String, required: true }, + apiUrl: { type: String, required: true }, + list: [ListItemSchema], + createdAt: { type: Date, default: Date.now }, + updatedAt: { type: Date, default: Date.now } +}); + +module.exports = mongoose.model('Widget', WidgetSchema); diff --git a/server.js b/server.js index b99148637ddd19a5c8a6a6330ab58cada353805f..524f6cb34b36594784eee390a1e75c406b604ff8 100644 --- a/server.js +++ b/server.js @@ -7,6 +7,7 @@ const connectDB = require('./db'); const app = express(); app.use(bodyParser.json()); +const apiBaseRouter = require('./api/apiBaseRouter'); // Connect to MongoDB connectDB(); @@ -15,6 +16,9 @@ connectDB(); const swaggerDocument = YAML.load('./swagger.yaml'); app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); +// API base URL +app.use(apiBaseRouter); + // Start the server const PORT = process.env.PORT || 5000; diff --git a/swagger.yaml b/swagger.yaml index d63e67b4734a809138f2c0f3e454d404ec207382..f9fb1ee49c7b6fcf09b630f50cbf0bf325da7a95 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -1,90 +1,27 @@ openapi: 3.0.0 info: - title: Layout Management API + title: Widgetized Homepage API version: 1.0.0 - description: API for managing layouts including creating, retrieving, and deleting layouts. + description: API for managing templates and widgets for a widgetized homepage and sub-pages. + +# servers: +# - url: http://localhost:3000 +# description: Local server + paths: - /api/layout/{layout}: + /widget/allLayout/{page}: get: - summary: Get a specific layout + summary: Get widget details for a page parameters: - in: path - name: layout + name: page required: true schema: type: string - description: The layout identifier + description: The page for which widget details are requested. responses: - 200: - description: Successfully retrieved layout - content: - application/json: - schema: - type: object - properties: - title: - type: string - layout: - type: string - priority: - type: integer - enable: - type: boolean - buttonData: - type: array - items: - type: object - properties: - url: - type: string - title: - type: string - sectionHeadingText: - type: string - list: - type: array - items: - type: object - properties: - bannerData: - type: object - properties: - imageName: - type: string - headingText: - type: string - subHeadingText: - type: string - landingUrl: - type: string - rowStartTime: - type: string - rowEndTime: - type: string - timerPosition: - type: string - timerColor: - type: string - dimension: - type: object - properties: - length: - type: integer - breadth: - type: integer - display_order: - type: integer - banner_title: - type: string - 404: - description: Layout not found - - /api/AllLayout: - get: - summary: Get all layouts - responses: - 200: - description: Successfully retrieved all layouts + '200': + description: Widgets retrieved successfully content: application/json: schema: @@ -92,12 +29,12 @@ paths: items: type: object properties: + id: + type: string title: type: string layout: type: string - priority: - type: integer enable: type: boolean buttonData: @@ -111,6 +48,8 @@ paths: type: string sectionHeadingText: type: string + apiUrl: + type: string list: type: array items: @@ -127,14 +66,12 @@ paths: type: string landingUrl: type: string - rowStartTime: - type: string - rowEndTime: - type: string timerPosition: type: string timerColor: type: string + display_order: + type: integer dimension: type: object properties: @@ -142,14 +79,21 @@ paths: type: integer breadth: type: integer - display_order: - type: integer banner_title: type: string + '404': + description: Widgets not found + content: + application/json: + schema: + type: object + properties: + error: + type: string - /api/newLayout: + /widget/createWidget: post: - summary: Create a new layout + summary: Create a new widget requestBody: required: true content: @@ -159,7 +103,7 @@ paths: properties: title: type: string - layout: + widget: type: string priority: type: integer @@ -176,6 +120,8 @@ paths: type: string sectionHeadingText: type: string + apiUrl: + type: string list: type: array items: @@ -192,14 +138,12 @@ paths: type: string landingUrl: type: string - rowStartTime: - type: string - rowEndTime: - type: string timerPosition: type: string timerColor: type: string + display_order: + type: integer dimension: type: object properties: @@ -207,38 +151,64 @@ paths: type: integer breadth: type: integer - display_order: - type: integer banner_title: type: string responses: - 201: - description: New layout created successfully + '201': + description: Widget created successfully content: application/json: schema: type: object properties: - message: + id: type: string - layoutId: + message: type: string - 400: + '400': description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string - /api/layout/{layout}: - delete: - summary: Delete a layout + /api/templates/{page}/widgets/{widgetId}: + put: + summary: Update and map a widget to a particular page parameters: - in: path - name: layout + name: page required: true schema: type: string - description: The layout identifier + description: The page to which the widget is to be mapped. + - in: path + name: widgetId + required: true + schema: + type: string + description: The widget ID that needs to be mapped. + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + position: + type: integer + startTime: + type: string + format: date-time + endTime: + type: string + format: date-time responses: - 200: - description: Layout deleted successfully + '200': + description: Widget mapped successfully content: application/json: schema: @@ -246,5 +216,18 @@ paths: properties: message: type: string - 404: - description: Layout not found + widgetId: + type: string + page: + type: string + position: + type: integer + '400': + description: Bad request + content: + application/json: + schema: + type: object + properties: + error: + type: string