Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion 4-typing-game/solution/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ document.getElementById('start').addEventListener('click', function () {

// UI updates
// Create an array of span elements so we can set a class
const spanWords = words.map(function(word) { return `<span>${word} </span>`});
const spanWords = words.map(function (word) { return `<span>${word} </span>` });
// Convert into string and set as innerHTML on quote display
quoteElement.innerHTML = spanWords.join('');
// Highlight the first word
Expand Down Expand Up @@ -83,3 +83,12 @@ typedValueElement.addEventListener('input', (e) => {
typedValueElement.className = 'error';
}
});

// Add this at the end of the file
const messages = {
success: "CONGRATULATIONS! You finished in {seconds} seconds.",
error: "Oops! There's a mistake.",
start: "Start typing to begin the game."
};

export default messages;
Comment on lines +88 to +94
Copy link
Preview

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This message constants addition appears unrelated to the main PR purpose of fixing the bank project API. Consider moving this to a separate PR for better change isolation.

Suggested change
const messages = {
success: "CONGRATULATIONS! You finished in {seconds} seconds.",
error: "Oops! There's a mistake.",
start: "Start typing to begin the game."
};
export default messages;

Copilot uses AI. Check for mistakes.

80 changes: 62 additions & 18 deletions 7-bank-project/solution/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

const serverUrl = 'http://localhost:5000/api';
const storageKey = 'savedAccount';
const accountsKey = 'accounts'; // New key for all accounts

// ---------------------------------------------------------------------------
// Router
Expand Down Expand Up @@ -32,7 +33,7 @@ function updateRoute() {
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);

if (typeof route.init === 'function') {
route.init();
}
Expand All @@ -41,32 +42,75 @@ function updateRoute() {
}

// ---------------------------------------------------------------------------
// API interactions
// API interactions (replaced with localStorage logic)
// ---------------------------------------------------------------------------

async function sendRequest(api, method, body) {
try {
const response = await fetch(serverUrl + api, {
method: method || 'GET',
headers: body ? { 'Content-Type': 'application/json' } : undefined,
body
});
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
function getAccounts() {
return JSON.parse(localStorage.getItem(accountsKey) || '[]');
}

function saveAccounts(accounts) {
localStorage.setItem(accountsKey, JSON.stringify(accounts));
}

function findAccount(user) {
const accounts = getAccounts();
return accounts.find(acc => acc.user === user) || null;
}

async function getAccount(user) {
return sendRequest('/accounts/' + encodeURIComponent(user));
// Simulate async
return new Promise(resolve => {
setTimeout(() => {
const acc = findAccount(user);
if (!acc) resolve({ error: 'Account not found' });
else resolve(acc);
}, 100);
});
}

async function createAccount(account) {
return sendRequest('/accounts', 'POST', account);
async function createAccount(accountJson) {
return new Promise(resolve => {
setTimeout(() => {
let data;
try {
data = JSON.parse(accountJson);
} catch (e) {
return resolve({ error: 'Malformed account data' });
}
if (!data.user) return resolve({ error: 'Username required' });
if (findAccount(data.user)) return resolve({ error: 'User already exists' });
// Set up initial account structure
const newAcc = {
user: data.user,
description: data.description || '',
balance: 0,
currency: data.currency || 'USD',
transactions: []
};
const accounts = getAccounts();
accounts.push(newAcc);
saveAccounts(accounts);
resolve(newAcc);
}, 100);
});
}

async function createTransaction(user, transaction) {
return sendRequest('/accounts/' + user + '/transactions', 'POST', transaction);
async function createTransaction(user, transactionJson) {
return new Promise(resolve => {
setTimeout(() => {
const accounts = getAccounts();
const idx = accounts.findIndex(acc => acc.user === user);
if (idx === -1) return resolve({ error: 'Account not found' });
const tx = JSON.parse(transactionJson);
Copy link
Preview

Copilot AI Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON.parse without error handling can throw an exception if transactionJson is invalid JSON. Wrap in try-catch to handle malformed input gracefully.

Suggested change
const tx = JSON.parse(transactionJson);
let tx;
try {
tx = JSON.parse(transactionJson);
} catch (e) {
return resolve({ error: 'Malformed transaction data' });
}

Copilot uses AI. Check for mistakes.

tx.amount = parseFloat(tx.amount);
tx.date = tx.date || new Date().toISOString().slice(0, 10);
accounts[idx].balance += tx.amount;
accounts[idx].transactions.push(tx);
saveAccounts(accounts);
resolve(tx);
}, 100);
});
}

// ---------------------------------------------------------------------------
Expand Down