Skip to content
Open
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
117 changes: 117 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
"preview": "vite preview"
},
"dependencies": {
"bootstrap": "^5.3.8",
"i18next": "^25.5.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^16.0.0",
"react-to-print": "^3.0.4"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useContext, useEffect, useState } from 'react'
import './styles/main.css'
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';

import Navbar from './components/Navbar.jsx'
import PuzzleFormContainer from './components/PuzzleFormContainer.jsx'
Expand All @@ -8,6 +10,7 @@ import Footer from './components/Footer.jsx'
import CrosswordContainer from './components/CrosswordContainer.jsx'
import ColorConfiguration from './components/ColorConfiguration.jsx'
import { AppContext } from './AppProvider.jsx'
import SettingsDropdown from './components/SettingsDropdown.jsx'


// Main App component that renders the entire application.
Expand Down
8 changes: 4 additions & 4 deletions src/AppProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export const AppProvider = ({ children }) => {

// {Object} original_colors - Ref object containing original color variables.
const original_colors = useRef({
'--c': '#3C096C',
'--d': '#5A189A',
'--e': '#7B2CBF',
'--f': '#9D4EDD',
'--c': '#4c65877f',
'--d': '#6b826e9e',
'--e': 'rgba(255, 255, 255, 0.728)',
'--f': '#6b826e7d',
});

// {Object} colors - Object containing color variables.
Expand Down
52 changes: 52 additions & 0 deletions src/components/LanguageDropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useContext, useState, useEffect } from 'react';
import { AppContext } from '../AppProvider';
import { updateContent, translation } from '../scripts/language-handler';

// A dropdown menu to change color settings for the crossword app
const LanguageDropdown = () => {
const [open, setOpen] = useState(false);
const { lang, setLang } = useContext(AppContext);

const toggleDropdown = () => setOpen(!open);

//handle the dropdown selection
const handleLanguageChange = (e) => {
setLang(e);
setOpen(false);
};

// It updates the local storage and the content based on the selected language.
useEffect(() => {
localStorage.setItem('language', lang);
updateContent(translation[lang]);
}, [lang])

return (
<div className="position-relative settings-dropdown">
<button className="personalize-btn"
onClick={toggleDropdown}>Language
</button>

{open && (
<div className="dropdown-menu show" style={{ right: '0', left: '0'}}>

<button className="dropdown-item d-flex align-items-center" onClick={() => handleLanguageChange('es')}>
<img src="https://flagcdn.com/es.svg"
alt="Spain flag" width="24" height="16"
style={{ marginRight: '8px' }}/>
Spanish
</button>

<button className="dropdown-item d-flex align-items-center" onClick={ () => handleLanguageChange('en')}>
<img src="https://flagcdn.com/gb.svg"
alt="UK flag" width="24" height="16"
style={{ marginRight: '8px' }}/>
English
</button>
</div>
)}
</div>
);
};

export default LanguageDropdown
39 changes: 16 additions & 23 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
import React, { useContext, useEffect } from 'react'
import { updateContent, translation } from '../scripts/language-handler'
import { AppContext } from '../AppProvider'

import SettingsDropdown from './SettingsDropdown'
import LanguageDropdown from './LanguageDropdown'


// Navbar component that provides language selection functionality and displays the brand logo.
const Navbar = () => {
const { lang, setLang } = useContext(AppContext)

// It updates the local storage and the content based on the selected language.
useEffect(() => {
localStorage.setItem('language', lang);
updateContent(translation[lang]);
}, [lang])

// ADD settings and customization options here ***
return (
<header>
<nav className="navbar bg-body-tertiary" id="mainNav">
<div className="container-fluid">
<a className="navbar-brand">
<img src="/images/icons8-crossword-64.png" />
Crucigrama | Crossword Puzzle
</a>
<div className="langauge-selection">
<button className={"language-btn " + (lang == 'es' ? "active-btn" : '')} onClick={() => setLang('es')}>
Spanish
</button>
<button className={"language-btn " + (lang == 'en' ? "active-btn" : '')} onClick={() => setLang('en')}>
English
</button>
</div>
<div className="container-fluid">
<a className="navbar-brand">
<img src="/images/icons8-crossword-64.png" /> Crucigrama | Crossword Puzzle
</a>
</div>
<div className="container-fluid d-flex justify-content-between align-items-center">

{/* Left: Language Buttons */}
<LanguageDropdown/>

{/* Right: Settings Dropdown */}
<SettingsDropdown />
</div>
</nav>
</header>
Expand Down
31 changes: 16 additions & 15 deletions src/components/PuzzleFormContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,22 @@ const PuzzleFormContainer = ({ restartCrossword }) => {
return (
<>
<form className="container-sm" id="cpuzzle-options">
<input data-i18n="restart_button" type="button" className="btn btn-primary" id="btn-restart" value="♻️ Restart" onClick={() => restartCrossword()} />
<input data-i18n="view_answers_button" type="button" className="btn btn-primary" id="btn-showAnswers" value="🔎 Show Answers" onClick={() => setShowAnswers(true)} />
<input data-i18n="print_button" type="button" className="btn btn-primary" id="btn-showAnswers" value="🖨️ Print" onClick={reactToPrintFn} />
<input data-i18n="restart_button" type="button" className="btn btn-primary text-wrap w-auto" id="btn-restart" value="♻️ Restart" onClick={() => restartCrossword()} />

<input data-i18n="view_answers_button" type="button" className="btn btn-primary text-wrap w-auto" id="btn-showAnswers" value="🔎 Show Answers" onClick={() => setShowAnswers(true)} />

<input data-i18n="print_button" type="button" className="btn btn-primary text-wrap w-auto" id="btn-showAnswers" value="🖨️ Print" onClick={reactToPrintFn} />

{/* Buttons to control the timer */}
{!timerRef && <button data-i18n="start_timer_button" id="start_timer_button" onClick={() => startTimerHandler(timerDuration, timerRef, setTimerRef, setTimeLeft)} className="btn btn-primary text-wrap w-auto" type="button">
⏱️ Start Timer
</button>}
{timerRef && <button data-i18n="restart-timer-button" id="restart-button" onClick={() => restartTimerHandler(timerDuration, timerRef, setTimerRef, setTimeLeft)} className="btn btn-primary text-wrap w-auto">
Restart Timer
</button>}

<div id="timer-container">
<span>Time Left: </span><span id="timer">
<span>Time Remaining: </span><span id="timer">
{formatTime(timeLeft)}
</span>
</div>
Expand All @@ -46,18 +56,9 @@ const PuzzleFormContainer = ({ restartCrossword }) => {
{/* Your crossword will go here */}
</div>

{/* Buttons to control the timer */}
{!timerRef && <button id="start-button" onClick={() => startTimerHandler(timerDuration, timerRef, setTimerRef, setTimeLeft)} className="btn btn-primary" type="button">
Start Timer
</button>}
{timerRef && <button id="restart-button" onClick={() => restartTimerHandler(timerDuration, timerRef, setTimerRef, setTimeLeft)} className="btn btn-primary">
Restart Timer
</button>}


<button data-i18n="configuration_button_text" type="button" className="btn btn-primary" id="btn-config"
data-bs-toggle="modal" data-bs-target="#configurationModal">
🔩 Settings
</button>


</form>
<div style={{ display: 'none' }}>
Expand Down
Loading