Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e7f7bdf
feat: create first Typescript workshop
a2937 Jul 31, 2025
48cb7ce
add typescript base
a2937 Jul 31, 2025
78ca335
add watcher
a2937 Aug 3, 2025
1d745be
feat: implement initial dashboard layout and responsive styles
tekluabayneh Aug 4, 2025
17cf82e
Update index.html and style.css
tekluabayneh Aug 5, 2025
3b746e8
fix: update package version and correct CSS syntax issues
tekluabayneh Aug 5, 2025
1d70d43
chore: updated HTML structure and CSS styles for better layout and ad…
tekluabayneh Aug 5, 2025
2f3c29d
feat: implement card reveal buttons and new reading reset logic
tekluabayneh Aug 5, 2025
5467ff1
fix: extra doublequote removed
shootermv Aug 5, 2025
f865da3
complete fetching from the API
a2937 Aug 6, 2025
936afa8
chore: get html formatted with prettier
shootermv Aug 6, 2025
e31d8e4
feat: add click handler to card elements to update displayed card data
tekluabayneh Aug 6, 2025
1fc5e31
chore: add prettier package & configuration
shootermv Aug 7, 2025
6f4b2c4
feat: replace card title with image and refactor some CSS
tekluabayneh Aug 7, 2025
0fa22ee
chore: formatting ts and css files
shootermv Aug 7, 2025
dbc9045
refactor: Game class added
shootermv Aug 7, 2025
9d3089f
feat: refactor typescript to use type guuard
tekluabayneh Aug 7, 2025
2790715
Merge branch 'feat/fortune-telling-app' of https://github.com/nhcarri…
tekluabayneh Aug 7, 2025
b1f24b5
chore: format the code
shootermv Aug 7, 2025
58020f1
chore: rename cardTamplate -> renderCard
shootermv Aug 7, 2025
df3c219
refactor: attach logic to clss methods
shootermv Aug 7, 2025
6085d13
feat: remove unused type
tekluabayneh Aug 7, 2025
cf61fd5
refactor: add improvements to typescript
shootermv Aug 7, 2025
45019ad
feat: added default image url for missing
tekluabayneh Aug 13, 2025
2bd8f95
fix: add preloader & add deafult image instead of missing image
shootermv Aug 17, 2025
469d212
refactor: move elements members of Game class
shootermv Aug 17, 2025
025a996
refactor: move fortueDescription element to be member if Game class
shootermv Aug 17, 2025
74e312a
refactor: remove extra vars
shootermv Aug 17, 2025
d48183d
refactor: rest of element vars moved to be Game members
shootermv Aug 17, 2025
8b337f7
docs: add a comments to the code
shootermv Aug 18, 2025
dbbd219
refactor: rename IMG_URL to CDN_URL
shootermv Aug 19, 2025
af8d733
chore: remove extra typechecking
shootermv Aug 19, 2025
54a01c7
refactor: replace img by figure tag
shootermv Aug 20, 2025
e76300e
fix: update non-null assertions and use generics with type guards
tekluabayneh Aug 21, 2025
f68cb1a
Merge branch 'feat/fortune-telling-app' of https://github.com/nhcarri…
shootermv Aug 24, 2025
367d4c1
style: improve the design
shootermv Sep 1, 2025
ca740a7
style: change style of fortune description
shootermv Sep 1, 2025
f0ff170
Merge pull request #24 from nhcarrigan/improve-the-design
a2937 Sep 1, 2025
9a5ff77
fix: remove unused css
tekluabayneh Sep 2, 2025
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
4 changes: 4 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.parcel-cache/
dist/
node_modules/
6 changes: 6 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/.parcelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
}
}
17 changes: 17 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "parcel-vanilla-starter",
"private": true,
"version": "0.0.0",
"source": "src/index.html",
"scripts": {
"start": "parcel",
"build": "parcel build"
},
"dependencies": {
"@parcel/config-default": "2.15.4",
"@parcel/transformer-typescript-tsc": "2.15.4"
},
"devDependencies": {
"parcel": "2.15.4"
}
}
1,827 changes: 1,827 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/pnpm-lock.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
onlyBuiltDependencies:
- '@parcel/watcher'
- '@swc/core'
- lmdb
- msgpackr-extract
70 changes: 70 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fortune Telling App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main id="main_container">

<!-- title start -->
<div>
<h1>MyStic Tarot</h1>
<h6>Discover the wisdom of the cards and unveil the mysteris of your path</h6>
</div>
<!-- title start end -->


<!-- buttons start -->
<div id="btn_title_container">


<!-- we will replace this title when card is being fetch -->
<div class="title_wrapper">
<h2>Choose Your Reading</h2>
<h2 class="hidden">Shuffling the cosmic deck...</h2>
</div>

<div class="btn_wrapper">
<button class="btn btn_singleCard" id="btn-single-card">Single Card Reading </button>
<button class="btn btn_threeCard" id="btn-multiple-cards">Three Card Spread</button>
</div>
</div>
<!-- buttons end -->

<section class="fortune_container hidden">

<div class="single_card">
</div>


<!-- multiple fortune card start-->
<h2 class="hidden text">Past • Present • Future</h2>
<div class="multiple_card hidden"> </div>
<!-- multiple fortune card end -->

<!-- fortune description container start -->
<div class="fortune_description">

<h2> The Devil </h2>
<h5> Personal transformation, fear of change, averting disaster. </h5>

<div class="description_wrapper">
<span>Description:</span>
<p> The High Priestess sits between two pillars, guarding the threshold to the unconscious mind. She represents intuitive wisdom and the mysteries that lie beneath the surface of consciousness. </p> </div>


</div>
<!-- fortune description container end-->

<button class="btn_reveal">New Reading</button>

</section>


</main>
<script src="script.ts"/>
</body>
</html>
107 changes: 107 additions & 0 deletions fullstack-cert/typescript-projects/fortune-app/src/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

interface Card
{
name: string;
value: number;
}

interface Deck
{
cards: Card[];
}

const singleCardBtn = document.getElementById("btn-single-card") as HTMLButtonElement;
const multipleCardsBtn = document.getElementById("btn-multiple-cards") as HTMLButtonElement;
const fortuneContainer = document.getElementsByClassName("fortune_container")[0] as HTMLElement;
const multiple_card = document.getElementsByClassName("multiple_card")[0] as HTMLElement;
const singleCard = document.getElementsByClassName("single_card")[0] as HTMLElement;
const newReadingBtn = document.getElementsByClassName("btn_reveal")[0] as HTMLButtonElement;
const apiURL = "https://cdn.freecodecamp.org/curriculum/typescript/tarot-app";

const dataUrl = apiURL + "/card_data.json";

const text = document.querySelector(".text") as HTMLElement;

let cardData: Deck = {cards: []};

document.addEventListener("DOMContentLoaded", async function () {
// This is the logic for where the card is fetched and parsed
const response = await fetch(dataUrl);
cardData = await response.json();
});

const HideElement = (...element:HTMLElement[]) => {
element.forEach(el => {
el.classList.add("hidden")
})
}

const cardTemplate = function (drawingType: string, cardName: string, value: number, isReversed : boolean) {
return `
<div>
<h2>${drawingType}</h2>
<div class="card_container ">
<div class="card_front ${isReversed ? 'reversed-card' : ""}">
<span>${value}</span>
<span>${cardName}</span>
${isReversed ? "<span>Reversed</span>" : ""}
</div>
</div>
</div>
`;
};

const ShowElement = (...element:HTMLElement[]) =>{
element.forEach(el => {
el.classList.remove("hidden")
})
}
// reveal card for single card
singleCardBtn.addEventListener("click", (e:Event) =>{
HideElement(singleCardBtn, multipleCardsBtn, multiple_card, text);
const isReversed = Math.round(Math.random()) + 1 === 1;
let chosenCardIndex = Math.round(Math.random() * cardData.cards.length - 1);
console.log(chosenCardIndex);
let chosenCard = cardData.cards[chosenCardIndex];

ShowElement(singleCard, fortuneContainer);
singleCard.innerHTML = cardTemplate(
"Your card",
chosenCard.name,
chosenCard.value,
isReversed
);
multiple_card.innerHTML = "";
})


// reveal card for multiple
multipleCardsBtn.addEventListener("click", (e: Event) => {
ShowElement(multiple_card, fortuneContainer, text)
HideElement(singleCard, singleCardBtn, multipleCardsBtn)

/// i am just adding to test how to multiple card look like we will change this later
const cards = ["past", "future", "present"];

const MultipleCards = `
${cards.map(itm => {
// 1 for front, 2 for reversed
const isReversed = (Math.round(Math.random()) + 1) === 1;
let chosenCardIndex = Math.round(Math.random() * cardData.cards.length - 1);
let chosenCard = cardData.cards[chosenCardIndex];
return cardTemplate(itm, chosenCard.name, chosenCard.value, isReversed);
}).join('')}`

multiple_card.innerHTML = MultipleCards

});


// new Reading button to just clear the reveal card
newReadingBtn.addEventListener("click", (e:Event) =>{
ShowElement( singleCardBtn ,multipleCardsBtn)
HideElement(singleCard, multiple_card, fortuneContainer)

})


Loading