diff --git a/package-lock.json b/package-lock.json index 26e6adfc..9bdbb37b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9822,7 +9822,7 @@ "version": "19.2.1", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.1.tgz", "integrity": "sha512-/EEvYBdT3BflCWvTMO7YkYBHVE9Ci6XdqZciZANQgKpaiDRGOLIlRo91jbTNRQjgPFWVaRxcYc0luVNFitz57A==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -21221,6 +21221,30 @@ "pathe": "^2.0.1" } }, + "node_modules/monaco-editor": { + "version": "0.55.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", + "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", + "license": "MIT", + "peer": true, + "dependencies": { + "dompurify": "3.2.7", + "marked": "14.0.0" + } + }, + "node_modules/monaco-editor/node_modules/marked": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz", + "integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==", + "license": "MIT", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/motion-dom": { "version": "12.23.23", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", @@ -25190,6 +25214,13 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/search-insights": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "license": "MIT", + "peer": true + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -26953,7 +26984,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/src/data/coursesData.ts b/src/data/coursesData.ts new file mode 100644 index 00000000..346cf993 --- /dev/null +++ b/src/data/coursesData.ts @@ -0,0 +1,582 @@ +export type Difficulty = "Beginner" | "Intermediate" | "Advanced"; + +export interface FreePlatform { + name: string; + url: string; + certificateAvailable: boolean; +} + +export interface Course { + id: string; + title: string; + description: string; + category: string; + difficulty: Difficulty; + duration: string; + tags: string[]; + freePlatforms: FreePlatform[]; +} + +export interface CourseCategory { + id: string; + label: string; + icon: string; +} + +export const courseCategories: CourseCategory[] = [ + { id: "all", label: "All Courses", icon: "πŸŽ“" }, + { id: "data-engineering", label: "Data Engineering", icon: "βš™οΈ" }, + { id: "data-science", label: "Data Science & ML", icon: "🧠" }, + { id: "web-development", label: "Web Development", icon: "🌐" }, + { id: "cloud", label: "Cloud Computing", icon: "☁️" }, + { id: "databases", label: "Databases & SQL", icon: "πŸ—„οΈ" }, + { id: "programming", label: "Programming", icon: "πŸ’»" }, +]; + +export const coursesData: Course[] = [ + // ── Data Engineering ───────────────────────────────────────────────────── + { + id: "python-data-engineering", + title: "Python for Data Engineering", + description: + "Learn to harness the power of Python for transforming and processing data at scale. Build robust data pipelines and optimize data workflows effectively.", + category: "data-engineering", + difficulty: "Beginner", + duration: "10 hrs", + tags: ["Python", "ETL", "Data Pipelines", "Pandas", "NumPy"], + freePlatforms: [ + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/python-for-data-science", + certificateAvailable: true, + }, + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/python-programming-language/", + certificateAvailable: false, + }, + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/scientific-computing-with-python/", + certificateAvailable: true, + }, + ], + }, + { + id: "sql-data-engineering", + title: "SQL for Data Engineering", + description: + "Unlock the potential of data manipulation and management. Gain proficiency in crafting and optimizing complex queries to build and maintain efficient data pipelines.", + category: "data-engineering", + difficulty: "Beginner", + duration: "8 hrs", + tags: ["SQL", "Query Optimization", "Data Pipelines", "Normalization"], + freePlatforms: [ + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/sql-for-data-science", + certificateAvailable: true, + }, + { + name: "W3Schools", + url: "https://www.w3schools.com/sql/", + certificateAvailable: false, + }, + { + name: "SQLZoo", + url: "https://sqlzoo.net/", + certificateAvailable: false, + }, + ], + }, + { + id: "apache-kafka", + title: "Apache Kafka for Data Engineering", + description: + "Dive into real-time data streaming with Apache Kafka. Learn to build scalable, fault-tolerant data pipelines that enable efficient data movement and processing.", + category: "data-engineering", + difficulty: "Intermediate", + duration: "12 hrs", + tags: ["Kafka", "Real-Time Processing", "Data Streaming", "Batch Processing"], + freePlatforms: [ + { + name: "Confluent (Apache Kafka)", + url: "https://developer.confluent.io/learn-kafka/", + certificateAvailable: false, + }, + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/apache-kafka/", + certificateAvailable: false, + }, + ], + }, + { + id: "apache-spark", + title: "Apache Spark for Data Engineering", + description: + "Master Apache Spark for distributed data processing. Learn PySpark, Spark SQL, DataFrames, and Spark Streaming for large-scale data engineering.", + category: "data-engineering", + difficulty: "Intermediate", + duration: "15 hrs", + tags: ["Spark", "PySpark", "Big Data", "DataFrames", "Spark SQL"], + freePlatforms: [ + { + name: "Databricks Academy", + url: "https://www.databricks.com/learn/training/learning-pathway-apache-spark", + certificateAvailable: false, + }, + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/apache-spark/", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/apache-spark-tutorial", + certificateAvailable: true, + }, + ], + }, + { + id: "snowflake-data-warehouse", + title: "Data Warehouse with Snowflake", + description: + "Discover the modern approach to data warehousing using Snowflake. Learn to design, implement, and manage a high-performance data warehouse.", + category: "data-engineering", + difficulty: "Intermediate", + duration: "10 hrs", + tags: ["Snowflake", "Data Warehouse", "Cloud Data", "OLAP", "Analytics"], + freePlatforms: [ + { + name: "Snowflake University", + url: "https://www.snowflake.com/en/learn/training/", + certificateAvailable: true, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/snowflake", + certificateAvailable: true, + }, + ], + }, + { + id: "workflow-orchestration", + title: "Workflow Orchestration with Airflow", + description: + "Explore workflow orchestration with Apache Airflow. Gain expertise in seamlessly coordinating and automating complex data pipelines.", + category: "data-engineering", + difficulty: "Intermediate", + duration: "10 hrs", + tags: ["Airflow", "Workflow Automation", "Data Orchestration", "ETL"], + freePlatforms: [ + { + name: "Apache Airflow Docs", + url: "https://airflow.apache.org/docs/", + certificateAvailable: false, + }, + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/introduction-to-apache-airflow/", + certificateAvailable: false, + }, + ], + }, + + // ── Data Science & ML ───────────────────────────────────────────────────── + { + id: "machine-learning-fundamentals", + title: "Machine Learning Fundamentals", + description: + "A comprehensive introduction to machine learning. Learn supervised, unsupervised, and reinforcement learning with practical Python examples.", + category: "data-science", + difficulty: "Beginner", + duration: "20 hrs", + tags: ["Machine Learning", "Python", "Scikit-learn", "Data Analysis"], + freePlatforms: [ + { + name: "Google ML Crash Course", + url: "https://developers.google.com/machine-learning/crash-course", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/machine-learning", + certificateAvailable: true, + }, + { + name: "Kaggle", + url: "https://www.kaggle.com/learn/intro-to-machine-learning", + certificateAvailable: true, + }, + ], + }, + { + id: "data-analysis-pandas", + title: "Data Analysis with Pandas & NumPy", + description: + "Master data manipulation and analysis using the Pandas and NumPy libraries. Learn to clean, transform, and explore datasets efficiently.", + category: "data-science", + difficulty: "Beginner", + duration: "8 hrs", + tags: ["Pandas", "NumPy", "Data Wrangling", "Data Cleaning", "Python"], + freePlatforms: [ + { + name: "Kaggle", + url: "https://www.kaggle.com/learn/pandas", + certificateAvailable: true, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/pandas-and-numpy", + certificateAvailable: true, + }, + ], + }, + { + id: "deep-learning-tensorflow", + title: "Deep Learning with TensorFlow", + description: + "Learn the fundamentals of deep learning and build neural networks using TensorFlow and Keras. Covers CNNs, RNNs, and transfer learning.", + category: "data-science", + difficulty: "Advanced", + duration: "25 hrs", + tags: ["Deep Learning", "TensorFlow", "Keras", "Neural Networks", "CNN"], + freePlatforms: [ + { + name: "TensorFlow Official Tutorials", + url: "https://www.tensorflow.org/tutorials", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/deep-learning", + certificateAvailable: true, + }, + ], + }, + { + id: "data-visualization", + title: "Data Visualization with Python", + description: + "Learn to create compelling visualizations using Matplotlib, Seaborn, and Plotly. Communicate data insights effectively to any audience.", + category: "data-science", + difficulty: "Beginner", + duration: "6 hrs", + tags: ["Data Visualization", "Matplotlib", "Seaborn", "Plotly", "Python"], + freePlatforms: [ + { + name: "Kaggle", + url: "https://www.kaggle.com/learn/data-visualization", + certificateAvailable: true, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/data-visualization", + certificateAvailable: true, + }, + ], + }, + + // ── Web Development ─────────────────────────────────────────────────────── + { + id: "html-css-basics", + title: "HTML & CSS Fundamentals", + description: + "Build a solid foundation in web development with HTML5 and CSS3. Learn semantic markup, responsive layouts, and modern CSS features.", + category: "web-development", + difficulty: "Beginner", + duration: "10 hrs", + tags: ["HTML", "CSS", "Responsive Design", "Web Development"], + freePlatforms: [ + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/responsive-web-design/", + certificateAvailable: true, + }, + { + name: "W3Schools", + url: "https://www.w3schools.com/html/", + certificateAvailable: false, + }, + { + name: "The Odin Project", + url: "https://www.theodinproject.com/paths/foundations/courses/foundations", + certificateAvailable: false, + }, + ], + }, + { + id: "javascript-fundamentals", + title: "JavaScript Fundamentals", + description: + "Master JavaScript from the ground up. Covers variables, functions, DOM manipulation, ES6+ features, and asynchronous programming.", + category: "web-development", + difficulty: "Beginner", + duration: "20 hrs", + tags: ["JavaScript", "ES6", "DOM", "APIs", "Async"], + freePlatforms: [ + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/", + certificateAvailable: true, + }, + { + name: "The Odin Project", + url: "https://www.theodinproject.com/paths/full-stack-javascript", + certificateAvailable: false, + }, + { + name: "javascript.info", + url: "https://javascript.info/", + certificateAvailable: false, + }, + ], + }, + { + id: "react-basics", + title: "React for Beginners", + description: + "Get started with React β€” the most popular front-end library. Learn components, state, props, hooks, and how to build modern single-page applications.", + category: "web-development", + difficulty: "Intermediate", + duration: "15 hrs", + tags: ["React", "JavaScript", "Hooks", "SPA", "Front-End"], + freePlatforms: [ + { + name: "React Official Docs", + url: "https://react.dev/learn", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/react-for-beginners", + certificateAvailable: true, + }, + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/front-end-development-libraries/", + certificateAvailable: true, + }, + ], + }, + + // ── Cloud Computing ─────────────────────────────────────────────────────── + { + id: "aws-cloud-fundamentals", + title: "AWS Cloud Fundamentals", + description: + "Gain a solid understanding of Amazon Web Services. Learn core services like EC2, S3, RDS, Lambda, and IAM β€” and prepare for the AWS Cloud Practitioner exam.", + category: "cloud", + difficulty: "Beginner", + duration: "12 hrs", + tags: ["AWS", "Cloud Computing", "EC2", "S3", "Lambda"], + freePlatforms: [ + { + name: "AWS Skill Builder", + url: "https://explore.skillbuilder.aws/learn/course/134/play/93785/aws-cloud-practitioner-essentials", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/aws-fundamentals", + certificateAvailable: true, + }, + ], + }, + { + id: "gcp-fundamentals", + title: "Google Cloud Platform Fundamentals", + description: + "Explore Google Cloud Platform services and learn to deploy, manage, and scale applications in the cloud. Covers BigQuery, Cloud Storage, and Compute Engine.", + category: "cloud", + difficulty: "Beginner", + duration: "10 hrs", + tags: ["Google Cloud", "GCP", "BigQuery", "Cloud Storage", "Cloud"], + freePlatforms: [ + { + name: "Google Cloud Skills Boost", + url: "https://www.cloudskillsboost.google/paths/9", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/google-cloud-fundamentals", + certificateAvailable: true, + }, + ], + }, + { + id: "azure-fundamentals", + title: "Microsoft Azure Fundamentals", + description: + "Start your journey with Microsoft Azure. Learn cloud concepts, core Azure services, security, privacy, compliance, and pricing to prepare for the AZ-900 exam.", + category: "cloud", + difficulty: "Beginner", + duration: "10 hrs", + tags: ["Azure", "Microsoft Azure", "Cloud Computing", "AZ-900"], + freePlatforms: [ + { + name: "Microsoft Learn", + url: "https://learn.microsoft.com/en-us/training/paths/azure-fundamentals/", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/azure-fundamentals", + certificateAvailable: true, + }, + ], + }, + + // ── Databases & SQL ─────────────────────────────────────────────────────── + { + id: "mysql-complete", + title: "MySQL β€” The Complete Course", + description: + "A complete guide to MySQL. Learn database design, DDL/DML statements, joins, indexes, stored procedures, triggers, and performance tuning.", + category: "databases", + difficulty: "Beginner", + duration: "12 hrs", + tags: ["MySQL", "SQL", "Relational Databases", "Indexing", "Stored Procedures"], + freePlatforms: [ + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/mysql", + certificateAvailable: true, + }, + { + name: "W3Schools", + url: "https://www.w3schools.com/mysql/", + certificateAvailable: false, + }, + ], + }, + { + id: "postgresql-advanced", + title: "PostgreSQL for Developers", + description: + "Go beyond basic SQL with PostgreSQL. Explore advanced queries, window functions, JSON support, partitioning, and full-text search.", + category: "databases", + difficulty: "Intermediate", + duration: "10 hrs", + tags: ["PostgreSQL", "SQL", "Window Functions", "Advanced SQL", "Data Integrity"], + freePlatforms: [ + { + name: "PostgreSQL Official Tutorial", + url: "https://www.postgresql.org/docs/current/tutorial.html", + certificateAvailable: false, + }, + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/postgresql-tutorial/", + certificateAvailable: false, + }, + ], + }, + { + id: "mongodb-nosql", + title: "MongoDB & NoSQL Databases", + description: + "Learn NoSQL database concepts and master MongoDB. Covers CRUD operations, aggregation pipeline, indexing, and schema design.", + category: "databases", + difficulty: "Beginner", + duration: "8 hrs", + tags: ["MongoDB", "NoSQL", "Database Design", "CRUD", "Aggregation"], + freePlatforms: [ + { + name: "MongoDB University", + url: "https://learn.mongodb.com/", + certificateAvailable: true, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/mongodb", + certificateAvailable: true, + }, + ], + }, + + // ── Programming ─────────────────────────────────────────────────────────── + { + id: "git-github-basics", + title: "Git & GitHub β€” Version Control", + description: + "Learn version control from scratch using Git and GitHub. Covers branching, merging, pull requests, and collaborative development workflows.", + category: "programming", + difficulty: "Beginner", + duration: "5 hrs", + tags: ["Git", "GitHub", "Version Control", "Collaboration"], + freePlatforms: [ + { + name: "GitHub Skills", + url: "https://skills.github.com/", + certificateAvailable: false, + }, + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/git-and-github", + certificateAvailable: true, + }, + ], + }, + { + id: "docker-kubernetes", + title: "Docker & Kubernetes Essentials", + description: + "Understand containerization with Docker and orchestration with Kubernetes. Learn to build, ship, and run applications consistently across environments.", + category: "programming", + difficulty: "Intermediate", + duration: "14 hrs", + tags: ["Docker", "Kubernetes", "Containers", "DevOps", "Scalability"], + freePlatforms: [ + { + name: "Play with Docker", + url: "https://labs.play-with-docker.com/", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/docker-tutorial", + certificateAvailable: true, + }, + { + name: "KodeKloud", + url: "https://kodekloud.com/courses/docker-for-the-absolute-beginner/", + certificateAvailable: false, + }, + ], + }, + { + id: "data-structures-algorithms", + title: "Data Structures & Algorithms", + description: + "Build a strong computer science foundation. Learn arrays, linked lists, trees, graphs, sorting, and searching algorithms with Python examples.", + category: "programming", + difficulty: "Intermediate", + duration: "30 hrs", + tags: ["DSA", "Algorithms", "Python", "Problem Solving", "Coding Interviews"], + freePlatforms: [ + { + name: "GeeksforGeeks", + url: "https://www.geeksforgeeks.org/data-structures/", + certificateAvailable: false, + }, + { + name: "freeCodeCamp", + url: "https://www.freecodecamp.org/learn/coding-interview-prep/", + certificateAvailable: false, + }, + { + name: "Great Learning", + url: "https://www.mygreatlearning.com/academy/learn-for-free/courses/data-structures-and-algorithms", + certificateAvailable: true, + }, + ], + }, +]; diff --git a/src/pages/courses/courses.css b/src/pages/courses/courses.css index 4fb86381..a044ef67 100644 --- a/src/pages/courses/courses.css +++ b/src/pages/courses/courses.css @@ -373,6 +373,16 @@ box-shadow: var(--courses-shadow-lg); } +/* Allow elements styled as the primary button to look/behave correctly */ +a.courses-button-link { + display: inline-flex; + text-decoration: none; +} + +a.courses-button-link:hover { + text-decoration: none; +} + .courses-button-primary:hover { background: linear-gradient(135deg, #2563eb 0%, #4f46e5 100%); transform: translateY(-3px); diff --git a/src/pages/courses/explore.css b/src/pages/courses/explore.css new file mode 100644 index 00000000..c1d4ae19 --- /dev/null +++ b/src/pages/courses/explore.css @@ -0,0 +1,452 @@ +/* ========================================================= + Explore Courses Page β€” explore.css + Inherits CSS variables from courses.css + ========================================================= */ + +/* ── Page wrapper ─────────────────────────────────────────── */ +.explore-page { + background-color: var(--courses-bg-primary); + color: var(--courses-text-primary); +} + +/* ── Hero ─────────────────────────────────────────────────── */ +.explore-hero { + padding: 4rem 1rem 3rem; + text-align: center; + border-bottom: 1px solid var(--courses-border); + background: linear-gradient( + 160deg, + var(--courses-bg-secondary) 0%, + var(--courses-bg-primary) 100% + ); +} + +.explore-hero-inner { + max-width: 720px; + margin: 0 auto; +} + +.explore-hero-title { + font-size: clamp(2rem, 5vw, 3.25rem); + font-weight: 800; + letter-spacing: -0.02em; + line-height: 1.15; + margin-bottom: 1rem; + color: var(--courses-text-primary); +} + +.explore-hero-sub { + font-size: 1.1rem; + color: var(--courses-text-secondary); + margin-bottom: 2rem; + line-height: 1.6; +} + +/* Search */ +.explore-search-wrapper { + position: relative; + max-width: 520px; + margin: 0 auto; +} + +.explore-search-icon { + position: absolute; + left: 1rem; + top: 50%; + transform: translateY(-50%); + width: 1.2rem; + height: 1.2rem; + color: var(--courses-text-muted); + pointer-events: none; +} + +.explore-search-input { + width: 100%; + padding: 0.75rem 2.8rem 0.75rem 2.8rem; + border-radius: 9999px; + border: 1px solid var(--courses-border); + background: var(--courses-bg-primary); + color: var(--courses-text-primary); + font-size: 0.95rem; + outline: none; + transition: border-color 0.2s, box-shadow 0.2s; +} + +.explore-search-input:focus { + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); +} + +.explore-search-clear { + position: absolute; + right: 0.9rem; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + font-size: 1.3rem; + color: var(--courses-text-muted); + line-height: 1; + padding: 0 0.25rem; + transition: color 0.15s; +} + +.explore-search-clear:hover { + color: var(--courses-text-primary); +} + +/* ── Shared container ──────────────────────────────────────── */ +.explore-container { + max-width: 1280px; + margin: 0 auto; + padding: 0 1rem; +} + +/* ── Filters section ──────────────────────────────────────── */ +.explore-filters-section { + padding: 1.5rem 1rem; + border-bottom: 1px solid var(--courses-border); + background-color: var(--courses-bg-secondary); +} + +/* Category tabs */ +.explore-category-tabs { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 1rem; +} + +.explore-category-tab { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.45rem 1rem; + border-radius: 9999px; + border: 1px solid var(--courses-border); + background: var(--courses-bg-primary); + color: var(--courses-text-secondary); + font-size: 0.875rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; +} + +.explore-category-tab:hover { + border-color: #3b82f6; + color: #3b82f6; +} + +.explore-category-tab.active { + background: linear-gradient(135deg, #3b82f6, #8b5cf6); + color: #fff; + border-color: transparent; +} + +.explore-cat-icon { + font-size: 1rem; +} + +/* Filter row */ +.explore-filter-row { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 1rem; + justify-content: space-between; +} + +/* Difficulty pills */ +.explore-difficulty-pills { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; +} + +.explore-difficulty-pill { + padding: 0.3rem 0.85rem; + border-radius: 9999px; + border: 1px solid var(--courses-border); + background: transparent; + color: var(--courses-text-secondary); + font-size: 0.8rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; +} + +.explore-difficulty-pill:hover { + border-color: #8b5cf6; + color: #8b5cf6; +} + +.explore-difficulty-pill.active { + background: linear-gradient(135deg, #6366f1, #8b5cf6); + color: #fff; + border-color: transparent; +} + +/* Sort */ +.explore-sort { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.explore-sort-label { + font-size: 0.85rem; + color: var(--courses-text-muted); + white-space: nowrap; +} + +.explore-sort-select { + padding: 0.35rem 0.75rem; + border-radius: 0.5rem; + border: 1px solid var(--courses-border); + background: var(--courses-bg-primary); + color: var(--courses-text-primary); + font-size: 0.85rem; + cursor: pointer; + outline: none; + transition: border-color 0.2s; +} + +.explore-sort-select:focus { + border-color: #3b82f6; +} + +/* Result count */ +.explore-result-count { + margin-top: 0.75rem; + font-size: 0.85rem; + color: var(--courses-text-muted); +} + +/* ── Grid section ─────────────────────────────────────────── */ +.explore-grid-section { + padding: 2.5rem 1rem 4rem; +} + +.explore-grid { + display: grid; + gap: 1.5rem; + grid-template-columns: 1fr; +} + +@media (min-width: 640px) { + .explore-grid { + grid-template-columns: repeat(2, 1fr); + } +} + +@media (min-width: 1024px) { + .explore-grid { + grid-template-columns: repeat(3, 1fr); + } +} + +/* ── Course Card ──────────────────────────────────────────── */ +.explore-card { + display: flex; + flex-direction: column; + gap: 1rem; + padding: 1.5rem; + border-radius: 1rem; + border: 1px solid var(--courses-border); + background: var(--courses-bg-primary); + box-shadow: var(--courses-shadow); + transition: box-shadow 0.25s, transform 0.25s, border-color 0.25s; +} + +.explore-card:hover { + box-shadow: var(--courses-shadow-lg); + transform: translateY(-3px); + border-color: rgba(59, 130, 246, 0.35); +} + +/* Card header */ +.explore-card-header { + display: flex; + flex-direction: column; + gap: 0.6rem; +} + +.explore-card-meta { + display: flex; + align-items: center; + gap: 0.6rem; + flex-wrap: wrap; +} + +/* Difficulty badges */ +.explore-badge { + display: inline-block; + padding: 0.2rem 0.65rem; + border-radius: 9999px; + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.03em; +} + +.explore-badge-beginner { + background: rgba(16, 185, 129, 0.12); + color: #10b981; + border: 1px solid rgba(16, 185, 129, 0.3); +} + +.explore-badge-intermediate { + background: rgba(245, 158, 11, 0.12); + color: #f59e0b; + border: 1px solid rgba(245, 158, 11, 0.3); +} + +.explore-badge-advanced { + background: rgba(239, 68, 68, 0.12); + color: #ef4444; + border: 1px solid rgba(239, 68, 68, 0.3); +} + +/* Duration */ +.explore-duration { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: 0.8rem; + color: var(--courses-text-muted); +} + +.explore-duration-icon { + width: 0.9rem; + height: 0.9rem; +} + +/* Title & desc */ +.explore-card-title { + font-size: 1.05rem; + font-weight: 700; + color: var(--courses-text-primary); + line-height: 1.35; + margin: 0; +} + +.explore-card-desc { + font-size: 0.875rem; + color: var(--courses-text-secondary); + line-height: 1.55; + margin: 0; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* Tags */ +.explore-tags { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; +} + +.explore-tag { + padding: 0.2rem 0.55rem; + border-radius: 0.4rem; + background: var(--courses-bg-tertiary); + color: var(--courses-text-muted); + font-size: 0.75rem; + font-weight: 500; + border: 1px solid var(--courses-border); +} + +/* Platforms section */ +.explore-platforms-section { + margin-top: auto; + border-top: 1px solid var(--courses-border); + padding-top: 0.75rem; +} + +.explore-platforms-toggle { + display: flex; + align-items: center; + gap: 0.5rem; + background: none; + border: none; + cursor: pointer; + color: #3b82f6; + font-size: 0.875rem; + font-weight: 600; + padding: 0; + transition: color 0.15s; +} + +.explore-platforms-toggle:hover { + color: #6366f1; +} + +.explore-chevron { + width: 1rem; + height: 1rem; + transition: transform 0.25s; +} + +.explore-chevron.rotate-180 { + transform: rotate(180deg); +} + +.explore-platforms-list { + list-style: none; + margin: 0.6rem 0 0; + padding: 0; + display: flex; + flex-direction: column; + gap: 0.4rem; + overflow: hidden; +} + +.explore-platform-item { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + flex-wrap: wrap; +} + +.explore-platform-link { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.85rem; + color: var(--courses-text-secondary); + text-decoration: none; + transition: color 0.15s; +} + +.explore-platform-link:hover { + color: #3b82f6; + text-decoration: underline; +} + +.explore-external-icon { + width: 0.8rem; + height: 0.8rem; + flex-shrink: 0; +} + +.explore-cert-badge { + font-size: 0.72rem; + padding: 0.15rem 0.5rem; + border-radius: 9999px; + background: rgba(234, 179, 8, 0.12); + color: #ca8a04; + border: 1px solid rgba(234, 179, 8, 0.3); + white-space: nowrap; +} + +/* ── Empty state ──────────────────────────────────────────── */ +.explore-empty { + text-align: center; + padding: 4rem 1rem; + color: var(--courses-text-muted); + font-size: 1.1rem; +} diff --git a/src/pages/courses/explore.tsx b/src/pages/courses/explore.tsx new file mode 100644 index 00000000..9e089f55 --- /dev/null +++ b/src/pages/courses/explore.tsx @@ -0,0 +1,351 @@ +import React, { useState, useMemo } from "react"; +import Layout from "@theme/Layout"; +import Head from "@docusaurus/Head"; +import { motion, AnimatePresence } from "framer-motion"; +import { + coursesData, + courseCategories, + type Course, + type Difficulty, +} from "../../data/coursesData"; +import "../courses/courses.css"; +import "./explore.css"; + +const difficultyColors: Record = { + Beginner: "explore-badge-beginner", + Intermediate: "explore-badge-intermediate", + Advanced: "explore-badge-advanced", +}; + +const difficultyOrder: Record = { + Beginner: 0, + Intermediate: 1, + Advanced: 2, +}; + +type SortOption = "default" | "difficulty-asc" | "difficulty-desc" | "duration-asc"; + +function CourseCard({ course }: { course: Course }) { + const [expanded, setExpanded] = useState(false); + + return ( + + {/* Header */} +
+
+ + {course.difficulty} + + + + + + {course.duration} + +
+ +

{course.title}

+

{course.description}

+
+ + {/* Tags */} +
+ {course.tags.map((tag) => ( + + {tag} + + ))} +
+ + {/* Free Platforms */} +
+ + + + {expanded && ( + + {course.freePlatforms.map((platform) => ( +
  • + + {platform.name} + + + + + {platform.certificateAvailable && ( + πŸ† Certificate + )} +
  • + ))} + + )} + +
    + + ); +} + +export default function ExploreCourses() { + const [activeCategory, setActiveCategory] = useState("all"); + const [searchQuery, setSearchQuery] = useState(""); + const [sortOption, setSortOption] = useState("default"); + const [activeDifficulty, setActiveDifficulty] = useState("All"); + + const filtered = useMemo(() => { + let result = coursesData; + + if (activeCategory !== "all") { + result = result.filter((c) => c.category === activeCategory); + } + + if (activeDifficulty !== "All") { + result = result.filter((c) => c.difficulty === activeDifficulty); + } + + if (searchQuery.trim()) { + const q = searchQuery.toLowerCase(); + result = result.filter( + (c) => + c.title.toLowerCase().includes(q) || + c.description.toLowerCase().includes(q) || + c.tags.some((t) => t.toLowerCase().includes(q)), + ); + } + + if (sortOption === "difficulty-asc") { + result = [...result].sort( + (a, b) => difficultyOrder[a.difficulty] - difficultyOrder[b.difficulty], + ); + } else if (sortOption === "difficulty-desc") { + result = [...result].sort( + (a, b) => difficultyOrder[b.difficulty] - difficultyOrder[a.difficulty], + ); + } else if (sortOption === "duration-asc") { + result = [...result].sort( + (a, b) => parseInt(a.duration) - parseInt(b.duration), + ); + } + + return result; + }, [activeCategory, searchQuery, sortOption, activeDifficulty]); + + return ( + + + + + +
    + {/* Hero */} + +
    +

    + Explore{" "} + Free Courses +

    +

    + Browse {coursesData.length}+ curated courses across multiple + disciplines. Every course links directly to free platforms where + you can learn and earn a certificate. +

    + + {/* Search */} +
    + + + + setSearchQuery(e.target.value)} + className="explore-search-input" + /> + {searchQuery && ( + + )} +
    +
    +
    + + {/* Filters */} +
    +
    + {/* Category Tabs */} +
    + {courseCategories.map((cat) => ( + + ))} +
    + + {/* Difficulty + Sort Row */} +
    + {/* Difficulty Pills */} +
    + {(["All", "Beginner", "Intermediate", "Advanced"] as const).map( + (d) => ( + + ), + )} +
    + + {/* Sort */} +
    + + +
    +
    + + {/* Result count */} +

    + {filtered.length === 0 + ? "No courses found." + : `Showing ${filtered.length} course${filtered.length !== 1 ? "s" : ""}`} +

    +
    +
    + + {/* Course Grid */} +
    +
    + {filtered.length === 0 ? ( +
    +

    πŸ˜” No courses match your filters.

    + +
    + ) : ( + + + {filtered.map((course) => ( + + ))} + + + )} +
    +
    +
    +
    + ); +} diff --git a/src/pages/courses/index.tsx b/src/pages/courses/index.tsx index 0ceff361..06869f9b 100644 --- a/src/pages/courses/index.tsx +++ b/src/pages/courses/index.tsx @@ -501,9 +501,9 @@ function CoursesContent() { className="mx-auto mb-12 flex max-w-md flex-col justify-center gap-4 sm:flex-row md:mb-16 md:max-w-none md:gap-6" variants={fadeIn} > - +