Compare commits

...

22 Commits
0.3.0 ... main

Author SHA1 Message Date
e3e57abefd fix: semver now has patch number again 2024-02-18 10:34:35 +01:00
ef8a3fe419 Merge branch 'develop' for 0.4 2024-02-18 10:28:49 +01:00
405e634e59 change: version number 0.4 2024-02-18 10:16:46 +01:00
e1be96557a feat: Added orientation warning 2024-02-18 10:15:34 +01:00
3b63a4ce00 feat: Improved navbar for mobile devices 2024-02-18 09:53:52 +01:00
75fad798be fix: Fixed merge conflict in cherry-pick 2024-02-18 09:08:48 +01:00
a79ebaf044 feat: Improved layout on mobile devices 2024-02-18 09:05:15 +01:00
c029ed416d fix: Fixed buzzwords nullable issue 2024-02-18 09:01:35 +01:00
53105dfcfe fix: Fixed buzzwords nullable issue 2024-02-16 19:52:06 +01:00
6bd1de8ad9 Merge branch 'develop' for 0.3.2 2024-02-13 01:40:48 +01:00
60360b44d0 change: Updated version number 2024-02-13 01:37:19 +01:00
c27564efa3 change: Moved layout to layout.tsx 2024-02-13 01:21:23 +01:00
72014130bf feat: Added buzzwords param to BingoController 2024-02-13 01:19:24 +01:00
2e857e0d72 Merge branch 'main' into develop 2024-02-13 01:17:50 +01:00
2a35bf61b2 feat: Added Dockerfile 2024-02-08 15:22:21 +01:00
e62544bd03 Update README.md 2023-11-17 20:24:00 +00:00
5700d1075b Merge branch 'develop' for 0.3.1 2023-11-16 03:02:32 +01:00
f100d1afa9 Resorted themes and added icon for dark themes 2023-11-16 02:59:51 +01:00
6a9b3e2af9 Added themes coffee and dim 2023-11-16 02:46:22 +01:00
2abc635d4f Updated daisyui 3.9.4 -> 4.0.8 2023-11-16 02:45:55 +01:00
487f5f854e Updated version to 0.3.1 2023-11-16 02:42:04 +01:00
9f189a9a44 Patched shuffle function to copy array
The inline implementation of shuffle caused React not to detect
changes, because the reference didn't change. Copying the array
with slice(), thus changing the reference, fixed the issue.
2023-11-16 02:21:52 +01:00
12 changed files with 110 additions and 59 deletions

8
Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM node:21.6
COPY . .
RUN npm i
RUN npm run build
CMD ["npm", "run", "start"]

View File

@ -1,5 +1,7 @@
This is a Buzzword Bingo generator for IT buzzwords, based on [Next.js](https://nextjs.org/), [TailwindCSS](https://tailwindcss.com/) and [DaisyUI](https://daisyui.com/).
Icons: [Iconify](https://icon-sets.iconify.design/ic/)
## Getting Started
To build and run, execute:
@ -11,3 +13,5 @@ $ npm run start
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
The latest stable build can be found at [https://buzz.datalore.sh](https://buzz.datalore.sh)

34
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "buzzword-bingo",
"version": "0.3.0",
"version": "0.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "buzzword-bingo",
"version": "0.3.0",
"version": "0.4.0",
"dependencies": {
"next": "14.0.1",
"react": "^18",
@ -18,7 +18,7 @@
"@types/react-dom": "^18",
"autoprefixer": "^10.4.16",
"clsx": "^2.0.0",
"daisyui": "^3.9.4",
"daisyui": "^4.0.8",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"typescript": "^5"
@ -531,12 +531,6 @@
"node": ">=6"
}
},
"node_modules/colord": {
"version": "2.9.3",
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
"integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
"dev": true
},
"node_modules/commander": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
@ -580,17 +574,25 @@
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
"dev": true
},
"node_modules/culori": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/culori/-/culori-3.2.0.tgz",
"integrity": "sha512-HIEbTSP7vs1mPq/2P9In6QyFE0Tkpevh0k9a+FkjhD+cwsYm9WRSbn4uMdW9O0yXlNYC3ppxL3gWWPOcvEl57w==",
"dev": true,
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/daisyui": {
"version": "3.9.4",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.9.4.tgz",
"integrity": "sha512-fvi2RGH4YV617/6DntOVGcOugOPym9jTGWW2XySb5ZpvdWO4L7bEG77VHirrnbRUEWvIEVXkBpxUz2KFj0rVnA==",
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.0.8.tgz",
"integrity": "sha512-kz+UNSsQx5vEKtrzOKwVvUYVt87Qro94SjGBnQs/D5/UfVaAZwPy2SPJTKRdfNF+zlGUocGKkX1sHdAAGX4J5A==",
"dev": true,
"dependencies": {
"colord": "^2.9",
"css-selector-tokenizer": "^0.8",
"postcss": "^8",
"postcss-js": "^4",
"tailwindcss": "^3.1"
"culori": "^3",
"picocolors": "^1",
"postcss-js": "^4"
},
"engines": {
"node": ">=16.9.0"

View File

@ -1,6 +1,6 @@
{
"name": "buzzword-bingo",
"version": "0.3.0",
"version": "0.4.0",
"private": true,
"scripts": {
"dev": "next dev",
@ -19,7 +19,7 @@
"@types/react-dom": "^18",
"autoprefixer": "^10.4.16",
"clsx": "^2.0.0",
"daisyui": "^3.9.4",
"daisyui": "^4.0.8",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"typescript": "^5"

View File

@ -13,7 +13,7 @@ export default function Bingo({size, items}: Props){
rows[i] = activeItems.slice(i * size, (i + 1) * size);
}
return(
<table className='w-1/2 table table-xs sm:table-sm md:table-md bg-primary text-primary-content m-auto'>
<table className='table table-xs bg-primary text-primary-content m-auto'>
<tbody>
{rows.map((item, index) => <BingoRow key={index} items={item}/>)}
</tbody>

View File

@ -4,6 +4,7 @@ import React from 'react'
import Bingo from './bingo'
function FisherYatesShuffle(array:string[]):string[]{
array = array.slice();
for(let i = array.length - 1; i > 0; i--){
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
@ -13,14 +14,36 @@ function FisherYatesShuffle(array:string[]):string[]{
return array;
}
export default function BingoController(){
export default function BingoController({buzzwords} : {buzzwords?: string[]}){
const [orientation, setOrientation] = React.useState("");
React.useEffect(()=>{
function updateOrientation()
{
setOrientation(window.screen.orientation.type);
}
// init
updateOrientation();
window.addEventListener("orientationchange", updateOrientation);
// destructor
return () => {
window.removeEventListener("orientationchange", updateOrientation);
}
});
const [size, setSize] = React.useState(5);
const buzzwords = ["Cloud", "Cyber-[Something]", "Distrupt[ive]", "AI", "Meta [Something]", "Gamification", "Web 2.0/3.0", "Industry 4.0", "Internet of Things", "Multiexperience", "Big Data", "Crypto", "[Something] as a service", "Emerging [Something]", "Streamline", "Ecosystem", "Leverage", "Outside the Box", "Pivot", "Strategic", "Agile", "Smart Tech", "Data Warehouse", "Actionable Insights", "Holistic Approach", "Digital Transformation", "Growth Hacking"];
if(buzzwords == undefined || buzzwords.length < 1) buzzwords = ["Cloud", "Cyber-[Something]", "Distrupt[ive]", "AI", "Meta [Something]", "Gamification", "Web 2.0/3.0", "Industry 4.0", "Internet of Things", "Multiexperience", "Big Data", "Crypto", "[Something] as a service", "Emerging [Something]", "Streamline", "Ecosystem", "Leverage", "Outside the Box", "Pivot", "Strategic", "Agile", "Smart Tech", "Data Warehouse", "Actionable Insights", "Holistic Approach", "Digital Transformation", "Growth Hacking"];
const [items, setItems] = React.useState(buzzwords);
const sizeError = (items.length < size);
return(
<>
<div className="w-3/4 flex flex-col m-auto gap-4">
<div className="w-full md:w-3/4 flex flex-col m-auto gap-4">
{orientation != "landscape-primary" && <div role="alert" className="alert alert-info">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" className="stroke-current shrink-0 w-6 h-6"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span>Please rotate your device</span>
</div>}
<Bingo size={size} items={items}/>
<form className="w-1/3 m-auto">
<input type="range" min={3} max={5} value={size} className="range range-xs sm:range-sm md:range-md range-secondary" step={1} onChange={({target:{value:s}}) => setSize(+s)}/>
@ -29,7 +52,7 @@ export default function BingoController(){
<span>4x4</span>
<span>5x5</span>
</div>
<a className="btn btn-xs sm:btn-sm md:btn-md btn-secondary" onClick={() => setItems(FisherYatesShuffle(buzzwords))}>Regenerate</a>
<a className="btn btn-xs sm:btn-sm md:btn-md btn-secondary" onClick={() => setItems(FisherYatesShuffle(buzzwords!))}>Regenerate</a>
</form>
</div>
{sizeError && <div className="alert alert-warning"><svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg><span>Warning: Mismatch between item count and size</span></div>}

View File

@ -9,6 +9,6 @@ export default function BingoItem({text}: Props){
const [clicked, setClicked] = React.useState(false);
return(
<td><a className={clsx("btn btn-xs sm:btn-sm md:btn-md w-full", {"btn-ghost":(!clicked)}, {"btn-accent":clicked})} onClick={() => setClicked(!clicked)}>{text}</a></td>
<td><a className={clsx("btn btn-xs w-full overflow-hidden", {"btn-ghost":(!clicked)}, {"btn-accent":clicked})} onClick={() => setClicked(!clicked)}>{text}</a></td>
);
}

View File

@ -0,0 +1,5 @@
export default function DarkIcon(){
return(
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="currentColor" d="M9.37 5.51A7.35 7.35 0 0 0 9.1 7.5c0 4.08 3.32 7.4 7.4 7.4c.68 0 1.35-.09 1.99-.27A7.014 7.014 0 0 1 12 19c-3.86 0-7-3.14-7-7c0-2.93 1.81-5.45 4.37-6.49zM12 3a9 9 0 1 0 9 9c0-.46-.04-.92-.1-1.36a5.389 5.389 0 0 1-4.4 2.26a5.403 5.403 0 0 1-3.14-9.8c-.44-.06-.9-.1-1.36-.1z"/></svg>
);
}

View File

@ -1,6 +1,7 @@
"use client";
import React from 'react';
import React from "react";
import DarkIcon from "./darkicon";
export default function ThemeSwitcher(){
const [theme, setTheme] = React.useState("dark");
@ -8,14 +9,16 @@ export default function ThemeSwitcher(){
React.useEffect(() => {document.body.setAttribute("data-theme", theme)});
return(
<ul className="p-2 right-0 text-base-content z-10">
<ul className="p-2 right-0 z-10">
<li><a onClick={() => setTheme("light")}>Light</a></li>
<li><a onClick={() => setTheme("dark")}>Dark</a></li>
<li><a onClick={() => setTheme("synthwave")}>Synthwave</a></li>
<li><a onClick={() => setTheme("cyberpunk")}>Cyberpunk</a></li>
<li><a onClick={() => setTheme("valentine")}>Valentine</a></li>
<li><a onClick={() => setTheme("pastel")}>Pastel</a></li>
<li><a onClick={() => setTheme("aqua")}>Aqua</a></li>
<li><a onClick={() => setTheme("dark")}><DarkIcon/>Dark</a></li>
<li><a onClick={() => setTheme("synthwave")}><DarkIcon/>Synthwave</a></li>
<li><a onClick={() => setTheme("coffee")}><DarkIcon/>Coffee</a></li>
<li><a onClick={() => setTheme("dim")}><DarkIcon/>Dim</a></li>
</ul>
);
}

View File

@ -1,4 +1,5 @@
import type { Metadata } from 'next'
import ThemeSwitcher from './components/themeswitcher'
import './globals.css'
export const metadata: Metadata = {
@ -7,13 +8,40 @@ export const metadata: Metadata = {
}
export default function RootLayout({
children,
children,
}: {
children: React.ReactNode
children: React.ReactNode
}) {
return (
<html lang="en" data-theme="dark">
<body className="bg-base-100 base-content flex flex-col h-screen">{children}</body>
</html>
)
return (
<html lang="en" data-theme="dark">
<body className="bg-base-100 base-content flex flex-col h-screen">
<div className="navbar bg-neutral text-neutral-content">
<div className="navbar-start">
<div className="dropdown">
<div tabIndex={0} role="button" className="btn btn-ghost lg:hidden">
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 6h16M4 12h8m-8 6h16" /></svg>
</div>
<ul tabIndex={0} className="menu menu-sm dropdown-content bg-neutral text-neutral-content mt-3 z-[1] p-2 shadow rounded-box w-52">
<li><a href="https://git.datalore.sh/datalore/buzzword-bingo.git" target="_blank">Source Code</a></li>
<li><a>Theme</a><ThemeSwitcher/></li>
</ul>
</div>
<span><b className="normal-case text-xl">Buzzword Bingo</b><span className="text-xs ml-1">v{process.env.npm_package_version}</span></span>
</div>
<div className="navbar-end hidden lg:flex">
<ul className="menu menu-horizontal px-1">
<li><a href="https://git.datalore.sh/datalore/buzzword-bingo.git" target="_blank">Source Code</a></li>
<li><details>
<summary>Theme</summary>
<ThemeSwitcher/>
</details></li>
</ul>
</div>
</div>
<main className="flex flex-col flex-1">
{children}
</main>
</body>
</html>
);
}

View File

@ -3,28 +3,6 @@ import ThemeSwitcher from './components/themeswitcher'
export default function Home(){
return(
<>
<div className="navbar bg-neutral text-neutral-content">
<div className="flex-1">
<span><b className="normal-case text-xl">Buzzword Bingo</b><span className="text-xs ml-1">v{process.env.npm_package_version}</span></span>
</div>
<div className="flex-none">
<ul className="menu menu-horizontal px-1">
<li>
<a href="https://git.datalore.sh/datalore/buzzword-bingo.git" target="_blank">Source Code</a>
</li>
<li>
<details>
<summary>Theme</summary>
<ThemeSwitcher/>
</details>
</li>
</ul>
</div>
</div>
<main className="flex flex-col flex-1">
<BingoController/>
</main>
</>
<BingoController/>
);
}

View File

@ -7,7 +7,7 @@ const config: Config = {
},
plugins: [require("daisyui")],
daisyui: {
themes: ["light", "dark", "synthwave", "cyberpunk", "valentine", "pastel", "aqua"]
themes: ["light", "dark", "synthwave", "cyberpunk", "valentine", "pastel", "aqua", "coffee", "dim"]
}
};