diff --git a/agent.md b/agent.md new file mode 100644 index 0000000..701929a --- /dev/null +++ b/agent.md @@ -0,0 +1,8 @@ +# Agent Guidelines for Vue + +These rules must be followed when working on this project: + +- **No Code Comments**: Never add comments to the ` + + diff --git a/src/components/404.vue b/src/components/404.vue deleted file mode 100644 index 7764416..0000000 --- a/src/components/404.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/src/components/About.vue b/src/components/About.vue deleted file mode 100644 index 0502557..0000000 --- a/src/components/About.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - diff --git a/src/components/Description.vue b/src/components/Description.vue deleted file mode 100644 index 40ee650..0000000 --- a/src/components/Description.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/components/Information.vue b/src/components/Information.vue deleted file mode 100644 index f0ea21c..0000000 --- a/src/components/Information.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - - diff --git a/src/components/Pages.vue b/src/components/Pages.vue deleted file mode 100644 index e6eeb08..0000000 --- a/src/components/Pages.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/src/components/Pokedex.vue b/src/components/Pokedex.vue deleted file mode 100644 index ced8656..0000000 --- a/src/components/Pokedex.vue +++ /dev/null @@ -1,136 +0,0 @@ - - - - diff --git a/src/components/Pokemon.vue b/src/components/Pokemon.vue deleted file mode 100644 index b4081e6..0000000 --- a/src/components/Pokemon.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - diff --git a/src/components/PokemonIndex.vue b/src/components/PokemonIndex.vue deleted file mode 100644 index 4da58a4..0000000 --- a/src/components/PokemonIndex.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - - diff --git a/src/components/Footer.vue b/src/components/layout/Footer.vue similarity index 90% rename from src/components/Footer.vue rename to src/components/layout/Footer.vue index 6a869cf..8e3b70c 100644 --- a/src/components/Footer.vue +++ b/src/components/layout/Footer.vue @@ -4,7 +4,7 @@ Pokedex - About + Home Inspiration Code diff --git a/src/components/layout/Header.vue b/src/components/layout/Header.vue new file mode 100644 index 0000000..bcbedf9 --- /dev/null +++ b/src/components/layout/Header.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/components/layout/LeftScreen.vue b/src/components/layout/LeftScreen.vue new file mode 100644 index 0000000..8980921 --- /dev/null +++ b/src/components/layout/LeftScreen.vue @@ -0,0 +1,68 @@ + + + diff --git a/src/components/layout/PokedexChassis.vue b/src/components/layout/PokedexChassis.vue new file mode 100644 index 0000000..142f72b --- /dev/null +++ b/src/components/layout/PokedexChassis.vue @@ -0,0 +1,42 @@ + + + diff --git a/src/components/layout/RightControls.vue b/src/components/layout/RightControls.vue new file mode 100644 index 0000000..54dcba8 --- /dev/null +++ b/src/components/layout/RightControls.vue @@ -0,0 +1,137 @@ + + + diff --git a/src/components/layout/ScreenSplit.vue b/src/components/layout/ScreenSplit.vue new file mode 100644 index 0000000..47655b7 --- /dev/null +++ b/src/components/layout/ScreenSplit.vue @@ -0,0 +1,48 @@ + + + diff --git a/src/components/layout/StatusBar.vue b/src/components/layout/StatusBar.vue new file mode 100644 index 0000000..6eba2d6 --- /dev/null +++ b/src/components/layout/StatusBar.vue @@ -0,0 +1,23 @@ + + + diff --git a/src/components/lists/PopularPokemonList.vue b/src/components/lists/PopularPokemonList.vue new file mode 100644 index 0000000..f290420 --- /dev/null +++ b/src/components/lists/PopularPokemonList.vue @@ -0,0 +1,82 @@ + + + diff --git a/src/components/pokemon/Description.vue b/src/components/pokemon/Description.vue new file mode 100644 index 0000000..fd8f908 --- /dev/null +++ b/src/components/pokemon/Description.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/pokemon/Information.vue b/src/components/pokemon/Information.vue new file mode 100644 index 0000000..598f06a --- /dev/null +++ b/src/components/pokemon/Information.vue @@ -0,0 +1,26 @@ + + + + diff --git a/src/components/pokemon/Pokemon.vue b/src/components/pokemon/Pokemon.vue new file mode 100644 index 0000000..98d9b8a --- /dev/null +++ b/src/components/pokemon/Pokemon.vue @@ -0,0 +1,19 @@ + + + + diff --git a/src/components/ui/ActionDisplay.vue b/src/components/ui/ActionDisplay.vue new file mode 100644 index 0000000..ba47342 --- /dev/null +++ b/src/components/ui/ActionDisplay.vue @@ -0,0 +1,50 @@ + + + diff --git a/src/components/ui/ArrowButton.vue b/src/components/ui/ArrowButton.vue new file mode 100644 index 0000000..f19db11 --- /dev/null +++ b/src/components/ui/ArrowButton.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/components/ui/BackgroundGrid.vue b/src/components/ui/BackgroundGrid.vue new file mode 100644 index 0000000..6a83f94 --- /dev/null +++ b/src/components/ui/BackgroundGrid.vue @@ -0,0 +1,16 @@ + + + diff --git a/src/components/ui/BezelButton.vue b/src/components/ui/BezelButton.vue new file mode 100644 index 0000000..3d664f1 --- /dev/null +++ b/src/components/ui/BezelButton.vue @@ -0,0 +1,11 @@ + + + diff --git a/src/components/ui/NumpadKey.vue b/src/components/ui/NumpadKey.vue new file mode 100644 index 0000000..1ad7f2b --- /dev/null +++ b/src/components/ui/NumpadKey.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/ui/PillButton.vue b/src/components/ui/PillButton.vue new file mode 100644 index 0000000..103b2b1 --- /dev/null +++ b/src/components/ui/PillButton.vue @@ -0,0 +1,11 @@ + diff --git a/src/components/ui/PokemonInfoCard.vue b/src/components/ui/PokemonInfoCard.vue new file mode 100644 index 0000000..97c10d0 --- /dev/null +++ b/src/components/ui/PokemonInfoCard.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/components/ui/SearchDisplay.vue b/src/components/ui/SearchDisplay.vue new file mode 100644 index 0000000..530428b --- /dev/null +++ b/src/components/ui/SearchDisplay.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/components/ui/SideMenuButton.vue b/src/components/ui/SideMenuButton.vue new file mode 100644 index 0000000..5bbcc77 --- /dev/null +++ b/src/components/ui/SideMenuButton.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/components/ui/StatusButton.vue b/src/components/ui/StatusButton.vue new file mode 100644 index 0000000..f50a434 --- /dev/null +++ b/src/components/ui/StatusButton.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/composables/usePokedexNavigation.js b/src/composables/usePokedexNavigation.js new file mode 100644 index 0000000..4fbfb49 --- /dev/null +++ b/src/composables/usePokedexNavigation.js @@ -0,0 +1,81 @@ +import { ref } from 'vue' +import { useRouter } from 'vue-router' +import { appState } from '../store' +import { MAX_SEARCH_LENGTH } from '../constants/ui' + +const searchQuery = ref('') + +export function usePokedexNavigation() { + const router = useRouter() + + function handleKeypad(num) { + if (searchQuery.value.length < MAX_SEARCH_LENGTH) { + searchQuery.value += String(num) + } + } + + function goHome() { + router.push('/') + } + + function goBack() { + router.go(-1) + } + + function executeSearch() { + if (searchQuery.value) { + const pokemonId = parseInt(searchQuery.value) + router.push(`/pokemon/${pokemonId}`) + searchQuery.value = '' + } + } + + function clearSearch() { + if (searchQuery.value.length > 0) { + searchQuery.value = searchQuery.value.slice(0, -1) + } + } + + function handleMainButton() { + if (searchQuery.value) { + executeSearch() + } else { + goHome() + } + } + + function handleBackButton() { + if (searchQuery.value) { + clearSearch() + } else { + goBack() + } + } + + function handleNext() { + if (appState.currentPokemon) { + let nextId = appState.currentPokemon.id + 1 + router.push(`/pokemon/${nextId}`) + } + } + + function handlePrev() { + if (appState.currentPokemon && appState.currentPokemon.id > 1) { + let prevId = appState.currentPokemon.id - 1 + router.push(`/pokemon/${prevId}`) + } + } + + return { + searchQuery, + handleKeypad, + goHome, + goBack, + executeSearch, + clearSearch, + handleMainButton, + handleBackButton, + handleNext, + handlePrev + } +} diff --git a/src/composables/useScreenActions.js b/src/composables/useScreenActions.js new file mode 100644 index 0000000..03307bb --- /dev/null +++ b/src/composables/useScreenActions.js @@ -0,0 +1,60 @@ +import { reactive, toRefs } from 'vue' + +const state = reactive({ + button1: { label: '', action: null, active: false }, + button2: { label: '', action: null, active: false }, + button3: { label: '', action: null, active: false }, + button4: { label: '', action: null, active: false }, + button5: { label: '', action: null, active: false } +}) + +export function useScreenActions() { + function setButtonAction(buttonNumber, label, action) { + if (buttonNumber >= 1 && buttonNumber <= 5) { + const buttonKey = `button${buttonNumber}` + state[buttonKey].label = label + state[buttonKey].action = action + } + } + + function setButtonActive(buttonNumber, active) { + if (buttonNumber >= 1 && buttonNumber <= 5) { + const buttonKey = `button${buttonNumber}` + state[buttonKey].active = active + } + } + + function clearActions() { + for (let i = 1; i <= 5; i++) { + const buttonKey = `button${i}` + state[buttonKey].label = '' + state[buttonKey].action = null + state[buttonKey].active = false + } + } + + function setButtonActions(actions) { + clearActions() + actions.forEach(({ buttonNumber, label, action }) => { + setButtonAction(buttonNumber, label, action) + }) + } + + function handleButton(buttonNumber) { + if (buttonNumber >= 1 && buttonNumber <= 5) { + const buttonKey = `button${buttonNumber}` + if (state[buttonKey].action) { + state[buttonKey].action() + } + } + } + + return { + ...toRefs(state), + setButtonAction, + setButtonActive, + clearActions, + setButtonActions, + handleButton + } +} diff --git a/src/constants/ui.js b/src/constants/ui.js new file mode 100644 index 0000000..c3626d8 --- /dev/null +++ b/src/constants/ui.js @@ -0,0 +1,23 @@ +export const POKEDEX_COLORS = { + CHASSIS_MAIN: '#dc0a2d', + CHASSIS_DARK: '#89061c', + SCREEN_BG: '#18181b', + SCREEN_BEZEL: '#e4e4e7', // zinc-200 + SCREEN_BORDER: '#89061c', + HINT_GREEN: '#22c55e', + HINT_RED: '#ef4444', + TEXT_MUTE: '#a1a1aa' // zinc-400 +} + +export const DIMENSIONS = { + WIDTH: '1200px', + HEIGHT: '900px', + SCREEN_ASPECT_RATIO: '3/4', + INFO_ASPECT_RATIO: '5/2' +} + +export const MAX_SEARCH_LENGTH = 4 + +export const SIDE_MENU_ITEMS = ['POKEDEX', 'FAVORITES', 'SETTINGS', 'MAP', 'BAG'] + +export const KEYPAD_KEYS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] diff --git a/src/pages/Home.vue b/src/pages/Home.vue new file mode 100644 index 0000000..db8a8a9 --- /dev/null +++ b/src/pages/Home.vue @@ -0,0 +1,152 @@ + + + + diff --git a/src/pages/NotFound.vue b/src/pages/NotFound.vue new file mode 100644 index 0000000..f11f6eb --- /dev/null +++ b/src/pages/NotFound.vue @@ -0,0 +1,59 @@ + + + diff --git a/src/pages/Pokedex.vue b/src/pages/Pokedex.vue new file mode 100644 index 0000000..36a8760 --- /dev/null +++ b/src/pages/Pokedex.vue @@ -0,0 +1,224 @@ + + + + + diff --git a/src/router.js b/src/router.js index c05e12e..d1d7f19 100644 --- a/src/router.js +++ b/src/router.js @@ -1,13 +1,13 @@ import { createRouter, createWebHistory } from "vue-router"; -import Pokedex from "./components/Pokedex.vue"; -import Page404 from "./components/404.vue"; -import About from "./components/About.vue"; +import Home from "./pages/Home.vue"; +import Pokedex from "./pages/Pokedex.vue"; +import NotFound from "./pages/NotFound.vue"; const routes = [ - { path: "/", component: About, name: "home" }, + { path: "/", component: Home, name: "home" }, { path: "/pokemon/:id", component: Pokedex, name: "pokemon" }, - { path: "/about", component: About, name: "about" }, - { path: "/:catchAll(.*)", component: Page404, name: "404" }, + { path: "/home", component: Home, name: "home-alias" }, + { path: "/:catchAll(.*)", component: NotFound, name: "404" }, ]; const history = createWebHistory(); diff --git a/src/store.js b/src/store.js new file mode 100644 index 0000000..5a8afed --- /dev/null +++ b/src/store.js @@ -0,0 +1,21 @@ +import { reactive } from 'vue' + +export const appState = reactive({ + currentPokemon: null, + previousPokemon: null, + nextPokemon: null, + setCurrentPokemon(pokemon) { + this.currentPokemon = pokemon + }, + setPreviousPokemon(pokemon) { + this.previousPokemon = pokemon + }, + setNextPokemon(pokemon) { + this.nextPokemon = pokemon + }, + clearCurrentPokemon() { + this.currentPokemon = null + this.previousPokemon = null + this.nextPokemon = null + } +}) diff --git a/src/utils/theme.js b/src/utils/theme.js new file mode 100644 index 0000000..cafeba5 --- /dev/null +++ b/src/utils/theme.js @@ -0,0 +1,11 @@ +import tinycolor from 'tinycolor2' + +export function generateThemeColors(colorArray) { + const rgbColor = `rgb(${colorArray[0]}, ${colorArray[1]}, ${colorArray[2]})` + const originalColor = tinycolor(rgbColor) + + return { + background: originalColor.darken(30).toString(), + text: originalColor.brighten(40).toString() // slightly brighter for contrast + } +}