diff --git a/.cspell.json b/.cspell.json
index 2c47b1f..dd95800 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -23,6 +23,7 @@
"eslint",
"flashword",
"husky",
+ "lightpink",
"keyup",
"linkcheck",
"lintstaged",
diff --git a/web-projects/first-website/images/fd2-logo-orange.png b/web-projects/first-website/images/fd2-logo-orange.png
new file mode 100644
index 0000000..12cc257
Binary files /dev/null and b/web-projects/first-website/images/fd2-logo-orange.png differ
diff --git a/web-projects/first-website/images/fd2-logo.png b/web-projects/first-website/images/fd2-logo.png
new file mode 100644
index 0000000..a9ff671
Binary files /dev/null and b/web-projects/first-website/images/fd2-logo.png differ
diff --git a/web-projects/first-website/index.html b/web-projects/first-website/index.html
new file mode 100644
index 0000000..4fe7a96
--- /dev/null
+++ b/web-projects/first-website/index.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+ The FarmData2 Project
+
+
+ The FarmData2 Project
+
+
+
+
+ FarmData2 aims to
+ extend farmOS by adding data input forms, reporting, and analytics that
+ support the day-to-day operation of diversified vegetable farms, while
+ also facilitating the keeping of records necessary for organic
+ certification and for the study of sustainable farming practices.
+
+
+
+ FarmData2 contains features for recording the following activities that
+ are likely to occur on a small diversified vegetable farm.
+
+
+ Tray seeding
+ Direct seeding
+ Cover crop seeding
+ Transplanting
+ Soil disturbance
+
+
+ Change user
+
+
diff --git a/web-projects/first-website/scripts/main.js b/web-projects/first-website/scripts/main.js
new file mode 100644
index 0000000..dcf5051
--- /dev/null
+++ b/web-projects/first-website/scripts/main.js
@@ -0,0 +1,34 @@
+const myImage = document.querySelector('img')
+
+myImage.addEventListener('click', () => {
+ const mySrc = myImage.getAttribute('src')
+ if (mySrc === 'images/fd2-logo.png') {
+ myImage.setAttribute('src', 'images/fd2-logo-orange.png')
+ } else {
+ myImage.setAttribute('src', 'images/fd2-logo.png')
+ }
+})
+
+let myButton = document.querySelector('button')
+let myHeading = document.querySelector('h1')
+
+function setUserName() {
+ const myName = prompt('Please enter your name.')
+ if (!myName) {
+ setUserName()
+ } else {
+ localStorage.setItem('name', myName)
+ myHeading.textContent = `Mozilla is cool, ${myName}`
+ }
+}
+
+if (!localStorage.getItem('name')) {
+ setUserName()
+} else {
+ const storedName = localStorage.getItem('name')
+ myHeading.textContent = `FarmData2 is cool, ${storedName}`
+}
+
+myButton.addEventListener('click', () => {
+ setUserName()
+})
diff --git a/web-projects/first-website/styles/style.css b/web-projects/first-website/styles/style.css
new file mode 100644
index 0000000..9872f0f
--- /dev/null
+++ b/web-projects/first-website/styles/style.css
@@ -0,0 +1,37 @@
+html {
+ /* px means "pixels". The base font size is now 10 pixels high */
+ font-size: 10px;
+ /* Replace PLACEHOLDER with the font-family property value you got from Google Fonts */
+ font-family: 'Roboto', sans-serif;
+ background-color: #b8fdb1;
+}
+
+h1 {
+ font-size: 60px;
+ text-align: center;
+ margin: 0;
+ padding: 20px 0;
+ color: #12601b;
+ text-shadow: 3px 3px 1px #b8fdb1;
+}
+
+p,
+li {
+ font-size: 16px;
+ line-height: 2;
+ letter-spacing: 1px;
+}
+
+body {
+ width: 600px;
+ margin: 0 auto;
+ background-color: #ff9500;
+ padding: 0 20px 20px 20px;
+ border: 5px solid black;
+}
+
+img {
+ display: block;
+ margin: 0 auto;
+ max-width: 100%;
+}
diff --git a/web-projects/flashword/app.js b/web-projects/flashword/app.js
new file mode 100644
index 0000000..6c655c8
--- /dev/null
+++ b/web-projects/flashword/app.js
@@ -0,0 +1,77 @@
+const Flashword = {
+ data() {
+ return {
+ wordA: 'hola',
+ wordB: 'hello',
+ answer: '',
+ correct: null,
+ showFeedback: false,
+ hasError: false,
+ correctAnswers: 0,
+ totalAnswers: 0,
+
+ // Array of objects example
+ words: [
+ { wordA: 'hola', wordB: 'hello' },
+ { wordA: 'adios', wordB: 'goodbye' },
+ { wordA: 'uno', wordB: 'one' },
+ { wordA: 'dos', wordB: 'two' },
+ ],
+ };
+ },
+ watch: {
+ answer(newAnswer) {
+ if (newAnswer !== '') {
+ this.hasError = false;
+ }
+ },
+ },
+ computed: {
+ inputCSSClass() {
+ return this.hasError ? 'error' : 'no-error';
+ },
+ correctPercentage() {
+ if (this.totalAnswers === 0) {
+ return 0;
+ }
+
+ return (this.correctAnswers / this.totalAnswers) * 100;
+ },
+ earnedBadge() {
+ return this.correctPercentage >= 80;
+ },
+ },
+ methods: {
+ checkAnswer() {
+ if (this.answer == '') {
+ this.hasError = true;
+ return;
+ }
+
+ this.hasError = false;
+ this.correct = this.wordB == this.answer;
+
+ this.totalAnswers++;
+
+ if (this.correct) {
+ this.correctAnswers++;
+ }
+
+ this.showFeedback = true;
+ },
+ reset() {
+ this.answer = '';
+ this.showFeedback = false;
+ this.correct = null;
+ this.hasError = false;
+
+ // Reset to a new random word
+ const randomIndex = Math.floor(Math.random() * this.words.length);
+ this.wordA = this.words[randomIndex].wordA;
+ this.wordB = this.words[randomIndex].wordB;
+ },
+ },
+};
+
+// eslint-disable-next-line no-unused-vars, no-undef
+const app = Vue.createApp(Flashword).mount('#app');
diff --git a/web-projects/flashword/images/badge.png b/web-projects/flashword/images/badge.png
new file mode 100644
index 0000000..2580507
Binary files /dev/null and b/web-projects/flashword/images/badge.png differ
diff --git a/web-projects/flashword/index.html b/web-projects/flashword/index.html
new file mode 100644
index 0000000..8918147
--- /dev/null
+++ b/web-projects/flashword/index.html
@@ -0,0 +1,83 @@
+
+
+
+ FlashWord
+
+
+
+
+
+
+
+
+
+ FlashWord
+
+
+ This is a simple flashcard app that will show you a word in Spanish and
+ ask you to enter the translation in English.
+
+
+
+ What is the English translation of the word
{{ wordA }} ?
+
+
Translation:
+
+
+
You answered: {{ answer }}
+
+
Check answer
+
+
You got it!
+
+ Sorry, please try again.
+
+
+
Reset
+
+
+
Badge earned!
+
+
+
+
+