diff options
| author | Yuval Adam <_@yuv.al> | 2025-03-05 12:21:25 +0100 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2025-03-05 12:21:25 +0100 |
| commit | 5bf781f3ac381744fbec035f938d69a201f75fa4 (patch) | |
| tree | 2ec82a90ce2cd1c279d77bdd6ca83b256ac4856a /morsehero/src/pages/chart | |
| parent | c6612a8b6dde5a5a9776d424ed33f5ca685699c6 (diff) | |
Replace all impl with vite
Diffstat (limited to 'morsehero/src/pages/chart')
| -rw-r--r-- | morsehero/src/pages/chart/ChartPage.tsx | 178 | ||||
| -rw-r--r-- | morsehero/src/pages/chart/styles.css | 132 |
2 files changed, 0 insertions, 310 deletions
diff --git a/morsehero/src/pages/chart/ChartPage.tsx b/morsehero/src/pages/chart/ChartPage.tsx deleted file mode 100644 index 88c1ec2..0000000 --- a/morsehero/src/pages/chart/ChartPage.tsx +++ /dev/null @@ -1,178 +0,0 @@ -import { useEffect, useRef } from 'react'; -import { Link } from 'react-router'; -import * as cw from 'cw'; -import '../../base.css'; -import './styles.css'; - -declare global { - interface Window { - cw: any; - } -} - -const ChartPage = () => { - const actxRef = useRef<any>(null); - - // Initialize audio context - const initAudio = () => { - if (actxRef.current) return; // Already initialized - - try { - actxRef.current = cw.initAudioContext({ tone: 600 }); - } catch (error) { - console.error('Failed to initialize audio context:', error); - } - }; - - // Play Morse code for a character - const playCharacter = (character: string) => { - // Initialize audio on first user interaction - if (!actxRef.current) { - initAudio(); - } - - if (actxRef.current) { - // Remove 'playing' class from all items - document.querySelectorAll('.morse-item').forEach(item => { - item.classList.remove('playing'); - }); - - // Add 'playing' class to the clicked item - const clickedItem = document.querySelector(`.morse-item[data-char="${character}"]`); - if (clickedItem) { - clickedItem.classList.add('playing'); - } - - cw.play(character, { - wpm: 20, - actx: actxRef.current - }); - - // Remove the 'playing' class after the audio finishes - setTimeout(() => { - if (clickedItem) { - clickedItem.classList.remove('playing'); - } - }, 2000); - } - }; - - // Add click event listeners to all morse items - useEffect(() => { - const handleMorseItemClick = (e: Event) => { - const target = e.currentTarget as HTMLElement; - const character = target.getAttribute('data-char'); - if (character) { - playCharacter(character); - } - }; - - const morseItems = document.querySelectorAll('.morse-item'); - morseItems.forEach(item => { - item.addEventListener('click', handleMorseItemClick); - }); - - return () => { - morseItems.forEach(item => { - item.removeEventListener('click', handleMorseItemClick); - }); - }; - }, []); - - return ( - <div className="container"> - <h1><Link to="/" className="title-link">Morse Hero</Link></h1> - <h2>Morse Code Chart</h2> - - <div className="chart-section"> - <h2>Letters</h2> - <div className="morse-grid"> - {[...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].map(char => ( - <div key={char} className="morse-item" data-char={char}> - <div className="character">{char}</div> - <div className="morse">{getMorseCode(char)}</div> - </div> - ))} - </div> - </div> - - <div className="chart-section"> - <h2>Numbers</h2> - <div className="morse-grid"> - {[...'0123456789'].map(char => ( - <div key={char} className="morse-item" data-char={char}> - <div className="character">{char}</div> - <div className="morse">{getMorseCode(char)}</div> - </div> - ))} - </div> - </div> - - <div className="chart-section"> - <h2>Special Characters</h2> - <div className="morse-grid"> - {[...'.=,?/'].map(char => ( - <div key={char} className="morse-item" data-char={char}> - <div className="character">{char}</div> - <div className="morse">{getMorseCode(char)}</div> - </div> - ))} - </div> - </div> - - <div className="chart-section"> - <h2>Prosigns</h2> - <div className="morse-grid"> - <div className="morse-item"> - <div className="character">AR</div> - <div className="morse">·−·−·</div> - <div className="description">End of message</div> - </div> - <div className="morse-item"> - <div className="character">SK</div> - <div className="morse">···−·−</div> - <div className="description">End of contact</div> - </div> - <div className="morse-item"> - <div className="character">BT</div> - <div className="morse">−···−</div> - <div className="description">Break</div> - </div> - <div className="morse-item"> - <div className="character">KN</div> - <div className="morse">−·−−·</div> - <div className="description">Go only</div> - </div> - </div> - </div> - - <div className="back-link"> - <Link to="/">Back to Morse Hero</Link> - </div> - - <footer className="footer"> - <p>Click on any character to hear its Morse code sound.</p> - <p>Created with <a href="https://www.mastercw.com/cw.js/">CW.js</a>. For a complete and professional - Morse Code training solution visit <a href="https://www.mastercw.com">Master CW</a>.</p> - </footer> - </div> - ); -}; - -// Helper function to get morse code representation -const getMorseCode = (char: string) => { - const morseMap: { [key: string]: string } = { - 'A': '·−', 'B': '−···', 'C': '−·−·', 'D': '−··', 'E': '·', - 'F': '··−·', 'G': '−−·', 'H': '····', 'I': '··', 'J': '·−−−', - 'K': '−·−', 'L': '·−··', 'M': '−−', 'N': '−·', 'O': '−−−', - 'P': '·−−·', 'Q': '−−·−', 'R': '·−·', 'S': '···', 'T': '−', - 'U': '··−', 'V': '···−', 'W': '·−−', 'X': '−··−', 'Y': '−·−−', - 'Z': '−−··', '0': '−−−−−', '1': '·−−−−', '2': '··−−−', '3': '···−−', - '4': '····−', '5': '·····', '6': '−····', '7': '−−···', '8': '−−−··', - '9': '−−−−·', '.': '·−·−·−', ',': '−−··−−', '?': '··−−··', '/': '−··−·', '=': '−···−' - }; - - return morseMap[char] || ''; -}; - -export default ChartPage; diff --git a/morsehero/src/pages/chart/styles.css b/morsehero/src/pages/chart/styles.css deleted file mode 100644 index 279d421..0000000 --- a/morsehero/src/pages/chart/styles.css +++ /dev/null @@ -1,132 +0,0 @@ -/* Morse Hero Chart Styles */ - -h1 { - font-size: 48px; -} - -h2 { - font-size: 32px; - margin: 30px 0 15px; - color: var(--primary-color); - text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.2), - 0 0 10px rgba(52, 152, 219, 0.4); - font-family: 'Fredoka', sans-serif; - font-weight: 600; -} - -.chart-section { - background: linear-gradient(145deg, var(--bg-light) 0%, #2d3e50 100%); - border-radius: var(--border-radius-md); - padding: 30px 25px; - margin-bottom: 40px; - box-shadow: var(--shadow-lg); - position: relative; - overflow: hidden; -} - -.chart-section::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 5px; - background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); - z-index: 1; -} - -.morse-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); - gap: 20px; - margin: 0 auto; -} - -.morse-item { - background: linear-gradient(145deg, rgba(52, 152, 219, 0.1) 0%, rgba(52, 152, 219, 0.2) 100%); - border-radius: var(--border-radius-sm); - padding: 20px 15px; - display: flex; - flex-direction: column; - align-items: center; - box-shadow: var(--shadow-sm); - transition: all var(--transition-normal); - cursor: pointer; - border: 1px solid rgba(52, 152, 219, 0.2); -} - -.morse-item:hover { - transform: translateY(-5px); - box-shadow: var(--shadow-md); - background: linear-gradient(145deg, rgba(52, 152, 219, 0.2) 0%, rgba(52, 152, 219, 0.3) 100%); - border-color: rgba(52, 152, 219, 0.3); -} - -.morse-item.playing { - background: linear-gradient(145deg, rgba(243, 156, 18, 0.2) 0%, rgba(243, 156, 18, 0.3) 100%); - box-shadow: 0 0 20px rgba(243, 156, 18, 0.4); - border-color: rgba(243, 156, 18, 0.4); -} - -.character { - font-size: 32px; - font-weight: bold; - margin-bottom: 10px; - text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); -} - -.morse { - font-family: monospace; - font-size: 18px; - letter-spacing: 2px; - color: var(--text-dim); -} - -.back-link { - margin-top: 40px; - font-size: 18px; -} - -.back-link a { - color: var(--primary-color); - text-decoration: none; - transition: all var(--transition-normal); - padding: 10px 20px; - background-color: rgba(255, 255, 255, 0.05); - border-radius: var(--border-radius-sm); - display: inline-block; -} - -.back-link a:hover { - color: var(--secondary-color); - background-color: rgba(255, 255, 255, 0.1); - transform: translateY(-3px); - box-shadow: var(--shadow-sm); -} - -@media (max-width: 768px) { - .morse-grid { - grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); - gap: 15px; - } - - .morse-item { - padding: 15px 10px; - } - - .character { - font-size: 28px; - } - - .morse { - font-size: 16px; - } - - h1 { - font-size: 36px; - } - - h2 { - font-size: 24px; - } -} |
