diff --git a/03-javascript/datastructures/queue/queue.mjs b/03-javascript/datastructures/queue/queue.mjs index c2f3119..4bcc799 100644 --- a/03-javascript/datastructures/queue/queue.mjs +++ b/03-javascript/datastructures/queue/queue.mjs @@ -1,34 +1,67 @@ +import { Stack } from "../stack/stack.mjs"; // Queue class for basic queue operations -class Queue { + +export class Queue { constructor() { this.items = []; } enqueue(element) { - // Implement enqueue operation + return this.items.push(element) } dequeue() { - // Implement dequeue operation + return this.items.shift() } peek() { - // Implement peek operation + if (this.items.length != 0){ + return this.items[0] + } + else{ + return 'Queue is empty' + } } isEmpty() { - // Implement isEmpty operation + if (this.items.length == 0){ + return true + } + else{ + return false + } } } // Function to reverse a queue -function reverseQueue(queue) { - // Implement reverseQueue function +export function reverseQueue(queue) { + const stack = new Stack(); + const obj = new Queue() + for(let i in queue){ + obj.enqueue(queue[i]) + } + while (!obj.isEmpty()) { + stack.push(obj.dequeue()); + } + const reversed = []; + while (!stack.isEmpty()) { + reversed.push(stack.pop()); + } + return reversed; } - // Function to check if a string is a palindrome using a queue -function isPalindrome(input) { - // Implement isPalindrome function +export function isPalindrome(input) { + const strSplit = [...input] + console.log(typeof(strSplit)) + console.log(typeof(reverseQueue(input))) + console.log(strSplit) + console.log(reverseQueue(input)) + if (strSplit == reverseQueue(input)){ + return 'it is a palindrone' + } + else{ + return 'it is not a palindrone' + } } // CircularQueue class for implementing a circular queue @@ -66,11 +99,4 @@ function simulateQueue(customers, serviceTime) { // Implement simulateQueue function } -// Exporting the classes and functions for use -export default { - Queue, - reverseQueue, - isPalindrome, - CircularQueue, - simulateQueue, -}; +// Exporting the classes and functions for use \ No newline at end of file diff --git a/03-javascript/datastructures/queue/scratch.mjs b/03-javascript/datastructures/queue/scratch.mjs new file mode 100644 index 0000000..4363304 --- /dev/null +++ b/03-javascript/datastructures/queue/scratch.mjs @@ -0,0 +1,11 @@ +import { reverseQueue } from "./queue.mjs"; +import { Queue } from "./queue.mjs"; +import { isPalindrome } from "./queue.mjs"; +const input = [1,2,3,4,5,6,7] +console.log(input) +console.log(reverseQueue(input)) + +console.log(isPalindrome('aisha')) +console.log(isPalindrome('racecar')) +console.log(isPalindrome('madam')) +console.log(isPalindrome('level')) diff --git a/03-javascript/datastructures/stack/scratch.mjs b/03-javascript/datastructures/stack/scratch.mjs new file mode 100644 index 0000000..0b95e26 --- /dev/null +++ b/03-javascript/datastructures/stack/scratch.mjs @@ -0,0 +1,8 @@ +import { reverseString } from "./stack.mjs"; +import { isBalanced } from "./stack.mjs"; +import { sortStack } from "./stack.mjs"; +//console.log(reverseString("harsh")) +//console.log(typeof(reverseString("harsh"))) +//console.log(isBalanced('{)')) +const input = [5,8,7,9,3,4] +console.log(sortStack(input)) diff --git a/03-javascript/datastructures/stack/stack.js b/03-javascript/datastructures/stack/stack.js deleted file mode 100644 index 7c6c6c4..0000000 --- a/03-javascript/datastructures/stack/stack.js +++ /dev/null @@ -1,72 +0,0 @@ -// Stack class for basic stack operations -class Stack { - constructor() { - this.items = []; - } - - push(element) { - // Implement push operation - } - - pop() { - // Implement pop operation - } - - peek() { - // Implement peek operation - } - - isEmpty() { - // Implement isEmpty operation - } -} - -// Function to reverse a string using a stack -function reverseString(input) { - // Implement reverseString function -} - -// Function to check if parentheses are balanced -function isBalanced(input) { - // Implement isBalanced function -} - -// MinStack class to support retrieving the minimum element -class MinStack extends Stack { - constructor() { - super(); - // Additional properties for MinStack - } - - push(element) { - // Implement push operation for MinStack - } - - pop() { - // Implement pop operation for MinStack - } - - getMin() { - // Implement getMin operation - } -} - -// Function to evaluate a postfix expression -function evaluatePostfix(expression) { - // Implement evaluatePostfix function -} - -// Function to sort a stack using only stack operations -function sortStack(stack) { - // Implement sortStack function -} - -// Exporting the functions and classes for use -export default { - Stack, - reverseString, - isBalanced, - MinStack, - evaluatePostfix, - sortStack, -}; diff --git a/03-javascript/datastructures/stack/stack.mjs b/03-javascript/datastructures/stack/stack.mjs new file mode 100644 index 0000000..991059a --- /dev/null +++ b/03-javascript/datastructures/stack/stack.mjs @@ -0,0 +1,125 @@ +// Stack class for basic stack operations +export class Stack { + constructor() { + this.items = []; + } + + push(element) { + this.items.push(element) + } + + pop() { + if (this.items.length != 0){ + return this.items.pop() + } + else{ + return 'Stack is empty' + } + } + + peek() { + if (this.items.length != 0){ + return this.items[this.items.length -1] + } + else{ + return 'Stack is empty' + } + } + + isEmpty() { + return this.items.length === 0 + } +} +//const stack = new Stack() + +// Function to reverse a string using a stack +export function reverseString(input) { + const stack = new Stack() + + for(let i in input){ + stack.push(input[i]) + } + const reverse = [] + while (!stack.isEmpty()){ + reverse.push(stack.pop()) + } + return reverse.join("") +} + +// Function to check if parentheses are balanced +export function isBalanced(input) { + if (input == reverseString(input)){ + return true + } + else{ + return false + } +} +// not able to do this one. still trying + +// MinStack class to support retrieving the minimum element +class MinStack extends Stack { + constructor() { + super(); + this.minStack = [] + } + + push(element) { + super.push(element) + if (this.minStack.length === 0){ + this.minStack.push(element) + } + else{ + if (element <= this.minStack[this.minStack.length -1]){ + this.minStack.push(element) + } + else{ + this.minStack.push(this.minStack[this.minStack.length -1]) + } + } + } + + pop() { + if (this.length == 0){ + return 'stack and Minstack is empty' + } + else{ + super.pop() + this.minStack.pop() + } + } + + getMin() { + if (this.minStack.length === 0){ + return 'minstack is empty' + } + else{ + return this.minStack[this.minStack.length -1] + } + } +} + +// Function to evaluate a postfix expression +function evaluatePostfix(expression) { + // Implement evaluatePostfix function +} + +// Function to sort a stack using only stack operations +export function sortStack(stack) { + const obj = new Stack(); + for (let i in stack) { + obj.push(stack[i]); + } + const auxiliaryStack = []; + while (!obj.isEmpty()) { + let temp = obj.pop(); + while (auxiliaryStack.length > 0 && auxiliaryStack[auxiliaryStack.length - 1] > temp) { + let moved = auxiliaryStack.pop(); + obj.push(moved); + } + auxiliaryStack.push(temp); + } + return auxiliaryStack; +} + +// Exporting the functions and classes for use diff --git a/03-javascript/datastructures/tree/README.md b/03-javascript/datastructures/tree/README.md index cb2c725..c7533d2 100644 --- a/03-javascript/datastructures/tree/README.md +++ b/03-javascript/datastructures/tree/README.md @@ -74,55 +74,64 @@ In this example: ## Practice Assignments 🎯 ### Assignment 1: Tree Height Calculator + **Difficulty: Easy** **Objective:** Create a function to calculate the height of a binary tree. **Instructions:** + - Implement a function `getTreeHeight(root)` that takes the root node as input - Return the maximum height (depth) of the tree - Return 0 for an empty tree ### Assignment 2: Node Counter + **Difficulty: Easy** **Objective:** Count the total number of nodes in a binary tree. **Instructions:** + - Create a function `countNodes(root)` that takes the root node as input - Count and return the total number of nodes in the tree - Include both leaf nodes and internal nodes in the count ### Assignment 3: Leaf Node Finder + **Difficulty: Medium** **Objective:** Find and print all leaf nodes in a binary tree. **Instructions:** + - Implement a function `findLeafNodes(root)` that takes the root node as input - Return an array containing all leaf nodes (nodes with no children) - Maintain the order of leaves from left to right ### Assignment 4: Level Order Traversal + **Difficulty: Medium** **Objective:** Print nodes level by level, from top to bottom. **Instructions:** + - Create a function `levelOrderTraversal(root)` that takes the root node as input - Print nodes at each level on a new line - Use a queue to manage the level-by-level traversal ### Assignment 5: Tree Mirror + **Difficulty: Medium** **Objective:** Create a mirror image of a binary tree. **Instructions:** + - Implement a function `mirrorTree(root)` that takes the root node as input - Swap left and right children of all nodes - Return the root node of the mirrored tree - The original tree structure should be modified in place Each assignment builds upon the basic binary tree concepts and helps understand different tree operations and traversal techniques. - diff --git a/03-javascript/datastructures/tree/RECURSION.md b/03-javascript/datastructures/tree/RECURSION.md new file mode 100644 index 0000000..a3c2111 --- /dev/null +++ b/03-javascript/datastructures/tree/RECURSION.md @@ -0,0 +1,69 @@ +# Recursion in JavaScript: Functions Calling Themselves 🔄 + +Recursion is a programming concept where a function solves a problem by calling itself with a smaller version of the same problem. Think of it like a Russian nesting doll - each doll contains a smaller version of itself until you reach the smallest one. + +## Understanding Recursion 🤔 + +Every recursive function has two main parts: + +1. **Base Case**: The condition where the function stops calling itself +2. **Recursive Case**: Where the function calls itself with a modified input + +## Practical Examples 🚀 + +### Example 1: Factorial Calculator + +Calculate the factorial of a number (n!): + +```javascript +function factorial(n) { + // Base case + if (n === 0 || n === 1) { + return 1; + } + // Recursive case + return n * factorial(n - 1); +} + +console.log(factorial(5)); // Output: 120 (5 * 4 * 3 * 2 * 1) +``` + +### Example 2: Fibonacci Sequence + +Generate the nth Fibonacci number: + +```javascript +function fibonacci(n) { + // Base case + if (n <= 1) { + return n; + } + // Recursive case + return fibonacci(n - 1) + fibonacci(n - 2); +} +console.log(fibonacci(6)); // Output: 8 (0 + 1 + 1 + 2 + 3 + 5) +``` + +### Example 3: Directory Tree Explorer + +Recursively explore a directory structure: + +```javascript +function exploreDirectory(directoryPath) { + // Base case: if directory is empty + if (!fs.existsSync(directoryPath)) { + return; + } + const files = fs.readdirSync(directoryPath); + for (const file of files) { + const filePath = path.join(directoryPath, file); + if (fs.statSync(filePath).isDirectory()) { + // Recursive case: if it's a directory, explore it + exploreDirectory(filePath); + } else { + // Base case: if it's a file, print its path + console.log(filePath); + } + } +} +``` diff --git a/03-javascript/datastructures/tree/scratch.mjs b/03-javascript/datastructures/tree/scratch.mjs new file mode 100644 index 0000000..282a476 --- /dev/null +++ b/03-javascript/datastructures/tree/scratch.mjs @@ -0,0 +1,98 @@ +import {Queue} from '../queue/queue.mjs' +class TreeNode { + constructor(name) { + this.name = name; + this.left = null; + this.right = null; + } + } + const grandparent = new TreeNode("John"); + const parent1 = new TreeNode("Mike"); + const parent2 = new TreeNode("Sarah"); + const child1 = new TreeNode("Tom"); + const child2 = new TreeNode("Emily"); + const child3 = new TreeNode("David"); + + grandparent.left = parent1; + grandparent.right = parent2; + parent1.left = child1; + parent1.right = child2; + parent2.left = child3; + +function getTreeHeight(node) { + if (node === null){ + return 0 + } + else{ + const leftheight= getTreeHeight(node.left); + const rightheight= getTreeHeight(node.right); + return 1 + Math.max(leftheight, rightheight) + } +} +console.log(getTreeHeight(grandparent)); + +function countNodes(node){ + if (node === null){ + return 0 + } + else{ + const leftcount = countNodes(node.left); + const rightcount= countNodes(node.right); + return 1+ leftcount + rightcount + } +} +console.log(countNodes(grandparent)) + +function findLeafNodes(node, arr=[]){ + if (node === null){ + return arr + } + if (node.left=== null && node.right=== null){ + arr.push(node.name) + } + + findLeafNodes(node.left, arr) + findLeafNodes(node.right, arr) + return arr +} + +console.log(findLeafNodes(grandparent)) + +function levelOrderTraversal(node){ + const queue = new Queue() + queue.enqueue(node) + queue.enqueue(null) + + while (!queue.isEmpty()){ + const temp = queue.peek() + queue.dequeue() + if (temp==null){ + console.log('\n') + if (!queue.isEmpty()){ + queue.enqueue(null) + } + } + else{ + console.log(temp.name) + if (temp.left){ + queue.enqueue(temp.left) + } + if (temp.right){ + queue.enqueue(temp.right) + } + } + } +} +console.log(levelOrderTraversal(grandparent)) + +function mirrorTree(node){ + if (node == null){ + return + } + node.left, node.right = node.right, node.left + + mirrorTree(node.left) + mirrorTree(node.right) +} + +console.log(mirrorTree(grandparent)) \ No newline at end of file diff --git a/03-javascript/portfolio-web/docs/cookie.md b/03-javascript/portfolio-web/docs/cookie.md index a3da488..0684692 100644 --- a/03-javascript/portfolio-web/docs/cookie.md +++ b/03-javascript/portfolio-web/docs/cookie.md @@ -28,7 +28,9 @@ function setLanguagePreference(lang) { // Get language preference function getLanguagePreference() { const cookies = document.cookie.split(";"); - const langCookie = cookies.find((cookie) => cookie.trim().startsWith("userLang=")); + const langCookie = cookies.find((cookie) => + cookie.trim().startsWith("userLang=") + ); return langCookie ? langCookie.split("=")[1] : "en"; } @@ -93,6 +95,8 @@ function getRememberedUser() { // Clear remembered user function forgetUser() { + document.cookie = + "rememberedUser=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/"; document.cookie = "rememberedUser=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/"; document.cookie = "authToken=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/"; } diff --git a/03-javascript/portfolio-web/docs/scratch.mjs b/03-javascript/portfolio-web/docs/scratch.mjs new file mode 100644 index 0000000..bcceef0 --- /dev/null +++ b/03-javascript/portfolio-web/docs/scratch.mjs @@ -0,0 +1,31 @@ +function trackVisit() { + let visits = parseInt(getCookie("visitCount")) || 0; + visits++; + + const expiryDate = new Date(); + expiryDate.setTime(expiryDate.getTime() + 7); + document.cookie = `visitCount=${visits};expires=${expiryDate.toUTCString()};path=/`; + + return visits; + } + function getCookie(name) { + const cookies = document.cookie.split(";"); + const cookie = cookies.find((c) => c.trim().startsWith(name + "=")); + return cookie ? cookie.split("=")[1] : null; + } + console.log(`Visit count: ${trackVisit()}`); + +function setThemePreference(theme) { + const expiryDate = new Date(); + expiryDate.setDate(expiryDate.getDate() + 30); + document.cookie = `usertheme=${theme};expires=${expiryDate.toUTCString()};path=/`; +} + +function getThemePreference() { + const cookies = document.cookie.split(";"); + const themeCookie = cookies.find(cookie => cookie.trim().startsWith("usertheme=")); + return themeCookie ? themeCookie.split("=")[1] : "light"; +} + +setThemePreference("dark"); +console.log(getThemePreference()); \ No newline at end of file diff --git a/03-javascript/portfolio-web/index.html b/03-javascript/portfolio-web/index.html deleted file mode 100644 index bfaef30..0000000 --- a/03-javascript/portfolio-web/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - Document - - - -
-
- - - -
-

-
- -
-
- - diff --git a/03-javascript/portfolio-web/js/accounts.mjs b/03-javascript/portfolio-web/js/accounts.mjs deleted file mode 100644 index 885ad98..0000000 --- a/03-javascript/portfolio-web/js/accounts.mjs +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Utility class for storing response - */ -export class Response { - constructor(success, message) { - this.success = success; - this.message = message; - } -} - -/** - * Create a signup request class - */ -export class SignupRequest { - constructor(name, email, password) { - // add code here - } -} - -/** - * Create a UserAccount class - */ -export class UserAccount {} - -class AccountService { - /** - * Stores a map of user accounts - * where the key is the email and value is the UserAccount object - * @param {*} accounts - */ - constructor(accounts) { - this.accounts = accounts; - } - - /** - * if user with that email already exists then return an object of type - * Response - new Response(false, 'User already exists with this email') - * else return new Response(true, 'You have successfully signed up') - * @param {*} request of type SignupRequest - */ - handleSignupRequest(request) {} - - /** - * Authenticate using email and password. - * @param {*} email - * @param {*} password - */ - handleSigninRequest(email, password) {} -} -//Create an empty Map for storing users -export default new AccountService(new Map()); diff --git a/03-javascript/portfolio-web/js/portfolio.mjs b/03-javascript/portfolio-web/js/portfolio.mjs deleted file mode 100644 index 328b409..0000000 --- a/03-javascript/portfolio-web/js/portfolio.mjs +++ /dev/null @@ -1,39 +0,0 @@ -import UserProfileService from "./services/profile.mjs"; - -const profileService = new UserProfileService(); - -/** - * Write a function to handle Signup request as per the design - */ -export function handleSignup(form) { - console.log(form); - // handle signup request - - //if it fails, then you will show an error message - const userError = document.getElementById("user-error"); - userError.innerText = `User already exists`; - - //if it succeeds, then you will show the signin form -} - -/** - * Write a function to handle Signin request as per the design - */ -export function handleSignin(form) { - console.log(form); - - // if it fails, show the error message - - //if it succeeds, show the portfolio website (navigation and about section) - - // Use UserProfileService get profile, articles, projects and talks - - const articles = UserProfileService.getArticles(account); - createArticlesSection(articles); - - // Add the about section -} - -function createArticlesSection(articles) {} - -window.handleSignup = handleSignup; diff --git a/03-javascript/portfolio-web/js/services/profile.mjs b/03-javascript/portfolio-web/js/services/profile.mjs deleted file mode 100644 index e8d4a22..0000000 --- a/03-javascript/portfolio-web/js/services/profile.mjs +++ /dev/null @@ -1,36 +0,0 @@ -class UserProfileService { - constructor(articlesList, projectsList, talksList) { - this.articlesStore = new ArticleStore(articlesList); - // this.projectsStore = new ProjectsStore(projectsList); - // this.talksStore = new TalksStore(talksList); - //.. - } - - addArticle(article) { - this.articlesStore.addArticle(article); - } - - listArticles() { - return this.articlesStore.listArticles(); - } - - /** - * Find the latest article - */ - latestArticle() {} - - /** - * (1)Function to return the article based on the link - * @param {*} link - */ - getArticle(link) { - // to get the article - // analyticsService.push({'view', link, 'article'}) - } - - /** - * (4)Find the most viewed article - */ - getMostViewedArticle() {} -} -export default UserProfileService; diff --git a/03-javascript/portfolio-web/js/stores/articles.mjs b/03-javascript/portfolio-web/js/stores/articles.mjs deleted file mode 100644 index 8284ebb..0000000 --- a/03-javascript/portfolio-web/js/stores/articles.mjs +++ /dev/null @@ -1,43 +0,0 @@ -class ArticleStore { - /** - * Constructor to initialize the store using local storage - * @param {*} accountWithArticles - */ - constructor(accountWithArticles) { - if (accountWithArticles && accountWithArticles.length > 0) { - // Iterate through each user account and their articles - for (const [account, articles] of accountWithArticles) { - if (Array.isArray(articles) && articles.length > 0) { - // Store articles array in localStorage with user email as key - localStorage.setItem(`articles-${account}`, JSON.stringify(articles)); - } - } - } - } - - /** - * Add a method to add an article to the user's account - * @param {*} account - * @param {*} article - */ - addArticle(account, article) {} - - /** - * Add a method to get all articles for a user - * @param {*} account - * @returns - */ - getArticles(account) {} - - /** - * Add a method to get the latest article of a user - */ - getLatestArticle(account) {} - - /** - * Add a method to get the oldest article of a user - */ - getOldestArticle(account) {} -} - -export default ArticleStore; diff --git a/03-javascript/portfolio-web/web/index.html b/03-javascript/portfolio-web/web/index.html new file mode 100644 index 0000000..16fac14 --- /dev/null +++ b/03-javascript/portfolio-web/web/index.html @@ -0,0 +1,41 @@ + + + + + + + + Form + + + +
+
+ + + + +
+

+
+ +
+
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/03-javascript/portfolio-web/js/entities.mjs b/03-javascript/portfolio-web/web/js/entities.mjs similarity index 54% rename from 03-javascript/portfolio-web/js/entities.mjs rename to 03-javascript/portfolio-web/web/js/entities.mjs index f82a791..7d8fb2f 100644 --- a/03-javascript/portfolio-web/js/entities.mjs +++ b/03-javascript/portfolio-web/web/js/entities.mjs @@ -5,13 +5,9 @@ class UserProfile { this.description = description; this.profileImg = profileImg; } - - log() { - console.log(this.title); - } } -class Article { +export class Article { constructor(blogImg, dateOfPublish, category, title, description, link) { this.blogImg = blogImg; this.dateOfPublish = dateOfPublish; @@ -22,6 +18,20 @@ class Article { } } -class Project {} +export class Project { + constructor(logo,title, description, link) { + this.logo = logo; + this.title = title; + this.description = description; + this.link = link; + } +} -class Talks {} +export class Talk { + constructor(blogImg, language, title, description) { + this.blogImg = blogImg; + this.language = language; + this.title = title; + this.description = description; + } +} diff --git a/03-javascript/portfolio-web/web/js/portfolio.mjs b/03-javascript/portfolio-web/web/js/portfolio.mjs new file mode 100644 index 0000000..f50ad28 --- /dev/null +++ b/03-javascript/portfolio-web/web/js/portfolio.mjs @@ -0,0 +1,137 @@ +import account , {SignupRequest} from "./services/accounts.mjs"; +import UserProfileService from "./services/profile.mjs"; +import { Article, Project, Talk} from "./entities.mjs"; + +const userprofile = new UserProfileService() +//Define an array of articles, projects and talks + +/** + * Write a function to handle Signup request as per the design + */ +export function handleSignup(form) { + //if it fails, then you will show an error message + //if it succeeds, then you will show the signin form + let signUp= new SignupRequest(form.name.value, form.email.value, form.password.value) + let response= account.handleSignupRequest(signUp) + + if(response.success){ + const display= document.getElementById('signInform'); + display.style.display= 'block' + const signupform = document.getElementById('signupform'); + signupform.style.display='none' + } + else{ + const userError = document.getElementById('user-error'); + userError.innerText = response.message; + } +} +const article1= new Article('img','20thjan','meeting','hsaah','one','readpost') +const article2= new Article('imgBlog','20thfeb','meeting','hsaah','two','blogpost') + +const project1= new Project('webby','about webby','how webby is useful...','nexon.io') +const project2= new Project('netkool','aboutNetkool','how netkool is useful...','nexon.ion') +const talk1= new Talk('javascript-img','javascript','aboutjavascript','how to learn...') +const talk2= new Talk('python-img', 'python','aboutPython','how we can use pyhthon in our....') + +/** + * Write a function to handle Signin request as per the design +*/ +export function handleSignIn(form){ + let response= account.handleSignInRequest(form.email.value, form.password.value) + if(response.success){ + console.log(response.account) + userprofile.addArticle(response.account,article1) + userprofile.addArticle(response.account,article2) + userprofile.addProject(response.account,project1) + userprofile.addProject(response.account,project2) + userprofile.addTalk(response.account,talk1) + userprofile.addTalk(response.account,talk2) + + const articles = userprofile.getArticles(account); + const projects= userprofile.getProjects(account); + const talks= userprofile.getTalks(account); + createArticlesSection(articles) + createProjectSection(projects) + createTalkSection(talks) + userprofile.addArticle(account,article1) + userprofile.addArticle(account,article2) + const articles = userprofile.getArticles(account); + createArticlesSection(articles) + } + else{ + const error= document.getElementById('error'); + error.innerText= response.message + } + + // if it fails, show the error message + + //if it succeeds, show the portfolio website (navigation and about section) + + // Use UserProfileService get profile, articles, projects and talks + + // Add the about section +} +function createArticlesSection(articles) { + const articleSection = document.getElementById('article__section'); + const articlesHTML = articles.map(a => `
+
+ +
+

${a.dateOfPublish}

+

${a.category}

+
+
+

${a.title}

+

+ ${a.description} +

+
+ `) + + articleSection.innerHTML += articlesHTML.join('') +} +function createProjectSection(projects){ + const projectSection = document.getElementById('project__section'); + const projectHTML = projects.map(a => `
+ +
+ +

${a.description}

+
+
+ `) + projectSection.innerHTML += projectHTML.join('') +} +function createTalkSection(talks){ + const talkSection = document.getElementById('talk__section'); + const talksHTML = talks.map(a => `
+ +

${a.language}

+

${a.title}

+

${a.description}

+
+ `) + talkSection.innerHTML += talksHTML.join('') + + articleSection.innerHTML += articlesHTML.join('') + +} + + + + +window.handleSignup = handleSignup; +window.handleSignIn= handleSignIn; \ No newline at end of file diff --git a/03-javascript/portfolio-web/web/js/services/accounts.mjs b/03-javascript/portfolio-web/web/js/services/accounts.mjs new file mode 100644 index 0000000..802689b --- /dev/null +++ b/03-javascript/portfolio-web/web/js/services/accounts.mjs @@ -0,0 +1,79 @@ + +/** + * Utility class for storing response + */ +export class Response { + constructor(success, message,account) { + this.success = success; + this.message = message; + this.account= account; + } +} + +/** + * Create a signup request class + */ +export class SignupRequest { + constructor(name, email, password) { + this.name= name; + this.email= email; + this.password= password; + } + +} + +/** + * Create a UserAccount class + */ +export class UserAccount { + constructor(email, password) { + this.email= email; + this.password= password + } +} + +class AccountService { + /** + * Stores a map of user accounts + * where the key is the email and value is the UserAccount object + * @param {*} accounts + */ + constructor(accounts) { + this.accounts = accounts; + } + + /** + * if user with that email already exists then return an object of type + * Response - new Response(false, 'User already exists with this email') + * else return new Response(true, 'You have successfully signed up') + * @param {*} request of type SignupRequest + */ + handleSignupRequest(request) { + if (this.accounts.has(request.email)){ + return new Response(false,'User already exists with this email') + } + else{ + this.accounts.set(request.email, new UserAccount(request.email,request.password)) + return new Response(true,'You have successfully signed up') + } + } + + /** + * Authenticate using email and password + * @param {*} email + * @param {*} password + * @returns + */ + handleSignInRequest(email,password){ + if (this.accounts.has(email) && this.accounts.get(email).password== password){ + return new Response(true,'authenticated', this.accounts.get(email)) + } + else{ + return new Response(false,'invalid email or password') + } + } +} + +//Create an empty Map for storing users +const account = new AccountService(new Map()); +export default account \ No newline at end of file diff --git a/03-javascript/portfolio-web/web/js/services/profile.mjs b/03-javascript/portfolio-web/web/js/services/profile.mjs new file mode 100644 index 0000000..d6509a0 --- /dev/null +++ b/03-javascript/portfolio-web/web/js/services/profile.mjs @@ -0,0 +1,52 @@ +import ArticleStore from "../stores/articles.mjs"; +import ProjectStore from "../stores/project.mjs"; +import TalkStore from "../stores/talks.mjs"; + +class UserProfileService { + constructor() { + this.articlesStore = new ArticleStore(new Map()); + this.projectStore = new ProjectStore(new Map()); + this.talkStore = new TalkStore(new Map()); + } + + addArticle(account,article) { + this.articlesStore.addArticle(account,article); + } + + getArticles(account) { + return this.articlesStore.getArticles(account); + } + addProject(account,project){ + this.projectStore.addProject(account,project); + } + getProjects(account){ + return this.projectStore.getProjects(account); + } + addTalk(account,talk){ + this.talkStoreStore.addTalk(account,talk); + } + getTalks(account){ + return this.talkStore.getTalks(account); + } +} + +/** + * Find the latest article + */ + //latestArticle() {} + + /** + * (1)Function to return the article based on the link + * @param {*} link + */ + //getArticle(link) { + // to get the article + // analyticsService.push({'view', link, 'article'}) + //} + + /** + * (4)Find the most viewed article + */ + //getMostViewedArticle() {} +//} +export default UserProfileService; diff --git a/03-javascript/portfolio-web/web/js/stores/articles.mjs b/03-javascript/portfolio-web/web/js/stores/articles.mjs new file mode 100644 index 0000000..4b4cecc --- /dev/null +++ b/03-javascript/portfolio-web/web/js/stores/articles.mjs @@ -0,0 +1,91 @@ +class ArticleStore { + /** + * Constructor to initialize the store using local storage + * @param {*} accountWithArticles + */ + constructor(accountWithArticles) { + if (accountWithArticles && accountWithArticles.size > 0) { + // Iterate through each user account and their articles + for (const [account, articles] of accountWithArticles) { + if (Array.isArray(articles) && articles.length > 0) { + // Store articles array in localStorage with user email as key + localStorage.setItem(`articles-${account}`, JSON.stringify(articles)); + } + } + } + } + + /** + * Add a method to add an article to the user's account + * @param {*} account + * @param {*} article + */ + addArticle(account, article) { + + if(localStorage.getItem(`articles-${account}`) == null){ + localStorage.setItem(`articles-${account}`,JSON.stringify(article)) + } + else { + const articlesString= localStorage.getItem(`articles-${account}`) + const articlesArray= JSON.parse(articlesString) + articlesArray.push(article) + localStorage.setItem(`articles-${account}`,JSON.stringify(articlesArray)) + } + } + /** + * Add a method to get all articles for a user + * @param {*} account + * @returns + */ + getArticles(account) { + const articleString=localStorage.getItem(`articles-${account.email}`) + const articleArray=JSON.parse(articleString) + return articleArray + } + deleteArticles(account){ + localStorage.removeItem(`articles-${account}`) + } + + /** + * Add a method to get the latest article of a user + */ + getLatestArticle(account) { + for(let i=0; inew Date(a.dateOfPublish).getTime()) + const latestArticle={date:0, article:object[0]} + for (let i in articlesarray){ + if (latestArticleDate[i]> latestArticle.date){ + latestArticle.date= latestArticleDate[i] + latestArticle.article= object[i] + } + return latestArticle.article + } + } + } + } + + /** + * Add a method to get the oldest article of a user + */ + getOldestArticle(account) { + for(let i=0; inew Date(a.dateOfPublish).getTime()) + const oldestArticle={date:oldestArticleDate[0], article:object[0]} + for (let j in articlesarray){ + if (oldestArticle[j] < oldestArticle.date){ + oldestArticle.date= oldestArticleDate[j] + oldestArticle.article= object[j] + } + return oldestArticle.article + } + } +} +} +} +export default ArticleStore; diff --git a/03-javascript/portfolio-web/web/js/stores/project.mjs b/03-javascript/portfolio-web/web/js/stores/project.mjs new file mode 100644 index 0000000..44ed201 --- /dev/null +++ b/03-javascript/portfolio-web/web/js/stores/project.mjs @@ -0,0 +1,37 @@ +class ProjectStore { + constructor(accountWithProjects) { + if (accountWithProjects && accountWithProjects.size > 0) { + for (const [account, projects] of accountWithProjects) { + if (Array.isArray(projects) && projects.length > 0) { + localStorage.setItem(`projects-${account}`, JSON.stringify(projects)); + } + } + } + } + addProject(account, project) { + if(localStorage.getItem(`projects-${account}`) == null){ + + localStorage.setItem(`projects-${account}`,JSON.stringify([project])) + } + else { + const projectsString= localStorage.getItem(`projects-${account}`) + const projectsArray = JSON.parse(projectsString); + localStorage.setItem(`projects-${account}`,JSON.stringify(project)) + } + else { + const projectsString= localStorage.getItem(`projects-${account}`) + const projectsArray= JSON.parse(projectsString) + articlesArray.push(project) + localStorage.setItem(`projects-${account}`,JSON.stringify(projectsArray)) + } + } + getProjects(account) { + const projectString=localStorage.getItem(`projects-${account}`) + const projectArray=JSON.parse(projectString) + return projectArray + } + deleteProjects(account){ + localStorage.removeItem(`projects-${account}`) + } +} +export default ProjectStore; \ No newline at end of file diff --git a/03-javascript/portfolio-web/web/js/stores/talks.mjs b/03-javascript/portfolio-web/web/js/stores/talks.mjs new file mode 100644 index 0000000..c0beaf2 --- /dev/null +++ b/03-javascript/portfolio-web/web/js/stores/talks.mjs @@ -0,0 +1,32 @@ +class TalkStore { + constructor(accountWithTalks) { + if (accountWithTalks && accountWithTalks.size > 0) { + for (const [account, talks] of accountWithTalks) { + if (Array.isArray(talks) && talks.length > 0) { + localStorage.setItem(`talks-${account}`, JSON.stringify(talks)); + } + } + } + } + addTalk(account, talk) { + if(localStorage.getItem(`talks-${account}`) == null){ + localStorage.setItem(`talks-${account}`,JSON.stringify(talk)) + } + else { + const talksString= localStorage.getItem(`talks-${account}`) + const talksArray= JSON.parse(talksString) + talksArray.push(talk) + localStorage.setItem(`talks-${account}`,JSON.stringify(talksArray)) + } + } + getTalks(account) { + const TalksString=localStorage.getItem(`talks-${account}`) + const TalksArray=JSON.parse(TalksString) + return TalksArray + } + deleteTalks(account){ + localStorage.removeItem(`talks-${account}`) + } +} +export default TalkStore; + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/.gitignore b/04-react-portfolio/learn-react/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/04-react-portfolio/learn-react/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/04-react-portfolio/learn-react/README.md b/04-react-portfolio/learn-react/README.md new file mode 100644 index 0000000..a75ac52 --- /dev/null +++ b/04-react-portfolio/learn-react/README.md @@ -0,0 +1,40 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. + +[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. + +The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/04-react-portfolio/learn-react/next.config.mjs b/04-react-portfolio/learn-react/next.config.mjs new file mode 100644 index 0000000..d5456a1 --- /dev/null +++ b/04-react-portfolio/learn-react/next.config.mjs @@ -0,0 +1,6 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, +}; + +export default nextConfig; diff --git a/04-react-portfolio/learn-react/package-lock.json b/04-react-portfolio/learn-react/package-lock.json new file mode 100644 index 0000000..7d080f7 --- /dev/null +++ b/04-react-portfolio/learn-react/package-lock.json @@ -0,0 +1,498 @@ +{ + "name": "learn-react", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "learn-react", + "version": "0.1.0", + "dependencies": { + "next": "14.2.24", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "typescript": "^5" + } + }, + "node_modules/@next/env": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.24.tgz", + "integrity": "sha512-LAm0Is2KHTNT6IT16lxT+suD0u+VVfYNQqM+EJTKuFRRuY2z+zj01kueWXPCxbMBDt0B5vONYzabHGUNbZYAhA==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.24.tgz", + "integrity": "sha512-7Tdi13aojnAZGpapVU6meVSpNzgrFwZ8joDcNS8cJVNuP3zqqrLqeory9Xec5TJZR/stsGJdfwo8KeyloT3+rQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.24.tgz", + "integrity": "sha512-lXR2WQqUtu69l5JMdTwSvQUkdqAhEWOqJEYUQ21QczQsAlNOW2kWZCucA6b3EXmPbcvmHB1kSZDua/713d52xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.24.tgz", + "integrity": "sha512-nxvJgWOpSNmzidYvvGDfXwxkijb6hL9+cjZx1PVG6urr2h2jUqBALkKjT7kpfurRWicK6hFOvarmaWsINT1hnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.24.tgz", + "integrity": "sha512-PaBgOPhqa4Abxa3y/P92F3kklNPsiFjcjldQGT7kFmiY5nuFn8ClBEoX8GIpqU1ODP2y8P6hio6vTomx2Vy0UQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.24.tgz", + "integrity": "sha512-vEbyadiRI7GOr94hd2AB15LFVgcJZQWu7Cdi9cWjCMeCiUsHWA0U5BkGPuoYRnTxTn0HacuMb9NeAmStfBCLoQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.24.tgz", + "integrity": "sha512-df0FC9ptaYsd8nQCINCzFtDWtko8PNRTAU0/+d7hy47E0oC17tI54U/0NdGk7l/76jz1J377dvRjmt6IUdkpzQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.24.tgz", + "integrity": "sha512-ZEntbLjeYAJ286eAqbxpZHhDFYpYjArotQ+/TW9j7UROh0DUmX7wYDGtsTPpfCV8V+UoqHBPU7q9D4nDNH014Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.24.tgz", + "integrity": "sha512-9KuS+XUXM3T6v7leeWU0erpJ6NsFIwiTFD5nzNg8J5uo/DMIPvCp3L1Ao5HjbHX0gkWPB1VrKoo/Il4F0cGK2Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.24.tgz", + "integrity": "sha512-cXcJ2+x0fXQ2CntaE00d7uUH+u1Bfp/E0HsNQH79YiLaZE5Rbm7dZzyAYccn3uICM7mw+DxoMqEfGXZtF4Fgaw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@types/node": { + "version": "20.17.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.19.tgz", + "integrity": "sha512-LEwC7o1ifqg/6r2gn9Dns0f1rhK+fPFDoMiceTJ6kWmVk6bgXBI/9IOWfVan4WiAavK9pIVWdX0/e3J+eEUh5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001700", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", + "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "14.2.24", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.24.tgz", + "integrity": "sha512-En8VEexSJ0Py2FfVnRRh8gtERwDRaJGNvsvad47ShkC2Yi8AXQPXEA2vKoDJlGFSj5WE5SyF21zNi4M5gyi+SQ==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.24", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.24", + "@next/swc-darwin-x64": "14.2.24", + "@next/swc-linux-arm64-gnu": "14.2.24", + "@next/swc-linux-arm64-musl": "14.2.24", + "@next/swc-linux-x64-gnu": "14.2.24", + "@next/swc-linux-x64-musl": "14.2.24", + "@next/swc-win32-arm64-msvc": "14.2.24", + "@next/swc-win32-ia32-msvc": "14.2.24", + "@next/swc-win32-x64-msvc": "14.2.24" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/04-react-portfolio/learn-react/package.json b/04-react-portfolio/learn-react/package.json new file mode 100644 index 0000000..7d3123f --- /dev/null +++ b/04-react-portfolio/learn-react/package.json @@ -0,0 +1,22 @@ +{ + "name": "learn-react", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "react": "^18", + "react-dom": "^18", + "next": "14.2.24" + }, + "devDependencies": { + "typescript": "^5", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18" + } +} diff --git a/04-react-portfolio/learn-react/public/favicon.ico b/04-react-portfolio/learn-react/public/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/04-react-portfolio/learn-react/public/favicon.ico differ diff --git a/04-react-portfolio/learn-react/public/images/5680244.png b/04-react-portfolio/learn-react/public/images/5680244.png new file mode 100644 index 0000000..2b83d5d Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/5680244.png differ diff --git a/04-react-portfolio/learn-react/public/images/about.svg b/04-react-portfolio/learn-react/public/images/about.svg new file mode 100644 index 0000000..c82a4e4 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/about.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/public/images/art-of-debug.png b/04-react-portfolio/learn-react/public/images/art-of-debug.png new file mode 100644 index 0000000..3295cdb Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/art-of-debug.png differ diff --git a/04-react-portfolio/learn-react/public/images/article.svg b/04-react-portfolio/learn-react/public/images/article.svg new file mode 100644 index 0000000..330d2f4 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/article.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/public/images/download.png b/04-react-portfolio/learn-react/public/images/download.png new file mode 100644 index 0000000..85a8f70 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/download.png differ diff --git a/04-react-portfolio/learn-react/public/images/focus.png b/04-react-portfolio/learn-react/public/images/focus.png new file mode 100644 index 0000000..76497d5 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/focus.png differ diff --git a/04-react-portfolio/learn-react/public/images/icons8-close.svg b/04-react-portfolio/learn-react/public/images/icons8-close.svg new file mode 100644 index 0000000..62fa7c6 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/icons8-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/public/images/images.png b/04-react-portfolio/learn-react/public/images/images.png new file mode 100644 index 0000000..4813d76 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/images.png differ diff --git a/04-react-portfolio/learn-react/public/images/js.jpeg b/04-react-portfolio/learn-react/public/images/js.jpeg new file mode 100644 index 0000000..4a0e771 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/js.jpeg differ diff --git a/04-react-portfolio/learn-react/public/images/meetup.png b/04-react-portfolio/learn-react/public/images/meetup.png new file mode 100644 index 0000000..2059c94 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/meetup.png differ diff --git a/04-react-portfolio/learn-react/public/images/microphone.jpg b/04-react-portfolio/learn-react/public/images/microphone.jpg new file mode 100644 index 0000000..335a6de Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/microphone.jpg differ diff --git a/04-react-portfolio/learn-react/public/images/netkool.svg b/04-react-portfolio/learn-react/public/images/netkool.svg new file mode 100644 index 0000000..7abfd87 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/netkool.svg @@ -0,0 +1,3 @@ + + + diff --git a/04-react-portfolio/learn-react/public/images/nextjs.jpeg b/04-react-portfolio/learn-react/public/images/nextjs.jpeg new file mode 100644 index 0000000..74917bb Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/nextjs.jpeg differ diff --git a/04-react-portfolio/learn-react/public/images/paris.jpg b/04-react-portfolio/learn-react/public/images/paris.jpg new file mode 100644 index 0000000..27e143d Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/paris.jpg differ diff --git a/04-react-portfolio/learn-react/public/images/phone.svg b/04-react-portfolio/learn-react/public/images/phone.svg new file mode 100644 index 0000000..5baa934 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/phone.svg @@ -0,0 +1,3 @@ + + + diff --git a/04-react-portfolio/learn-react/public/images/project.svg b/04-react-portfolio/learn-react/public/images/project.svg new file mode 100644 index 0000000..7bf182a --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/project.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/public/images/react.jpeg b/04-react-portfolio/learn-react/public/images/react.jpeg new file mode 100644 index 0000000..51cbdc9 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/react.jpeg differ diff --git a/04-react-portfolio/learn-react/public/images/spain.jpg b/04-react-portfolio/learn-react/public/images/spain.jpg new file mode 100644 index 0000000..09d3a30 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/spain.jpg differ diff --git a/04-react-portfolio/learn-react/public/images/talk.svg b/04-react-portfolio/learn-react/public/images/talk.svg new file mode 100644 index 0000000..810101b --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/talk.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/04-react-portfolio/learn-react/public/images/torqbit.png b/04-react-portfolio/learn-react/public/images/torqbit.png new file mode 100644 index 0000000..a146d3c Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/torqbit.png differ diff --git a/04-react-portfolio/learn-react/public/images/uifaces-popular-image.jpg b/04-react-portfolio/learn-react/public/images/uifaces-popular-image.jpg new file mode 100644 index 0000000..0547184 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/uifaces-popular-image.jpg differ diff --git a/04-react-portfolio/learn-react/public/images/usa.jpg b/04-react-portfolio/learn-react/public/images/usa.jpg new file mode 100644 index 0000000..54917c2 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/usa.jpg differ diff --git a/04-react-portfolio/learn-react/public/images/vscode-plugin.png b/04-react-portfolio/learn-react/public/images/vscode-plugin.png new file mode 100644 index 0000000..e185727 Binary files /dev/null and b/04-react-portfolio/learn-react/public/images/vscode-plugin.png differ diff --git a/04-react-portfolio/learn-react/public/images/webby.svg b/04-react-portfolio/learn-react/public/images/webby.svg new file mode 100644 index 0000000..1f6e769 --- /dev/null +++ b/04-react-portfolio/learn-react/public/images/webby.svg @@ -0,0 +1,3 @@ + + + diff --git a/04-react-portfolio/learn-react/src/components/Fetch API/basicDataFetcher.tsx b/04-react-portfolio/learn-react/src/components/Fetch API/basicDataFetcher.tsx new file mode 100644 index 0000000..8d49f36 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Fetch API/basicDataFetcher.tsx @@ -0,0 +1,40 @@ +import React from 'react' +import {useState,useEffect, FC} from 'react' + +interface User { + id: number; + name: string; + email: string; + } + +export const BasicFetch: FC = () => { + const [users, setUsers] = useState([]); + const [error, setError] = useState(null); + useEffect(() => { + fetch("https://jsonplaceholder.typicode.com/users") + .then(response => { + if(response.ok){ + response.status + response.json().then(result => { + setUsers(result) + }) + } else { + throw new Error(`HTTP error! Status: ${response.status}`); + } + }).catch(error => { + setError(new error("Error fetching data")); + + }) + },[]) + + return ( +
+

FETCH EXAMPLE

+
    + {users.map(user => ( +
  • {user.name} - {user.email}
  • + ))} +
+
+ ); + }; \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Fetch API/example.tsx b/04-react-portfolio/learn-react/src/components/Fetch API/example.tsx new file mode 100644 index 0000000..e5718a4 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Fetch API/example.tsx @@ -0,0 +1,28 @@ +import {useState,useEffect, FC} from 'react' + +export const GetExample: FC = () => { + + useEffect(() => { + fetch("https://jsonplaceholder.typicode.com/posts").then(response => { + if(response.ok){ + //status code + // we got the response + response.status + response.json().then(result => { + console.log(result) + }) + } else { + // we get the errors received from the server + } + }).catch(error => { + // error when fetch was unable to connect with the given url + + }) + },[]) + + return ( + <> +

FETCH EXAMPLE +

+ ) + } \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Fetch API/postDataFetch.tsx b/04-react-portfolio/learn-react/src/components/Fetch API/postDataFetch.tsx new file mode 100644 index 0000000..df6b936 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Fetch API/postDataFetch.tsx @@ -0,0 +1,45 @@ +import React from 'react' +import {useState,useEffect, FC} from 'react' + +interface Post { + id: number; + title: string; + body: string; + userId: number; +} +export const BasicFetch: FC = () => { + const [users, setUsers] = useState([]); + const [error, setError] = useState(null); + useEffect(() => { + fetch("https://jsonplaceholder.typicode.com/users", { + method: "POST", + headers:{ + 'Content-Type': 'application/json', + }, + }) + .then(response => { + if(response.ok){ + response.status + response.json().then(result => { + setUsers(result) + }) + } else { + throw new Error(`HTTP error! Status: ${response.status}`); + } + }).catch(error => { + setError(new error("Error fetching data")); + + }) + },[]) + + return ( +
+

FETCH EXAMPLE

+
    + {users.map(user => ( +
  • {user.name} - {user.email}
  • + ))} +
+
+ ); + }; diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/About/About.css b/04-react-portfolio/learn-react/src/components/Portfolio/About/About.css new file mode 100644 index 0000000..d8384f5 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/About/About.css @@ -0,0 +1,47 @@ +.about{ + width: var(--container-width); + margin: 50px auto; +} +.about__container{ + display:flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.edit__container{ + display: flex; + flex-direction: row; +} +.img__container{ + position: relative; + width: 170px; + height: 170px; + padding: 5px; + border-radius: 50%; + background: linear-gradient(to bottom, rgb(148, 144, 144), rgb(17, 17, 17)); +} +.img__container img{ + width:150px; + height:150px; + position: absolute; + border-radius: 50%; + padding: 8px; + background-color: #121213;; +} +.about__container p{ + font-size:30px; + font-weight: bold; + background: linear-gradient(to right, rgb(207, 206, 206), #444444); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} +.about__container h1{ + margin:0; + max-width: 800px; + text-align: center; + margin-bottom: 20px; + background: linear-gradient(to right, #999 0%, #fff 50%, #999 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + +} \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/About/About.tsx b/04-react-portfolio/learn-react/src/components/Portfolio/About/About.tsx new file mode 100644 index 0000000..f76da68 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/About/About.tsx @@ -0,0 +1,44 @@ +import styles from '@/styles/Portfolio/About.module.css' +import { useRouter } from 'next/router'; +import {FC, useContext, useEffect, useState} from "react"; + +export type AboutProps = { + img: string | null; + name: string | null; + description: string | null; +} + + +export const About: FC = ({name, description, img}) =>{ + const[abouthighlight, setabout] = useState(false) + const[displaynum, setdisplaynum] = useState() + useEffect(()=>{ + setTimeout(() => { + setdisplaynum(5) + + }, 3000); + },[]) + + const router = useRouter() + + return( +
setabout(true)} onMouseLeave={(e:any)=> setabout(false)}> +
+ {displaynum != null &&( +

{displaynum}

+ )} +
+ {img != null &&( + )} +
+ {abouthighlight &&( + )} +

Hey,I'm {name}

+

+ {description} +

+
+
+ ) +} + diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.css b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.css new file mode 100644 index 0000000..ea4b0f6 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.css @@ -0,0 +1,72 @@ +.article{ + width:var(--container-width); + margin: 50px auto; +} +.article p{ + color: white; +} +.article hr{ + border-color: #2d2d36b4; + border-width: 1px; + margin-bottom: 30px; +} +.grid{ + display:grid; + grid-template-columns: auto auto; + gap:var(--gap); +} +.blog{ + display:flex; + flex-direction: column; + width:var(--article-flex-width); + height: 350px; + background-color: var(--card-bg); + border-radius: 10px; +} +.image{ + position: relative; + height:200px; +} +.blog>.image img{ + width:var(--article-img-width); + height: 200px; + border-radius: 5px; +} +.blog>.image>.date{ + display: flex; + background-color: #ffffff7a; + position:absolute; + padding:10px 20px 10px 10px; + bottom:0; + width: calc(var(--article-img-width) - 30px); + justify-content: space-between; +} +.blog>.image>.date p{ + margin:0; + font-size:12px; +} +.grid p{ + padding: 0 12px; +} +.grid>.blog>p:last-of-type{ + font-size:13px; + color:rgba(189, 212, 207, 0.87); + margin-top: 0; +} +.article__link{ + display: flex; + justify-items: center; +} +.article__link p{ + font-size: 13px; + margin: 10px 0; +} + svg{ + margin:10px 5px; + color:rgba(189, 212, 207, 0.87) ; +} +@media screen and (max-width:430px){ + .grid{ + grid-template-columns: 1fr; + } +} diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.tsx b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.tsx new file mode 100644 index 0000000..295d9cf --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/Article.tsx @@ -0,0 +1,57 @@ +import styles from '@/styles/Portfolio/Article.module.css' +import {FC} from "react"; +import articleList from './ArticleStore'; + +export type ArticleProps = { + blogImg: string; + dateOfPublish: string; + category: string; + title: string; + description: string; + articleLink: string +} + +export const Articles: FC<{articles: ArticleProps[]}> = ({articles}) => { + + return( +
+

Articles

+
+
+ {articles.map(article => ( + + ))} +
+
+ ) +} + +const ArticleCard: FC<{blogImg: string, dateOfPublish:string, category:string, title:string, description:string, articleLink:string}>=({blogImg, dateOfPublish, category, title, description, articleLink}) => ( +
+
+ +
+

{dateOfPublish}

+

{category}

+
+
+

{title}

+

{description}

+ +

Read post

+ + + + + +
+
+) \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Articles/ArticleStore.ts b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/ArticleStore.ts new file mode 100644 index 0000000..843f60b --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Articles/ArticleStore.ts @@ -0,0 +1,43 @@ +class Article{ + + blogImg: string; + dateOfPublish: string; + category:string; + title:string; + description: string; + readLink:string; + linkLogo:string + + constructor(blogImg: string, dateOfPublish: string, category: string, title: string, description: string, readLink: string, linkLogo: string){ + this.blogImg=blogImg + this.dateOfPublish= dateOfPublish + this.category=category + this.title= title + this.description=description + this.readLink= readLink + this.linkLogo= linkLogo + } +} +class ArticleStore{ + articles:Article[] + constructor(){ + this.articles = [] + } + addArticle(article:Article){ + this.articles.push(article) + } + getArticles() { + return this.articles; + } +} +const a1= new Article('./images/meetup.png','20th Jan 2025','Meetups','How to use Meetups to generate leads','You talk aboout something you built, and share the strategy of how someone made benefit out of it, and thats it.You are onto to your...','Read Post','') +const a2= new Article('./images/art-of-debug.png','2nd Jan 2025','Engineering','The Art of Debugging',' We all spent countless hours in debugging and optimizing backend applications do we take time to practice clean coding in...','Read Post','') +const a3= new Article('./images/vscode-plugin.png','5th Jan 2025','Engineering','The power of VSCode plugins',' Your development environment-VSCode, is more powerful than you would have imagined. If you want to accelerate your development...','Read Post','') +const a4= new Article('./images/focus.png','20th Jan 2025','Meetups','Focus is everything',"Your workplace isn't just about a table,chair and laptop. Its a piece where you craft the art,that can run systems of multiple companies",'Read Post','') +const articleList = new ArticleStore() +articleList.addArticle(a1) +articleList.addArticle(a2) +articleList.addArticle(a3) +articleList.addArticle(a4) + +export default articleList; \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.css b/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.css new file mode 100644 index 0000000..4cc2ffa --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.css @@ -0,0 +1,86 @@ +nav { + width: var(--container-width); + height: 60px; + background-color: #2b2b40; + margin: 50px auto; + border-radius: 30px; +} +.head { + display: flex; + height: 60px; + padding: 0px 8px 0px 40px; + align-items: center; + justify-items: center; + justify-content: space-between; + +} + +.head h1 { + font-size: 20px; + margin-left: 40px; + color: rgba(189, 212, 207, 0.87); + font-weight: lighter; +} +.head b{ + font-size: 20px; + color: white; + font-weight: 500; +} + +.links { + display: flex; + gap: 30px; +} +ul>li>a{ + font-size: 17px; + color: rgba(189, 212, 207, 0.87); +} +.icon { + display: flex; + gap:10px; + padding:10px 18px; + background-color: rgb(71, 71, 177); + border-radius: 26px; +} + +.icon img { + height: 20px; +} +.icon p{ + margin:0; + font-size: 18px; + color: white; + font-weight: normal; +} +@media screen and (max-width:430px){ + nav{ + margin: 15px auto; + height: 40px; + } + .head{ + padding:0 8px 0 20px; + height:40px; + } + .head h1 { + font-size: 15px; + margin:0; + } + .head b{ + font-size: 15px; + } + + + .links{ + display: none; + } + .icon{ + padding:6px 16px; + } + .icon p{ + font-size: 15px; + } + .icon img { + height: 17px; + } + +} \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.tsx b/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.tsx new file mode 100644 index 0000000..c34354d --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Nav/Nav.tsx @@ -0,0 +1,33 @@ +import styles from '@/styles/Portfolio/Nav.module.css' +import {FC} from "react"; + +type NavProps ={ + firstName: string; + lastName: string; + //onClickHandler: () => void; + links: string[]; + btnlogo : string; + content: string; +} + +export const Nav : FC = ({firstName, lastName , links, btnlogo, content}) => { + return +} +const FullName :FC<{firstname:string, lastname:string}> = ({firstname , lastname}) => ( +

{firstname} {lastname}

+) +const NavLinks: FC<{links:string[]}> = ({links}) => ( +
    + {links.map(li =>
  • {li}
  • )} +
) + +const Contact: FC<{logo:string, content:string}> = ({logo, content}) => ( + + +

{content}

+
+) \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.css b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.css new file mode 100644 index 0000000..4c93a05 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.css @@ -0,0 +1,88 @@ +.project{ + width:var(--container-width); + margin: 50px auto; +} +.project p{ + color:#ffffff; +} +.project hr{ + border-color:#2d2d36b4; + border-width: 1px; + margin-bottom: 40px; +} +.project__container{ + display:flex; + gap:var(--gap); +} +.content{ + width: var(--project-flex-width); + display:flex; + padding: 10px; + background-color:#2b2b40; + border-radius: 10px; + align-items: center; + justify-items: center; + gap:20px; +} +.content img{ + height:30px; + width:30px; + padding:10px; + border-radius: 50%; +} +img#yellow{ + background: linear-gradient(to top, #ff7e5f 60%, #feb47b ); +} +img#pink{ + background: linear-gradient(to top, #df68cb 30%, #4136d8 ); +} +.project__description{ + width:335px; +} +.project__description>.project__name p{ + font-size:20px; + margin:0; + margin-top: 10px; + color: #ffffff; +} +.project__description p{ + font-size: 12px; + margin:0; + margin-top: 10px; + margin-bottom:10px; + color: #bdd4cfde; +} +.project__name{ + display:flex; + justify-content: space-between; + align-items: center; +} +.project__name>.web__link{ + display: flex; + padding:0; + margin:0; + background-color:#474768; + align-items: center; + justify-items: center; + gap:4px; + border-radius: 3px; + padding:0 12px; + height:20px; +} +.project__name>.web__link>p{ + margin:0; + font-size: small; + color: #bdd4cfde; +} +.project__name>.web__link>i>svg{ + margin:0; + font-size: 15px; + color:#bdd4cfde; +} + +@media screen and (max-width:430px){ + .project__container{ + display:flex; + flex-direction: column; + } +} diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.tsx b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.tsx new file mode 100644 index 0000000..37b4f4c --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/Project.tsx @@ -0,0 +1,55 @@ +import styles from '@/styles//Portfolio/Projects.module.css' +import {FC} from "react"; + +export type ProjectProps ={ + logo:string, + title:string, + description:string, + link:string, + arrow:string; +} +export const Projects: FC<{projects : ProjectProps[]}>= ({projects}) =>{ + // const updateColour = (logo:string) =>{ + // if (logo.includes("project1")) return styles.project1; + // if (logo.includes("project2")) return styles.project2; + // } + return( +
+

Projects

+
+
+ {projects.map(project => + + )} +
+
+ ) +} +const ProjectCard: FC<({logo:string,title: string, description:string, link:string, arrow:string})>=({logo,title, description, link, arrow})=>( +
+ +
+ +

{description}

+
+
+) \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Projects/ProjectStore.js b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/ProjectStore.js new file mode 100644 index 0000000..5611575 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Projects/ProjectStore.js @@ -0,0 +1,26 @@ +class Project{ + constructor(logo,title, description, link, arrow){ + this.logo=logo + this.title= title + this.description= description + this.link= link + this.arrow= arrow + } +} +class ProjectStore{ + constructor(){ + this.projects = [] + } + addProject(project){ + this.projects.push(project) + } + getProjects() { + return this.projects; + } +} +const p1= new Project('./images/netkool.svg','Netkool','Networking platform for school students','netkool.io') +const p2= new Project('./images/webby.svg','Webby','Website analytics platform','webby.dev') +const projectList = new ProjectStore() +projectList.addProject(p1) +projectList.addProject(p2) +export default projectList; \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.css b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.css new file mode 100644 index 0000000..e5ea1ce --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.css @@ -0,0 +1,70 @@ +.talks{ + width:var(--container-width); + margin: 50px auto; +} +.talks p{ + color:white; +} +.talks hr{ + border-color: #2d2d36b4; + border-width: 1px; + margin-bottom: 40px; +} +.talks__topic{ + display:flex; + gap:var(--gap); +} +.language{ + width:var(--talk-flex-width); + border-radius: 5px; + background-color: #2b2b40; +} +.language img{ + width:var(--talk-img-width); + border-radius: 5px 5px 0 0; + height:140px; + object-fit: cover; +} +.language p:first-of-type{ + font-size: 12px; + padding:4px 10px; + max-width: max-content; + border-radius: 4px; + color: black; + margin-left: 15px; +} +.language>#white{ + background-color: antiquewhite; +} +.language>#green{ + background-color:rgb(177, 233, 177) ; +} +.language>#blue{ + background-color: lightblue; +} + + +.language p:nth-last-of-type(even){ + font-size: 13px; + margin-left: 15px; + margin-right:20px; + color:antiquewhite; +} +.language p:last-of-type{ + font-size: 11px; + margin-left: 15px; + margin-right: 20px; + margin-bottom: 30px; + color: rgba(189, 212, 207, 0.87); + +} +@media screen and (max-width:430px){ + .talks{ + margin:50px auto 0 auto; + } + .talks__topic{ + display:flex; + flex-direction: column; + } + +} \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.tsx b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.tsx new file mode 100644 index 0000000..3513725 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/Talk.tsx @@ -0,0 +1,36 @@ +import styles from '@/styles/Portfolio/Talks.module.css' +import {FC} from "react"; + +export type TalkProps ={ + blogImg: string; + language:string; + title:string; + description:string; +} + +export const Talks : FC<{talks:TalkProps[]}>=({talks}) =>{ + return( +
+

Talks

+
+
+ {talks.map(talk=> + + )} +
+
+ ) +} +const TalkCard: FC<({blogImg:string, language:string, title:string, description:string})>= ({blogImg, language, title, description})=>( +
+ +

{language}

+

{title}

+

{description}

+
+) \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/Portfolio/Talks/TalkStore.js b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/TalkStore.js new file mode 100644 index 0000000..510c3a0 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/Portfolio/Talks/TalkStore.js @@ -0,0 +1,28 @@ +class Talk{ + constructor(blogImg, language, title, description){ + this.blogImg= blogImg + this.language= language + this.title= title + this.description= description + } +} +class TalkStore{ + constructor(){ + this.talks = [] + } + addTalk(talk){ + this.talks.push(talk) + } + getTalks() { + return this.talks; + } +} +const t1= new Talk('./images/js.jpeg','Javascript','Dynamic Programming Alogorithms in Javascript','In this talk,I explain the different DP algos that are important for cracking..') +const t2= new Talk('./images/react.jpeg','ReactJS','Optimise rendering of componenets in ReactJS','The real magic happens when you have thousands of componenets rendering..') +const t3= new Talk('./images/nextjs.jpeg','NextJS','Dynamic routes with Server side rendering in NextJS',' Imagine you want all your blog pages to be SEO optimised, an performant..') + +const talkList = new TalkStore() +talkList.addTalk(t1) +talkList.addTalk(t2) +talkList.addTalk(t3) +export default talkList; \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.css b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.css new file mode 100644 index 0000000..d8384f5 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.css @@ -0,0 +1,47 @@ +.about{ + width: var(--container-width); + margin: 50px auto; +} +.about__container{ + display:flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.edit__container{ + display: flex; + flex-direction: row; +} +.img__container{ + position: relative; + width: 170px; + height: 170px; + padding: 5px; + border-radius: 50%; + background: linear-gradient(to bottom, rgb(148, 144, 144), rgb(17, 17, 17)); +} +.img__container img{ + width:150px; + height:150px; + position: absolute; + border-radius: 50%; + padding: 8px; + background-color: #121213;; +} +.about__container p{ + font-size:30px; + font-weight: bold; + background: linear-gradient(to right, rgb(207, 206, 206), #444444); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} +.about__container h1{ + margin:0; + max-width: 800px; + text-align: center; + margin-bottom: 20px; + background: linear-gradient(to right, #999 0%, #fff 50%, #999 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + +} \ No newline at end of file diff --git a/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.tsx b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.tsx new file mode 100644 index 0000000..e1ad7b1 --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/About.tsx @@ -0,0 +1,28 @@ +import styles from '@/styles/portfolioEditor/About.module.css' +import { useRouter } from 'next/router'; +import {FC, useContext, useState} from "react"; + +export type AboutProps = { + img: string | null; + name: string | null; + description: string | null; +} + + +export const About: FC = ({name, description, img}) =>{ + return( +
+
+
+ {img != null &&( + )} +
+

Hey,I'm {name}

+

+ {description} +

+
+
+ ) +} + diff --git a/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/aboutform.tsx b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/aboutform.tsx new file mode 100644 index 0000000..dcfe5cb --- /dev/null +++ b/04-react-portfolio/learn-react/src/components/PortfolioEditor/About/aboutform.tsx @@ -0,0 +1,108 @@ +import { FC, useEffect, useState } from "react" +import styles from "@/styles/portfolioEditor/AboutForm.module.css" +import { useContext } from "react" +import { AppContext } from "@/components/useContext/appContext" + +export type AboutProps = { + firstname:string, + lastname:string , + name: string, + contact: number, + img: string, + description : string +} +export const aboutInitialState:AboutProps={ + firstname:"BELLA", + lastname:"DOE", + contact: 9857263235, + img: "images/uifaces-popular-image.jpg", + name: "Bella", + description : "I help Startsups through fast-paced full stack software development" +} + +export const Aboutform:FC=({firstname,lastname,contact,img,description,name})=>{ + + const { state, dispatch} = useContext(AppContext); + const [aboutDetails, setAboutDetails] = useState(state.about); + + useEffect(() => { + dispatch({ type: "INPUT_CHANGE", payload: aboutDetails}); + }, [aboutDetails]); + + + + return ( +
+

About Section

+
+
+ + setAboutDetails({...aboutDetails, firstname:e.currentTarget.value })} + required + /> +
+
+ + setAboutDetails({...aboutDetails, lastname:e.currentTarget.value })} + required + /> +
+
+ + setAboutDetails({...aboutDetails, name:e.currentTarget.value })} + required + /> +
+
+ + setAboutDetails({...aboutDetails, img:e.currentTarget.value })} + required + /> +
+
+ +