diff --git a/include/js/charts.js b/include/js/charts.js
new file mode 100644
index 0000000000000000000000000000000000000000..5db45da7b00efcd69a4370dcb9dda744225f3280
--- /dev/null
+++ b/include/js/charts.js
@@ -0,0 +1,56 @@
+/**
+ * Requête AJAX pour obtenir une information du serveur et l'utiliser pour faire deux graphiques.
+ * Il faut déclarer la requête et lui dire de faire les graphiques dès qu'on reçoit le résultat.
+ */
+const httpRequest = new XMLHttpRequest() // 1. Déclaration de la requête
+httpRequest.onreadystatechange = () => { // 2. Définition de ce qu'il faut faire quand on obtient une réponse
+    if (httpRequest.readyState === XMLHttpRequest.DONE) {
+        if (httpRequest.status === 200) {
+            // On a reçu la réponse du serveur, on peut générer la graphique
+            const response = JSON.parse(httpRequest.responseText)
+            google.charts.load("current", { "packages": ["corechart"], "language": "fr" })
+            google.charts.setOnLoadCallback(function() {
+                drawChart(response)
+            })
+        } else {
+            console.log("Erreur de connexion au serveur !")
+        }
+    }
+}
+httpRequest.open('POST', 'include/php/data.php', true) // 3. Ouverture et configuration de la requête
+httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
+// Requête SQL
+const query = "SELECT acad_mies, sum(capa_fin) AS places FROM parcoursup GROUP BY acad_mies ORDER BY places DESC"
+httpRequest.send(`query=${encodeURIComponent(query)}`) // 4. Envoi de la requête
+
+
+/**
+ * Fonction qui fait deux graphiques avec les données du serveur
+ */
+function drawChart(result) {
+    // Données de la graphique
+    let data = new google.visualization.DataTable()
+    data.addColumn('string', 'Académie')
+    data.addColumn('number', 'Places')
+    // Utiliser les données du serveur
+    let dataArray = []
+    for (const item of result) {
+        dataArray.push([item.acad_mies, Number(item.places)])
+    }
+    data.addRows(dataArray)
+
+    let piechart_options = {
+        title: "Pie Chart : Nombre de places dans chaque académie",
+        height: 600
+    }
+    let piechart = new google.visualization.PieChart(document.getElementById('piechart_div'))
+    piechart.draw(data, piechart_options)
+
+    let barchart_options = {
+        title: "Barchart : Nombre de places dans chaque académie",
+        height: 600,
+        legend: 'none'
+    }
+    let barchart = new google.visualization.BarChart(document.getElementById('barchart_div'))
+    barchart.draw(data, barchart_options)
+}
\ No newline at end of file
diff --git a/include/js/geochart.js b/include/js/geochart.js
new file mode 100644
index 0000000000000000000000000000000000000000..d985945ec5d29e86c3c2f821eb29f5378eed5729
--- /dev/null
+++ b/include/js/geochart.js
@@ -0,0 +1,74 @@
+/**
+ * Fonction pour transformer le nom d'une region
+ * dans un objet JavaScript que Google Charts comprend.
+ */
+function formatter_region(region) {
+    const codes = {
+        "Ile-de-France": 'FR-IDF',
+        "Auvergne-Rhône-Alpes": 'FR-ARA',
+        "Grand Est": 'FR-GES',
+        "Occitanie": 'FR-OCC',
+        "Nouvelle-Aquitaine": 'FR-NAQ',
+        "Hauts-de-France": 'FR-HDF',
+        "Normandie": 'FR-NOR',
+        "Provence Alpes Côte d'Azur": 'FR-PAC',
+        "Bretagne": 'FR-BRE',
+        "Bourgogne-Franche-Comté": 'FR-BFC',
+        "Pays de la Loire": 'FR-PDL',
+        "Centre-Val de Loire": 'FR-CVL',
+        "La Réunion": 'FR-974',
+        "Corse": 'FR-20R',
+        "Guadeloupe": 'FR-971',
+        "Guyane": 'FR-973',
+        "Polynésie française": 'FR-PF',
+        "Martinique": 'FR-972',
+    }
+    return {v: codes[region], f: region}
+}
+
+
+const httpRequest = new XMLHttpRequest()
+httpRequest.onreadystatechange = () => {
+    if (httpRequest.readyState === XMLHttpRequest.DONE) {
+        if (httpRequest.status === 200) {
+            const response = JSON.parse(httpRequest.responseText)
+            google.charts.load("current", { "packages": ["geochart"], "language": "fr" })
+            google.charts.setOnLoadCallback(function() {
+                drawChart(response)
+            })
+        } else {
+            console.log("Erreur de connexion au serveur !")
+        }
+    }
+}
+httpRequest.open('POST', 'include/php/data.php', true)
+httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
+const query = 'SELECT region_etab_aff, count(*) AS count FROM parcoursup WHERE fili = "BUT" GROUP BY region_etab_aff ORDER BY count DESC'
+httpRequest.send(`query=${encodeURIComponent(query)}`) // 4. Envoi de la requête
+
+
+/**
+ * Fonction qui fait un geochart avec les régions de la France
+ */
+function drawChart(result) {
+    let data = new google.visualization.DataTable()
+    data.addColumn("string", "Région")
+    data.addColumn("number", "Nombre des BUT")
+    let dataArray = []
+    for (const item of result) {
+        dataArray.push([formatter_region(item.region_etab_aff), item.count])
+    }
+    data.addRows(dataArray)
+
+    let options = {
+        width: 600,
+        height: 500,
+        displayMode: 'regions',
+        region: 'FR',
+        resolution: 'provinces',
+        geochartVersion: 11,
+    }
+
+    let chart = new google.visualization.GeoChart(document.getElementById("geochart_div"))
+    chart.draw(data, options)
+}
\ No newline at end of file
diff --git a/include/php/data.php b/include/php/data.php
new file mode 100644
index 0000000000000000000000000000000000000000..43bd6c653fc817d72309755048680f80b1cb1a85
--- /dev/null
+++ b/include/php/data.php
@@ -0,0 +1,13 @@
+<?php
+// Cette page reçoit une requête SQL par la méthode POST
+// On se connecte à la base de données pour faire cette requête et affiche le résultat
+// en format JSON.
+// Cette page sert à faire une requête AJAX avec JavaScript.
+require_once 'functions.php';
+$query = $_POST['query'];
+$dbh = db_connection();
+$sth = $dbh->prepare($query);
+$sth->execute();
+$results = $sth->fetchAll(PDO::FETCH_OBJ);
+echo json_encode($results);
+?>
\ No newline at end of file
diff --git a/include/php/functions.php b/include/php/functions.php
new file mode 100644
index 0000000000000000000000000000000000000000..5db2e05fb45954e7ca0cbc4c584d28a2493b27ea
--- /dev/null
+++ b/include/php/functions.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * Coordonnées de connexion à la base de données en local
+ */
+const db_local = [
+    'dbname' => 'sae303', 
+    'user' => 'root',
+    'pwd' => ''     // 'root' pour MAMP
+];
+
+/**
+ * Coordonnées de connexion à la base de données sur un serveur
+ */
+const db_serveur = [
+    'dbname' => 'a21000000',    // remplacer par votre identifiant
+    'user' => 'a21000000',      // remplacer par votre identifiant
+    'pwd' => 'secret'
+];
+
+/**
+ * Connexion à la base de données
+ * 
+ * Mettre la variable $local à true si le site web est déployé en local (avec XAMPP),
+ * ou false s'il est déployé sur un serveur web.
+ */
+function db_connection() {
+    $local = true;
+    if ($local) {
+        $dbh = new PDO(
+            'mysql:host=localhost;dbname=' . db_local['dbname'] . ';charset=utf8', 
+            db_local['user'], 
+            db_local['pwd']
+        );
+    } else {
+        $dbh = new PDO(
+            'mysql:host=localhost;dbname=' . db_serveur['dbname'] . ';charset=utf8', 
+            db_serveur['user'], 
+            db_serveur['pwd']
+        );
+    }
+    return $dbh;
+}
+?>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c6485cc7a37cfe5dbef273f3ad47b0500408bda
--- /dev/null
+++ b/index.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Différents exemples de requêtes SQL
+ */
+include 'include/php/functions.php';
+?>
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+    <meta charset="utf-8">
+    <title>SAÉ 303</title>
+</head>
+<body>
+	<h1>SAÉ 303</h1>
+	<p>
+		Concevoir des visualisations de données pour le web et un support animé.
+	</p>
+	<p>
+		Voici quelques exemples d'utilisation de la base de données.
+	</p>
+	<p>
+		Aussi, vous trouverez
+	</p>
+	<ul>
+		<li><a href="test-charts.html">un exemple</a> avec deux graphiques utilisant Google Charts</li>
+		<li><a href="regions.html">un exemple</a> avec une graphique avec les régions de l'Hexagone</li>
+		<li><a href="search.php">un exemple</a> avec une barre de recherche</li>
+	</ul>
+	
+	<section>
+		<h2>Les BUT avec le plus grand nombre de candidats</h2>
+		<ol>
+<?php
+$dbh = db_connection();
+$sth = $dbh->prepare('SELECT lib_comp_voe_ins, voe_tot FROM parcoursup
+    WHERE fili = "BUT"
+    ORDER BY voe_tot DESC LIMIT 5');
+$sth->execute();
+$result = $sth->fetchAll();
+foreach ($result as $row) {
+	echo '<li>' . $row['lib_comp_voe_ins'] . ' (<em>' . $row['voe_tot'] . ' candidats</em>)</li>';
+}
+?>
+		</ol>
+	</section>
+
+	<section>
+		<h2>Les villes avec le plus de BTS</h2>
+		<ol>
+<?php
+$sth = $dbh->prepare('SELECT ville_etab, count(*) AS count FROM parcoursup
+	WHERE fili = "BTS"
+	GROUP BY ville_etab
+	ORDER BY count DESC LIMIT 5');
+$sth->execute();
+$result = $sth->fetchAll();
+foreach ($result as $row) {
+	echo '<li>' . $row['ville_etab'] . ' (<em>' . $row['count'] . ' BTS</em>)</li>';
+}
+?>
+		</ol>
+	</section>
+
+	<section>
+		<h2>Les BUT Informatique avec le plus grand nombre de candidates admises</h2>
+		<ol>
+<?php
+$sth = $dbh->prepare('SELECT lib_comp_voe_ins, acc_tot_f, acc_tot FROM parcoursup
+	WHERE lib_for_voe_ins LIKE "BUT - Informatique%"
+    ORDER BY acc_tot_f DESC LIMIT 5');
+$sth->execute();
+$result = $sth->fetchAll();
+foreach ($result as $row) {
+	echo '<li>' . $row['lib_comp_voe_ins'] . ' (<em>' . $row['acc_tot_f'] . ' étudiantes sur ' . $row['acc_tot'] . '</em>)</li>';
+}
+?>
+		</ol>
+	</section>
+</body>
+</html>
\ No newline at end of file
diff --git a/search.php b/search.php
new file mode 100644
index 0000000000000000000000000000000000000000..50b582a0e491710acf92b3251a96b4b4ebb57aa9
--- /dev/null
+++ b/search.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Barre de recherche de formations avec affichage d'informations
+ * 
+ * L'utilisateur choisit une formation dans le formulaire.
+ * Le formulaire envoie cette information vers la même page, et on
+ * affiche le nombre de places et de candidats.
+ */
+include 'include/php/functions.php';
+?>
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+    <meta charset="utf-8">
+    <title>SAÉ 303</title>
+</head>
+<body>
+	<h1>SAÉ 303</h1>
+
+    <form method="get" action="search.php">
+        <label>
+            Choisis une formation&nbsp;:
+            <input list="formations" name="formation" style="width: 400px">
+        </label>
+        <datalist id="formations">
+<?php
+// On remplit l'élément datalist (les suggestions pour le formulaire) avec les noms des formations
+$dbh = db_connection();
+$sth = $dbh->prepare('SELECT lib_comp_voe_ins FROM parcoursup
+    ORDER BY lib_comp_voe_ins ASC');
+$sth->execute();
+$result = $sth->fetchAll();
+foreach ($result as $row) {
+	echo '<option value="' . $row['lib_comp_voe_ins'] . '">';
+}
+?>
+        </datalist>
+        <input type="submit" value="Confirmer">
+    </form>
+
+<?php
+// Si $_GET['formation'] est défini, ça veut dire qu'on est arrivé dans cette page
+// après avoir sélectionné une formation. Dans ce cas, on affiche les informations
+// de cette formation
+if (isset($_GET['formation'])) {
+    $sth = $dbh->prepare('SELECT capa_fin, voe_tot FROM parcoursup
+    WHERE lib_comp_voe_ins = :formation');
+    $donnees = [
+        "formation" => $_GET['formation']
+    ];
+    $sth->execute($donnees);
+    $result = $sth->fetchAll();
+    if (count($result) == 1) {
+        // Si on obtient un résultat, on affiche les informations
+        echo "<h2>" . $_GET['formation'] . "</h2>";
+        echo "<p>" . $result[0]['voe_tot'] . " candidats pour " . $result[0]['capa_fin'] . " places</p>";
+    }
+} else {
+    echo "<p>Veuillez choisir une formation</p>";
+}
+?>
+</body>
+</html>
\ No newline at end of file
diff --git a/test-charts.html b/test-charts.html
new file mode 100644
index 0000000000000000000000000000000000000000..1d940ff45caea7871b2876292453b04abd1dd7f4
--- /dev/null
+++ b/test-charts.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
+    <title>SAÉ 303</title>
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <div class="col-12 col-lg-6">
+                <div id="piechart_div"></div>
+            </div>
+            <div class="col-12 col-lg-6">
+                <div id="barchart_div"></div>
+            </div>
+        </div>
+    </div>
+
+    <script src="https://www.gstatic.com/charts/loader.js"></script>
+    <script src="include/js/charts.js" defer></script>
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
+</body>
+</html>
\ No newline at end of file