|
| 1 | +import React, { useState, useEffect } from 'react'; |
| 2 | +import { Link } from 'react-router-dom'; |
| 3 | +import { ArrowLeftIcon, Sparkle, Copy } from '@phosphor-icons/react'; |
| 4 | +import usePageTitle from '../../utils/usePageTitle'; |
| 5 | +import colors from '../../config/colors'; |
| 6 | +import { useToast } from '../../hooks/useToast'; |
| 7 | + |
| 8 | +const prefixes = [ |
| 9 | + 'Operation', 'Project', 'Protocol', 'Directive', 'Initiative', 'Task Force', 'Unit', 'Division', 'Cell', 'Asset', |
| 10 | + 'Red', 'Blue', 'Green', 'Black', 'White', 'Gold', 'Silver', 'Bronze', |
| 11 | +]; |
| 12 | + |
| 13 | +const nouns = [ |
| 14 | + 'Viper', 'Phoenix', 'Shadow', 'Ghost', 'Spectre', 'Wraith', 'Raven', 'Crow', 'Jackal', 'Cobra', 'Hydra', 'Cerberus', |
| 15 | + 'Aegis', 'Shield', 'Sword', 'Dagger', 'Arrow', 'Spear', 'Javelin', 'Trident', 'Hammer', 'Anvil', 'Crucible', |
| 16 | + 'Avalanche', 'Blizzard', 'Cyclone', 'Hurricane', 'Tornado', 'Typhoon', 'Earthquake', 'Volcano', 'Tsunami', |
| 17 | + 'Genesis', 'Exodus', 'Leviathan', 'Behemoth', 'Goliath', 'Titan', 'Colossus', 'Gargantua', 'Prometheus', |
| 18 | + 'Icarus', 'Daedalus', 'Orpheus', 'Morpheus', 'Nyx', 'Erebus', 'Hades', 'Styx', 'Charon', 'Thanatos', |
| 19 | + 'Valkyrie', 'Ragnarok', 'Valhalla', 'Asgard', 'Midgard', 'Jotunheim', 'Fenrir', 'Jormungandr', 'Sleipnir', |
| 20 | + 'Paperclip', 'Viking', 'Survival', 'Overlord', 'Neptune', 'Barbarossa', 'Stalingrad', 'Kursk', 'Midway', |
| 21 | + 'Normandy', 'Market Garden', 'Watchtower', 'Downfall', 'Unthinkable', 'Crossbow', 'Mincemeat', 'Fortitude', |
| 22 | + 'Dragon', 'Wyvern', 'Griffin', 'Chimera', 'Manticore', 'Basilisk', 'Kraken', 'Scylla', 'Charybdis', |
| 23 | + 'Sun', 'Moon', 'Star', 'Comet', 'Nebula', 'Galaxy', 'Quasar', 'Pulsar', 'Supernova', |
| 24 | + 'Storm', 'Tempest', 'Maelstrom', 'Vortex', 'Singularity', 'Event Horizon', 'Black Hole', |
| 25 | + 'Nomad', 'Wanderer', 'Ronin', 'Samurai', 'Ninja', 'Shinobi', 'Kunoichi', |
| 26 | + 'Gladiator', 'Centurion', 'Legionnaire', 'Spartan', 'Hoplite', 'Phalanx', |
| 27 | + 'Crusader', 'Paladin', 'Templar', 'Inquisitor', 'Exorcist', |
| 28 | + 'Warlock', 'Sorcerer', 'Mage', 'Wizard', 'Archmage', 'Necromancer', |
| 29 | + 'Druid', 'Shaman', 'Witch Doctor', 'Oracle', 'Seer', 'Prophet', |
| 30 | + 'Bard', 'Skald', 'Troubadour', 'Minstrel', |
| 31 | + 'Thief', 'Rogue', 'Assassin', 'Cutthroat', 'Bandit', 'Outlaw', |
| 32 | + 'Pirate', 'Corsair', 'Privateer', 'Buccaneer', 'Freebooter', |
| 33 | + 'Rebel', 'Insurgent', 'Guerrilla', 'Freedom Fighter', 'Revolutionary', |
| 34 | + 'Anarchist', 'Nihilist', 'Terrorist', 'Extremist', |
| 35 | + 'Cyborg', 'Android', 'Robot', 'Mech', 'Drone', |
| 36 | + 'Mutant', 'Chimera', 'Hybrid', 'Abomination', |
| 37 | + 'Vampire', 'Werewolf', 'Lich', 'Ghoul', 'Zombie', |
| 38 | + 'Angel', 'Demon', 'Devil', 'Archon', 'Seraph', 'Nephilim', |
| 39 | + 'God', 'Goddess', 'Deity', 'Avatar', 'Primordial', |
| 40 | + 'Serpent', 'Owl', 'Hawk', 'Viper', 'Hunter', 'Orchid', 'Fox', 'Mamba', 'Phoenix', 'Wind' |
| 41 | +]; |
| 42 | + |
| 43 | +const CodenameGeneratorPage = () => { |
| 44 | + usePageTitle('Codename Generator'); |
| 45 | + const [codename, setCodename] = useState(''); |
| 46 | + const { addToast } = useToast(); |
| 47 | + |
| 48 | + useEffect(() => { |
| 49 | + generateCodename(); |
| 50 | + }, []); |
| 51 | + |
| 52 | + const generateCodename = () => { |
| 53 | + const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]; |
| 54 | + const noun = nouns[Math.floor(Math.random() * nouns.length)]; |
| 55 | + setCodename(`${prefix} ${noun}`); |
| 56 | + }; |
| 57 | + |
| 58 | + const handleCopy = () => { |
| 59 | + navigator.clipboard.writeText(codename); |
| 60 | + addToast('Copied to clipboard!', 'success'); |
| 61 | + }; |
| 62 | + |
| 63 | + const cardStyle = { |
| 64 | + backgroundColor: colors['app-alpha-10'], |
| 65 | + borderColor: colors['app-alpha-50'], |
| 66 | + color: colors.app, |
| 67 | + }; |
| 68 | + |
| 69 | + return ( |
| 70 | + <div className="py-16 sm:py-24"> |
| 71 | + <div className="mx-auto max-w-7xl px-6 lg:px-8 text-gray-300"> |
| 72 | + <Link |
| 73 | + to="/apps" |
| 74 | + className="text-article hover:underline flex items-center justify-center gap-2 text-lg mb-4" |
| 75 | + > |
| 76 | + <ArrowLeftIcon size={24} /> Back to Apps |
| 77 | + </Link> |
| 78 | + <h1 className="text-4xl font-bold tracking-tight sm:text-6xl mb-4 flex items-center"> |
| 79 | + <span className="codex-color">fc</span> |
| 80 | + <span className="separator-color">::</span> |
| 81 | + <span className="apps-color">apps</span> |
| 82 | + <span className="separator-color">::</span> |
| 83 | + <span className="single-app-color">codename-generator</span> |
| 84 | + </h1> |
| 85 | + <hr className="border-gray-700" /> |
| 86 | + <div className="flex justify-center items-center mt-16"> |
| 87 | + <div |
| 88 | + className="group bg-transparent border rounded-lg shadow-2xl p-6 flex flex-col justify-between relative transform transition-all duration-300 ease-in-out scale-105 overflow-hidden h-full w-full max-w-4xl" |
| 89 | + style={cardStyle} |
| 90 | + > |
| 91 | + <div |
| 92 | + className="absolute top-0 left-0 w-full h-full opacity-10" |
| 93 | + style={{ |
| 94 | + backgroundImage: |
| 95 | + 'radial-gradient(circle, white 1px, transparent 1px)', |
| 96 | + backgroundSize: '10px 10px', |
| 97 | + }} |
| 98 | + ></div> |
| 99 | + <div className="relative z-10 p-1"> |
| 100 | + <h1 className="text-3xl font-arvo font-normal mb-4 text-app"> Codename Generator </h1> |
| 101 | + <hr className="border-gray-700 mb-4" /> |
| 102 | + <div className="flex flex-col items-center gap-8"> |
| 103 | + <div className="text-4xl text-app font-arvo font-bold text-center h-16 mt-12">{codename}</div> |
| 104 | + <div className="flex gap-4"> |
| 105 | + <button |
| 106 | + onClick={generateCodename} |
| 107 | + className="flex items-center gap-2 text-lg font-arvo font-normal px-4 py-2 rounded-md border transition-colors duration-300 ease-in-out bg-app/50 text-white hover:bg-app/70" |
| 108 | + > |
| 109 | + <Sparkle size={20} /> Generate |
| 110 | + </button> |
| 111 | + <button |
| 112 | + onClick={handleCopy} |
| 113 | + className="flex items-center gap-2 text-lg font-arvo font-normal px-4 py-2 rounded-md border transition-colors duration-300 ease-in-out bg-app/50 text-white hover:bg-app/70" |
| 114 | + disabled={!codename} |
| 115 | + > |
| 116 | + <Copy size={20} /> Copy |
| 117 | + </button> |
| 118 | + </div> |
| 119 | + </div> |
| 120 | + </div> |
| 121 | + </div> |
| 122 | + </div> |
| 123 | + </div> |
| 124 | + </div> |
| 125 | + ); |
| 126 | +}; |
| 127 | + |
| 128 | +export default CodenameGeneratorPage; |
0 commit comments