Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
20 changes: 6 additions & 14 deletions fullstack-cert/typescript-projects/fortune-app/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,16 @@ <h2 class="hidden">Shuffling the cosmic deck...</h2>

<section class="fortune_container hidden">

<div class="single_card hidden">
<h2>Your Card</h2>
<div class="card_container">
<div class="card_front">
<span>16</span>
<span>The Tower</span>
<span>Reversed</span>
</div>
</div>
<div class="single_card">
</div>


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

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

<h2> The Devil </h2>
Expand All @@ -65,9 +57,9 @@ <h5> Personal transformation, fear of change, averting disaster. </h5>


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

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

</section>

Expand Down
112 changes: 74 additions & 38 deletions fullstack-cert/typescript-projects/fortune-app/src/script.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,106 @@
/**
* TODO: Fetch data from external source
* Card images should be hosted on CDN
*/

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 fortune_container = 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_revil")[0] as HTMLButtonElement
const text = document.querySelector(".text") as HTMLElement
console.log(singleCardBtn, multipleCardsBtn, singleCard)
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")
})
}
// reail card for single card
// reveal card for single card
singleCardBtn.addEventListener("click", (e:Event) =>{
HideElement(singleCardBtn ,multipleCardsBtn,multiple_card,text)
ShowElement(singleCard, fortune_container)
multiple_card.innerHTML = "";
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 = "";
})


// revail card for muiltiple
multipleCardsBtn.addEventListener("click", (e:Event) =>{
ShowElement( multiple_card, fortune_container,text)
HideElement(singleCard, singleCardBtn ,multipleCardsBtn)
// 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"];

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

const MultipleCards = `
${cards.map(itm => `
<div>
<h2>${itm}</h2>
<div class="card_container">
<div class="card_front">
<span>16</span>
<span>The Tower</span>
<span>Reversed</span>
</div>
</div>
</div>
`).join('')}`
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
multiple_card.innerHTML = MultipleCards

})
});


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

})

Expand Down
17 changes: 11 additions & 6 deletions fullstack-cert/typescript-projects/fortune-app/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ h2{
font-weight:700;
font-size:1.75rem;
margin:2rem 0;

}

h6{
color:var(--accent-secondary);
font-size:1.8rem;
Expand Down Expand Up @@ -143,7 +143,7 @@ h5{
background-image:linear-gradient(to right, var(--gradient-cosmic-to))
}

.btn_revil{
.btn_reveal{
color: var(--text-dark);
font-weight: 500;
font-size: .875rem;
Expand All @@ -160,7 +160,7 @@ h5{
margin:1rem;
}

.btn_revil:hover{
.btn_reveal:hover{
background-color:var(--gradient-gold-from);
}

Expand Down Expand Up @@ -192,10 +192,15 @@ h5{
color:var(--accent-light-gold);
cursor:pointer;
z-index:1;
transform:rotate(180deg);
transition: transform 0.4s ease;
}
.card_front:hover{

.reversed-card
{
transform:rotate(180deg);
transition: transform 0.4s ease;
}

.reversed-card:hover{
transform:rotate(0deg) translateY(-4%);
}

Expand Down