Exerciศiu Seminar:
Portofoliu personal cu DOM Manipulation ศi GitHub
Obiectiv general
Studenศii vor crea pagini personale dinamice folosind HTML, CSS, JavaScript ศi GitHub, consolidรขnd cunoศtinศele de manipulare DOM ศi colaborare prin Git.
Structura proiectului
web-portfolio-2025/
โ
โโโ index.html # Pagina principalฤ (catalog studenศi)
โโโ main.css # Stiluri pentru pagina principalฤ
โโโ main.js # Script pentru pagina principalฤ
โโโ students.json # JSON master cu lista studenศilor
โ
โโโ students/ # Folder pentru paginile individuale
โโโ popescu-ion/
โ โโโ index.html
โ โโโ styles.css
โ โโโ script.js
โ
โโโ ionescu-maria/
โ โโโ index.html
โ โโโ styles.css
โ โโโ script.js
โ
โโโ ... (alte foldere studenti)Cerinศe pentru fiecare student
1. Crearea paginii personale
Fiecare student va crea un folder รฎn students/ cu structura:
Nume folder:
prenume-nume(lowercase, cu cratimฤ, fฤrฤ diacritice)Exemplu:
popescu-ion,ionescu-maria
2. Structura JSON personalฤ (Hardcoded รฎn script.js)
script.js)// script.js - รฎncepe cu JSON-ul personal
const studentData = {
personalInfo: {
firstName: "Ion",
lastName: "Popescu",
email: "ion.popescu@csie.ase.ro",
phone: "+40 123 456 789",
birthDate: "2003-05-15"
},
education: {
university: "BUES",
faculty: "CSIE - eBusiness",
year: 1,
group: "1234A"
},
skills: [
{ name: "HTML", level: 80, category: "Frontend" },
{ name: "CSS", level: 75, category: "Frontend" },
{ name: "JavaScript", level: 70, category: "Frontend" },
{ name: "Python", level: 60, category: "Backend" }
],
projects: [
{
title: "Primul meu website",
description: "Un website personal creat cu HTML ศi CSS",
technologies: ["HTML", "CSS"],
link: "https://github.com/username/project1"
},
{
title: "Calculator JavaScript",
description: "Calculator funcศional cu operaศii matematice",
technologies: ["HTML", "CSS", "JavaScript"],
link: "https://github.com/username/project2"
}
],
avatar: "https://ui-avatars.com/api/?name=Ion+Popescu&size=200&background=random"
};Cerinศe JSON:
Minimum 3 niveluri de nested objects (exemplu:
studentData.personalInfo.firstName)Cel puศin 2 arrays cu obiecte (exemplu:
skills,projects)Proprietatea
avatartrebuie sฤ foloseascฤ un generator automat:UI Avatars:
https://ui-avatars.com/api/?name=Prenume+Nume&size=200DiceBear:
https://api.dicebear.com/7.x/initials/svg?seed=PrenumeNumeRoboHash:
https://robohash.org/PrenumeNume.png?size=200x200
3. Fiศierul index.html (template minimal)
index.html (template minimal)<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Portofoliu - [Prenume Nume]</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- Conศinutul va fi generat dinamic de JavaScript -->
<div id="app"></div>
<script src="script.js"></script>
</body>
</html>Cerinศฤ importantฤ: Tot conศinutul paginii trebuie generat dinamic prin JavaScript!
4. Fiศierul script.js (Manipulare DOM)
script.js (Manipulare DOM)Cerinศe obligatorii:
// 1. JSON-ul studentData (vezi mai sus)
// 2. Funcศie pentru crearea structurii paginii
function createPersonalPage() {
const app = document.getElementById('app');
// Creeazฤ elementele DOM dinamic:
// - Header cu avatar ศi nume
// - Secศiune informaศii personale
// - Secศiune educaศie
// - Secศiune skills (cu bare de progres)
// - Secศiune proiecte (carduri)
// - Footer cu link-uri sociale
// Exemplu pentru header:
const header = document.createElement('header');
header.className = 'hero';
const avatar = document.createElement('img');
avatar.src = studentData.avatar;
avatar.alt = `${studentData.personalInfo.firstName} ${studentData.personalInfo.lastName}`;
avatar.className = 'avatar';
const name = document.createElement('h1');
name.textContent = `${studentData.personalInfo.firstName} ${studentData.personalInfo.lastName}`;
header.appendChild(avatar);
header.appendChild(name);
app.appendChild(header);
// ... continuฤ cu restul secศiunilor
}
// 3. Apeleazฤ funcศia cรขnd DOM-ul este gata
document.addEventListener('DOMContentLoaded', createPersonalPage);Cerinศe tehnice pentru script.js:
Minimum 5 tipuri diferite de elemente HTML create dinamic
Folosirea
createElement,appendChild,textContent,innerHTMLSetarea
classNamesauclassListpentru stilizareIterare prin arrays cu
forEachsaufor...ofAcces la proprietฤศi nested din JSON (ex:
studentData.personalInfo.firstName)Cel puศin 1 event listener (exemplu: click pe proiect, hover pe skill)
5. Fiศierul styles.css
styles.cssCerinศe obligatorii:
Layout responsive (mobile-first cu media queries)
Stilizare pentru toate clasele folosite รฎn JavaScript
Minimum 3 culori coordonate (folosiศi CSS variables)
Avatar rotund cu
border-radius: 50%
Exemplu de structurฤ:
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--bg-color: #f8f9fa;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: var(--text-color);
background-color: var(--bg-color);
line-height: 1.6;
}
.hero {
text-align: center;
padding: 3rem 1rem;
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
color: white;
}
.avatar {
width: 200px;
height: 200px;
border-radius: 50%;
border: 5px solid white;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* ... restul stilurilor */Cerinศe pentru Pagina Principalฤ (catalog)
Responsabil: Un student voluntar
1. Fiศierul students.json (root), actualizat de studentul voluntar la fiecare pull request
students.json (root), actualizat de studentul voluntar la fiecare pull request{
"course": "TIC - Web Technologies",
"semester": "2025-2026",
"students": [
{
"id": 1,
"firstName": "Ion",
"lastName": "Popescu",
"folder": "popescu-ion"
},
{
"id": 2,
"firstName": "Maria",
"lastName": "Ionescu",
"folder": "ionescu-maria"
}
]
}2. Fiศierul index.html (root)
index.html (root)<!DOCTYPE html>
<html lang="ro">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Catalog Studenศi - Web Technologies 2025</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<header>
<h1>Catalog Portofolii Studenศi</h1>
<p>Web Technologies - 2025/2026</p>
</header>
<main>
<div id="students-grid">
<!-- Carduri generate dinamic din students.json -->
</div>
</main>
<footer>
<p>© BUES - eBUSINESS</p>
</footer>
<script src="main.js"></script>
</body>
</html>3. Fiศierul main.js (root)
main.js (root)async function loadStudents() {
try {
const response = await fetch('students.json');
const data = await response.json();
renderStudentCards(data.students);
} catch (error) {
console.error('Eroare la รฎncฤrcarea studenศilor:', error);
}
}
function renderStudentCards(students) {
const grid = document.getElementById('students-grid');
students.forEach(student => {
const card = document.createElement('div');
card.className = 'student-card';
const avatar = document.createElement('img');
avatar.src = student.avatar;
avatar.alt = `${student.firstName} ${student.lastName}`;
const name = document.createElement('h3');
name.textContent = `${student.firstName} ${student.lastName}`;
const group = document.createElement('p');
group.textContent = `Grupa: ${student.group}`;
const link = document.createElement('a');
link.href = `students/${student.folder}/index.html`;
link.textContent = 'Vezi portofoliu โ';
link.className = 'portfolio-link';
card.appendChild(avatar);
card.appendChild(name);
card.appendChild(group);
card.appendChild(link);
grid.appendChild(card);
});
}
document.addEventListener('DOMContentLoaded', loadStudents);Workflow GitHub
Pasul 1: Iniศializare Repo (Student voluntar)
# Voluntarul creeazฤ repo-ul principal
git init web-portfolio-2025
cd web-portfolio-2025
# Structurฤ iniศialฤ
mkdir students
touch index.html main.css main.js students.json README.md
# Commit iniศial
git add .
git commit -m "Initial structure"
# Push pe GitHub
git remote add origin https://github.com/username/web-portfolio-2025.git
git push -u origin mainPasul 2: Fork ศi Clone (fiecare student)
Fork repo-ul principal pe contul propriu GitHub
Clone fork-ul local:
git clone https://github.com/ContulTau/web-portfolio-2025.git
cd web-portfolio-2025Pasul 3: Creare Branch ศi dezvoltare (student)
# Creeazฤ branch propriu
git checkout -b add-popescu-ion
# Creeazฤ folderul personal
mkdir -p students/popescu-ion
cd students/popescu-ion
# Creeazฤ fiศierele (index.html, styles.css, script.js)
# ... dezvoltฤ pagina personalฤ ...
# Adaugฤ modificฤrile
git add students/popescu-ion/
git commit -m "Add personal portfolio for Ion Popescu"
# Push branch
git push origin add-popescu-ionPasul 4: Pull Request (student)
Acceseazฤ fork-ul pe GitHub
Click pe "Compare & pull request"
Titlu:
Add portfolio - Prenume NumeDescriere:
- Adฤugat pagina personalฤ pentru [Prenume Nume]- Folder: students/popescu-ion/- JSON complet cu informaศii personale- Paginฤ generatฤ dinamic cu DOM manipulationSubmit pull request
Pasul 5: Review ศi Merge (Voluntar)
Git CheatSheet
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 1: SETUP INIศIAL (o singurฤ datฤ)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 1. Fork repo-ul pe GitHub (click pe butonul "Fork" รฎn interfaศa web)
# URL repo original: https://github.com/user-voluntar/web-portfolio-2025
# 2. Cloneazฤ fork-ul TฤU pe calculatorul local (autentificare cu PAT)
git clone https://github.com/ContulTau/web-portfolio-2025.git
cd web-portfolio-2025
# 3. Configureazฤ upstream (repo-ul studentului voluntar)
git remote add upstream https://github.com/user-voluntar/web-portfolio-2025.git
# 4. Verificฤ cฤ ai ambele remote-uri
git remote -v
# Output:
# origin https://github.com/ContulTau/web-portfolio-2025.git (fetch)
# origin https://github.com/ContulTau/web-portfolio-2025.git (push)
# upstream https://github.com/user-voluntar/web-portfolio-2025.git (fetch)
# upstream https://github.com/user-voluntar/web-portfolio-2025.git (push)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 2: SINCRONIZARE รNAINTE DE LUCRU
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 5. Asigurฤ-te cฤ ai ultima versiune de pe main
git checkout main
git pull upstream main
git push origin main # Actualizeazฤ ศi fork-ul tฤu pe GitHub
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 3: CREAREA BRANCH-ULUI ศI รNCEPEREA LUCRULUI
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 6. Creeazฤ branch-ul tฤu de lucru (foloseศte numele tฤu!)
git checkout -b add-popescu-ion
# 7. Creeazฤ folderul ศi fiศierele tale
mkdir -p students/popescu-ion
cd students/popescu-ion
# Creeazฤ fiศierele
touch index.html styles.css script.js
# 8. Lucreazฤ la proiect (editeazฤ fiศierele รฎn editor)
# - Adaugฤ JSON-ul รฎn script.js
# - Creeazฤ HTML-ul minimal รฎn index.html
# - Stilizeazฤ รฎn styles.css
# 9. Commit-uri pe parcurs (fฤ mai multe, nu unul singur!)
cd ../.. # รnapoi รฎn root
git add students/popescu-ion/
git commit -m "Add HTML structure and initial JSON data"
# ... continui sฤ lucrezi...
git add students/popescu-ion/
git commit -m "Add CSS styling with flexbox layout"
# ... continui sฤ lucrezi...
git add students/popescu-ion/
git commit -m "Add JavaScript DOM manipulation"
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 4: PUSH BRANCH-UL (prima datฤ sau dupฤ modificฤri)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 10. Push branch-ul pe fork-ul tฤu
git push origin add-popescu-ion
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# โฐ รNTRE TIMP: Alศi studenศi au fฤcut PR-uri care au fost acceptate pe main
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Studentul voluntar a merge-uit PR-urile pentru:
# - ionescu-maria
# - vasilescu-ana
# Main-ul de pe upstream acum are mai multe foldere รฎn students/
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 5: ACTUALIZARE BRANCH CU MODIFICฤRILE DIN MAIN
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 11. Salveazฤ munca curentฤ (dacฤ ai modificฤri nesalvate)
git status # Verificฤ ce modificฤri ai
# Dacฤ ai modificฤri uncommitted:
git add .
git commit -m "Work in progress - before sync"
# 12. Treci pe main ศi actualizeazฤ-l cu upstream
git checkout main
git pull upstream main # Descarcฤ modificฤrile de la repo-ul principal
git push origin main # (Opศional) Actualizeazฤ ศi fork-ul pe GitHub
# 13. Revino pe branch-ul tฤu ศi รฎmbinฤ modificฤrile din main
git checkout add-popescu-ion
git merge main # Aduce modificฤrile din main รฎn branch-ul tฤu
# Dacฤ merge-ul reuศeศte fฤrฤ conflicte, vei vedea:
# "Merge made by the 'recursive' strategy."
# sau "Already up to date." (dacฤ nu erau modificฤri noi)
# Dacฤ apar conflicte (rar รฎn acest proiect!):
# - Editeazฤ manual fiศierele marcate cu conflict
# - git add fisier-rezolvat
# - git commit
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 6: VERIFICARE ศI TESTARE
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 14. Verificฤ cฤ totul funcศioneazฤ
# Deschide students/popescu-ion/index.html รฎn browser
# Verificฤ consola pentru erori JavaScript
# Testeazฤ cฤ toate elementele se creeazฤ corect
# 15. Dacฤ ai fฤcut modificฤri dupฤ merge, commit-eazฤ-le
git add .
git commit -m "Fix styling after merge with main"
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 7: PUSH FINAL ศI PULL REQUEST
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 16. Push branch-ul actualizat
git push origin add-popescu-ion
# 17. Creeazฤ Pull Request pe GitHub:
# - Mergi pe https://github.com/ContulTau/web-portfolio-2025
# - Vei vedea un banner galben: "add-popescu-ion had recent pushes"
# - Click pe "Compare & pull request"
# - Asigurฤ-te cฤ:
# * Base repository: user-voluntar/web-portfolio-2025
# * Base: main
# * Head repository: ContulTau/web-portfolio-2025
# * Compare: add-popescu-ion
# - Titlu: "Add portfolio - Ion Popescu"
# - Descriere:
# ```
# ## Modificฤri
# - Adฤugat pagina personalฤ pentru Ion Popescu
# - Folder: `students/popescu-ion/`
# - JSON complet cu informaศii personale pe 3 niveluri
# - Paginฤ generatฤ 100% dinamic cu JavaScript
# - Design responsive cu Flexbox
#
# ## Checklist
# - [x] JSON cu minimum 3 niveluri nested
# - [x] Minimum 5 tipuri de elemente HTML create dinamic
# - [x] CSS responsive cu media queries
# - [x] Event listeners funcศionali
# - [x] Cod testat รฎn browser
# ```
# - Click "Create pull request"
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# FAZA 8: DUPฤ MERGE (cรขnd voluntarul acceptฤ PR-ul)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# 18. Dupฤ ce PR-ul e acceptat, actualizeazฤ-ศi repo-ul local
git checkout main
git pull upstream main
git push origin main
# 19. ศterge branch-ul local (nu mai e nevoie de el)
git branch -d add-popescu-ion
# 20. (Opศional) ศterge branch-ul de pe GitHub
git push origin --delete add-popescu-ionLast updated
Was this helpful?