diff --git a/Answers to technical questions.md b/Answers to technical questions.md new file mode 100644 index 0000000..553558c --- /dev/null +++ b/Answers to technical questions.md @@ -0,0 +1,71 @@ +# Answers to Technical Questions + +## 1. How long did you spend on the coding test? What would you add if you had more time? + +I spent approximately a few hours working on the coding test, focusing mainly on implementing the core functionality and ensuring that the application works correctly. + +If I had more time, I would improve the following areas: +- Refactor the code for better readability and maintainability +- Add proper error handling and validation +- Improve UI responsiveness and accessibility +- Optimize performance, especially for dynamic rendering and API calls +- Add unit and integration tests to ensure reliability +- Enhance mobile and cross-browser compatibility + +--- + +## 2. How would you track down a performance issue in production? Have you ever had to do this? + +To track down a performance issue in production, I would follow a structured approach: + +1. **Identify the issue** + - Use monitoring tools (e.g., logs, APM tools like New Relic, Datadog, or application logs) + - Check metrics like response time, CPU usage, memory usage, and database latency + +2. **Reproduce the issue** + - Try to replicate it in a staging environment using similar data and traffic patterns + +3. **Analyze bottlenecks** + - Inspect slow API calls, database queries, or frontend rendering issues + - Use profiling tools (Chrome DevTools, backend profilers, query analyzers) + +4. **Fix and validate** + - Optimize the problematic code/query + - Deploy fixes in a controlled manner and monitor impact + +5. **Prevent recurrence** + - Add alerts, logging, and performance benchmarks + +Yes, I have worked on debugging performance-related issues where I analyzed slow API responses and optimized database queries and frontend rendering logic to improve load times. + +--- + +## 3. Please describe yourself using JSON + +```json +{ + "name": "Biken Singh", + "role": "Full Stack Developer", + "skills": [ + "JavaScript", + "React", + "Node.js", + "PHP", + "MySQL", + "HTML", + "CSS" + ], + "interests": [ + "Web Development", + "Performance Optimization", + "UI/UX Design", + "Learning new technologies" + ], + "strengths": [ + "Problem solving", + "Clean code practices", + "Quick learner", + "Debugging and optimization" + ], + "goals": "To become a highly skilled full stack engineer building scalable and efficient web applications" +} diff --git a/controllers/SliderController.php b/controllers/SliderController.php new file mode 100644 index 0000000..315ef6d --- /dev/null +++ b/controllers/SliderController.php @@ -0,0 +1,27 @@ +connect(); + $this->item = new Item($db); + } + + public function getData() { + + $result = $this->item->getAll(); + + $data = []; + + while ($row = $result->fetch_assoc()) { + $data[] = $row; + } + + echo json_encode($data); + } +} +?> \ No newline at end of file diff --git a/items.sql b/items.sql new file mode 100644 index 0000000..da6ed75 --- /dev/null +++ b/items.sql @@ -0,0 +1,73 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Generation Time: Apr 15, 2026 at 12:56 AM +-- Server version: 10.4.28-MariaDB +-- PHP Version: 8.2.4 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `wpoets_test` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `items` +-- + +CREATE TABLE `items` ( + `id` int(11) NOT NULL, + `title` varchar(255) NOT NULL, + `description` text DEFAULT NULL, + `image` varchar(255) DEFAULT NULL, + `tab_name` varchar(100) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- +-- Dumping data for table `items` +-- + +INSERT INTO `items` (`id`, `title`, `description`, `image`, `tab_name`) VALUES +(1, 'E-learning Solutions', 'Interactive learning platforms for education and training', 'public/images/DL-Learning.jpg', 'Learning'), +(2, 'Training Modules', 'Custom training modules for corporate learning', 'public/images/DL-Communication.jpg', 'Learning'), +(3, 'Software Development', 'End-to-end software solutions for enterprises', 'public/images/DL-Technology.jpg', 'Technology'), +(4, 'Cloud Services', 'Scalable cloud infrastructure and deployment services', 'public/images/DL-Technology.jpg', 'Technology'), +(7, 'Corporate Communication', 'Effective internal and external communication strategies', 'public/images/DL-Communication.jpg', 'Communication'), +(8, 'Digital Communication', 'Modern digital communication solutions for businesses', 'public/images/DL-Technology.jpg', 'Communication'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `items` +-- +ALTER TABLE `items` + ADD PRIMARY KEY (`id`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `items` +-- +ALTER TABLE `items` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/models/Database.php b/models/Database.php new file mode 100644 index 0000000..fe437b1 --- /dev/null +++ b/models/Database.php @@ -0,0 +1,27 @@ +conn = new mysqli( + $this->host, + $this->username, + $this->password, + $this->dbname + ); + + if ($this->conn->connect_error) { + die("Database Connection Failed: " . $this->conn->connect_error); + } + + return $this->conn; + } +} \ No newline at end of file diff --git a/models/item.php b/models/item.php new file mode 100644 index 0000000..12c2caf --- /dev/null +++ b/models/item.php @@ -0,0 +1,19 @@ +conn = $db; + } + + public function getAll() { + + $query = "SELECT * FROM " . $this->table; + $result = $this->conn->query($query); + + return $result; + } +} \ No newline at end of file diff --git a/public/css/slider.css b/public/css/slider.css new file mode 100644 index 0000000..6bda0e0 --- /dev/null +++ b/public/css/slider.css @@ -0,0 +1,205 @@ +/* ================= BASE ================= */ +body { + background: #173f5f; + color: white; +} + +/* ================= LAYOUT ================= */ +.custom-row { + height: 642px; /* fixed design height */ +} + +.tabs-container, +.slider-container, +.image-container { + height: 100%; + display: flex; + flex-direction: column; +} + +/* ================= TABS ================= */ +.tabs-container { + background: #fff; + border: 1px solid #eee; + box-shadow: 0 6px 18px rgba(0,0,0,0.08); + padding: 10px 0; +} + +#tabs { + background: #fff; + padding: 10px; + height: 100%; + display: flex; + flex-direction: column; +} + +.tab { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 15px; + margin-bottom: 10px; + + background: #fff; + cursor: pointer; + border: 1px solid #eee; + + box-shadow: -4px 4px 10px rgba(0,0,0,0.08); + transition: all 0.25s ease; +} + +.tab.active { + border-left: 4px solid #ffffff; + background: #f6fbfc; + box-shadow: -6px 2px 18px #adb5bd; +} + +.tab-text { + font-size: 14px; + font-weight: 500; + color: #333; +} + +/* ================= SWIPER ================= */ +.swiper { + width: 100%; + height: 67vh; +} + +.swiper-wrapper, +.swiper-slide { + height: 100%; +} + +.swiper-slide { + background: #64b4c8; + background-position: center; + padding: 20px; + color: #fff; +} + +/* ================= SLIDE DESIGN ================= */ +.slide-bg { + background-size: cover; + background-position: center; + position: relative; +} + +.slide-bg::before { + content: ""; + position: absolute; + inset: 0; + background: rgba(100,180,200,0.85); +} + +.slide-bg * { + position: relative; + z-index: 1; +} + +.slide-content { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 15px; + text-align: center; +} + +.slide-tag { + background: #538f9f; + padding: 6px 14px; + border-radius: 5px; + font-size: 12px; +} + +.slide-title { + font-size: 20px; + font-weight: 600; +} + +/* ================= IMAGE (UPDATED ✅) ================= */ +.image-box { + width: 100%; + height: 100%; + background-size: cover; + background-position: center; + background-repeat: no-repeat; + position: relative; + transition: background-image 0.4s ease; +} + +/* optional overlay */ +.image-box::after { + content: ""; + position: absolute; + inset: 0; + background: rgba(0,0,0,0.15); +} + +/* ================= MOBILE ================= */ +@media (max-width: 768px) { + + .custom-row { + height: auto; + } + + .swiper { + height: auto; + } + + .acc-item { + margin-bottom: 10px; + } + + .acc-header { + background: #f5f5f5; + padding: 15px; + display: flex; + justify-content: space-between; + cursor: pointer; + border-radius: 10px; + position: relative; + } + + .acc-body { + padding-top: 15px; + display: none; + } + + .acc-header span { + color: #000; + font-weight: 600; + } + + .acc-item.active .acc-header::after { + content: ""; + position: absolute; + bottom: -15px; + left: 50%; + transform: translateX(-50%); + + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-bottom: 10px solid #5fa3b5; + } + + .acc-body .swiper { + height: 250px; + } +} + +/* ================= BUTTON ================= */ +.learn-more { + display: flex; + align-items: center; + gap: 6px; + color: #fff; + text-decoration: none; + font-size: 16px; +} + +.learn-more img { + width: 14px; +} \ No newline at end of file diff --git a/public/images/DL-Communication.jpg b/public/images/DL-Communication.jpg new file mode 100644 index 0000000..51b3b5b Binary files /dev/null and b/public/images/DL-Communication.jpg differ diff --git a/public/images/DL-Learning-1.jpg b/public/images/DL-Learning-1.jpg new file mode 100644 index 0000000..755171f Binary files /dev/null and b/public/images/DL-Learning-1.jpg differ diff --git a/public/images/DL-Technology.jpg b/public/images/DL-Technology.jpg new file mode 100644 index 0000000..a8d4354 Binary files /dev/null and b/public/images/DL-Technology.jpg differ diff --git a/public/images/DL-communication.svg b/public/images/DL-communication.svg new file mode 100644 index 0000000..0088544 --- /dev/null +++ b/public/images/DL-communication.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/DL-learning.svg b/public/images/DL-learning.svg new file mode 100644 index 0000000..bfeb0b5 --- /dev/null +++ b/public/images/DL-learning.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/DL-technology.svg b/public/images/DL-technology.svg new file mode 100644 index 0000000..59f2ea5 --- /dev/null +++ b/public/images/DL-technology.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/Moodboard.xlsx b/public/images/Moodboard.xlsx new file mode 100644 index 0000000..0d5fe30 Binary files /dev/null and b/public/images/Moodboard.xlsx differ diff --git a/public/images/arrow-right.svg b/public/images/arrow-right.svg new file mode 100644 index 0000000..37d307b --- /dev/null +++ b/public/images/arrow-right.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/public/images/minus-01.svg b/public/images/minus-01.svg new file mode 100644 index 0000000..a0639ca --- /dev/null +++ b/public/images/minus-01.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/public/images/mobile-view.png b/public/images/mobile-view.png new file mode 100644 index 0000000..e24e766 Binary files /dev/null and b/public/images/mobile-view.png differ diff --git a/public/images/plus-01.svg b/public/images/plus-01.svg new file mode 100644 index 0000000..d80a766 --- /dev/null +++ b/public/images/plus-01.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/public/images/web-view.png b/public/images/web-view.png new file mode 100644 index 0000000..a6eea25 Binary files /dev/null and b/public/images/web-view.png differ diff --git a/public/js/slider.js b/public/js/slider.js new file mode 100644 index 0000000..6d8c4a5 --- /dev/null +++ b/public/js/slider.js @@ -0,0 +1,286 @@ +let items = []; +let baseUrl = "/WPOET_demo/"; +let currentView = $(window).width() < 768 ? "mobile" : "desktop"; +let resizeTimer; +function handleLayout() { + if (currentView === "mobile") { + initMobile(); + } else { + initDesktop(); + } +} +$(window).on("resize", function () { + + clearTimeout(resizeTimer); + + resizeTimer = setTimeout(() => { + + let newView = $(window).width() < 768 ? "mobile" : "desktop"; + + if (newView !== currentView) { + + currentView = newView; + + console.log("Switched to:", newView); // debug + + // clear UI + $("#slider").empty(); + $("#tabs").empty(); + $("#mobileAccordion").empty(); + + // re-init + handleLayout(); + } + + }, 250); + +}); +$(document).ready(function () { + + $.get("../routes/sliderRoutes.php", function (data) { + + // Safe JSON parse + items = typeof data === "string" ? JSON.parse(data) : data; + + if ($(window).width() < 768) { + initMobile(); + } else { + initDesktop(); + } + + }); + +}); + + const tabIcons = { + "Learning": "public/images/DL-learning.svg", + "Technology": "public/images/DL-technology.svg", + "Communication": "public/images/DL-communication.svg", + }; +// ================= DESKTOP (SLICK) ================= +function initDesktop() { + + let tabs = [...new Set(items.map(i => i.tab_name))]; + + $("#tabs").html(""); + + tabs.forEach(tab => { + let icon = tabIcons[tab] || "public/images/default.svg"; + + $("#tabs").append(` +
+ + ${tab} +
+ `); + }); + + let swiperInstance = null; + + $(document).on("click", ".tab", function () { + + $(".tab").removeClass("active"); + $(this).addClass("active"); + + let tab = $(this).data("tab"); + let filtered = items.filter(i => i.tab_name === tab); + + $("#slider").html(""); + + let slides = ""; + + filtered.forEach(item => { + slides += ` +
+ +
+ ${item.title} +

${item.description}

+ + Learn More + arrow + +
+ +
+ `; + }); + + $("#slider").html(` +
+
+ ${slides} +
+ +
+
+ `); + + // destroy old swiper + if (swiperInstance) { + swiperInstance.destroy(true, true); + } + + // init swiper + swiperInstance = new Swiper(".desktop-swiper", { + slidesPerView: 1, + spaceBetween: 10, + pagination: { + el: ".desktop-swiper .swiper-pagination", + clickable: true + }, + + // ✅ FIX IMAGE CHANGE HERE + on: { + slideChange: function () { + + let active = this.slides[this.activeIndex]; + + if (active) { + let img = active.getAttribute("data-img"); + + if (img) { + $("#mainImage").css( + "background-image", + `url('${baseUrl + img}')` + ); + } + } + } + } + }); + + // set first image + if (filtered.length > 0) { + $("#mainImage").css( + "background-image", + `url('${baseUrl + filtered[0].image}')` + ); + } + }); + + $(".tab").first().click(); +} + +// ================= MOBILE (SWIPER) ================= + +function initMobile() { + + let grouped = {}; + + items.forEach(item => { + if (!grouped[item.tab_name]) grouped[item.tab_name] = []; + grouped[item.tab_name].push(item); + }); + + $("#mobileAccordion").html(""); + + Object.keys(grouped).forEach((tab, i) => { + + let slides = ""; + let icon = tabIcons[tab] || "public/images/default.svg"; + grouped[tab].forEach(item => { + slides += `
+ +
+ + + ${item.title} + + +

+ ${item.description} +

+ + + Learn More + arrow + + +
+ +
+ `; + }); + + $("#mobileAccordion").append(` +
+ +
+
+ + ${tab} +
+ +
+ +
+
+ + + +
+ `); + + // INIT SWIPER + setTimeout(() => { + new Swiper(`.mobile-slider-${i}`, { + loop: true, + spaceBetween: 10, + + pagination: { + el: `.mobile-slider-${i} .swiper-pagination`, + clickable: true + }, + }); + }, 100); + }); +} + + +// ================= ACCORDION ================= + +$(document).on("click", ".acc-header", function () { + + let parent = $(this).parent(); + let isOpen = parent.find(".acc-body").is(":visible"); + + // close all + $(".acc-body").slideUp(); + $(".acc-item").removeClass("active"); + + // reset all icons to PLUS + $(".toggle-icon").attr("src", "/WPOET_demo/public/images/plus-01.svg"); + + // if it was NOT open → open it + if (!isOpen) { + + parent.addClass("active"); + parent.find(".acc-body").slideDown(); + + // change THIS icon to MINUS + $(this).find(".toggle-icon") + .attr("src", "/WPOET_demo/public/images/minus-01.svg"); + + // fix swiper / layout + setTimeout(() => { + window.dispatchEvent(new Event('resize')); + }, 300); + + } +}); + diff --git a/routes/sliderRoutes.php b/routes/sliderRoutes.php new file mode 100644 index 0000000..0adc71c --- /dev/null +++ b/routes/sliderRoutes.php @@ -0,0 +1,8 @@ +getData(); + +?> \ No newline at end of file diff --git a/views/index.php b/views/index.php new file mode 100644 index 0000000..d1dfc12 --- /dev/null +++ b/views/index.php @@ -0,0 +1,50 @@ + + + + + WPoets Assignment + + + + + + + +
+
+ +

DelphianLogic in Action

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. +

+ + +
+
+ +
+ + +
+
+
+ + +
+
+
+
+
+ + +
+ +
+
+ + + + + + + \ No newline at end of file