Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to nuxt 3 #30

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions nuxt-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
*.log*
.nuxt
.nitro
.cache
.output
.env
dist
13 changes: 13 additions & 0 deletions nuxt-app/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"tabWidth": 2,
"useTabs": false,
"overrides": [
{
"files": "*.vue",
"options": {
"tabWidth": 2,
"parser": "vue"
}
}
]
}
42 changes: 42 additions & 0 deletions nuxt-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Nuxt 3 Minimal Starter

Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.

## Setup

Make sure to install the dependencies:

```bash
# yarn
yarn install

# npm
npm install

# pnpm
pnpm install
```

## Development Server

Start the development server on http://localhost:3000

```bash
npm run dev
```

## Production

Build the application for production:

```bash
npm run build
```

Locally preview production build:

```bash
npm run preview
```

Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
6 changes: 6 additions & 0 deletions nuxt-app/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<template>
<NuxtLayout>
<NuxtLoadingIndicator />
<NuxtPage />
</NuxtLayout>
</template>
3 changes: 3 additions & 0 deletions nuxt-app/assets/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
Binary file added nuxt-app/assets/images/apple.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/avocado.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/banana.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/cherry.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/coconut.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/grape.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/kiwi.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/mango.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/orange.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/papaya.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/peach.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/peanut.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/pineapple.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/strawberry.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added nuxt-app/assets/images/watermelon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 79 additions & 0 deletions nuxt-app/components/app-nav.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script setup>
const colorMode = useColorMode();

const themes = ["system", "light", "dark"];

function toggleTheme() {
const currentThemeIndex = themes.indexOf(colorMode.preference);
const nextThemeIndex = (currentThemeIndex + 1) % themes.length;

colorMode.preference = themes[nextThemeIndex];
}
</script>

<template>
<div>
<nav>
<div class="flex flex-row items-center gap-2 p-2">
<NuxtLink
to="/"
class="p-2 text-xl font-bold rounded-md hover:bg-pink-100 dark:hover:bg-pink-500"
>
Mystery Fruits
</NuxtLink>
<div class="flex items-stretch justify-between flex-grow">
<div class="flex flex-row">
<NuxtLink
to="/credits"
class="p-2 rounded-md hover:bg-pink-100 dark:hover:bg-pink-500 dark:hover:text-white"
:class="{ 'text-pink-600': $route.name === 'credits' }"
>
Credits
</NuxtLink>
<RouterLink
to="/contributors"
class="p-2 rounded-md hover:bg-pink-100 dark:hover:bg-pink-500 dark:hover:text-white"
:class="{
'text-pink-600': $route.name === 'contributors',
}"
>
Contributors
</RouterLink>
</div>
<div class="flex flex-row gap-2">
<a
class="flex items-center p-2 rounded-md hover:bg-pink-100 dark:hover:bg-pink-500"
href="https://www.github.com/jedymatt/mystery-fruits-js"
target="_blank"
rel="noopener noreferrer"
>
<span class="sr-only">Github</span>

<Icon name="logos:github-icon" />
</a>
<!-- Theme button -->
<button
class="p-2 rounded-md hover:bg-pink-100"
@click="toggleTheme()"
>
<Icon
v-if="colorMode.preference === themes[2]"
name="heroicons:computer-desktop-solid"
/>

<Icon
v-else-if="colorMode.preference === themes[0]"
name="heroicons:sun-solid"
/>

<Icon
v-else="colorMode.preference === themes[1]"
name="heroicons:moon-solid"
/>
</button>
</div>
</div>
</div>
</nav>
</div>
</template>
40 changes: 40 additions & 0 deletions nuxt-app/components/fruit-button.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
fruit: {
type: String,
required: true,
},

selectedIndex: {
type: Number,
default: -1,
},
});

// const selectedIndex = computed(() => props.selectedIndex + 1);

const isSelected = computed(() => props.selectedIndex !== -1);
</script>

<template>
<button
class="relative flex flex-col items-center justify-center gap-1 p-2 transition-all duration-300 rounded-md hover:cursor-pointer overflow-clip"
:class="[
isSelected ? 'bg-pink-500/20' : 'hover:drop-shadow-[0_0_1em_#ec4899] dark:hover:drop-shadow-[0_0_2em_#ec4899]',
]"
>
<FruitImage class="aspect-square" :fruit="fruit" />
<div class="text-xs font-semibold uppercase">
{{ fruit }}
</div>
<div
v-if="isSelected"
class="absolute flex items-center justify-center w-5 h-5 text-gray-700 bg-white border border-gray-400 rounded-full top-2 right-2"
>
<span class="text-xs font-medium text-gray-700">{{
selectedIndex + 1
}}</span>
</div>
</button>
</template>
15 changes: 15 additions & 0 deletions nuxt-app/components/fruit-image.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script setup>
const props = defineProps({
fruit: {
type: String,
required: true,
},
});

const imageUrl = new URL(`/assets/images/${props.fruit}.png`, import.meta.url)
.href;
</script>

<template>
<img class="w-full h-full" :src="imageUrl" :alt="fruit" />
</template>
80 changes: 80 additions & 0 deletions nuxt-app/components/game-over-section.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<script setup>
import { computed } from "vue";
import { countMatchingArrayOrder } from "../lib/counter";

const props = defineProps({
hiddenFruits: {
type: Array,
required: true,
},
selectedFruits: {
type: Array,
required: true,
},
restartGame: {
type: Function,
required: true,
},
attemptsLeft: {
type: Number,
required: true,
default: 0,
},
});

const remark = computed(() =>
isSuccess()
? `You guessed it all with ${props.attemptsLeft} remaining attempts.`
: "You have no more attempts left."
);

function isSuccess() {
return (
countMatchingArrayOrder(props.hiddenFruits, props.selectedFruits) ===
props.hiddenFruits.length
);
}
</script>

<template>
<div class="flex flex-col items-center justify-center">
<h1 class="inline-flex items-center gap-1 text-pink-500">
Game Over
<div class="w-8 h-auto hover:animate-bounce">
<IconsTrophyIcon v-if="isSuccess()" />
<IconsHeartCrackIcon v-else />
</div>
</h1>
<p class="text-gray-800">
{{ remark }}
</p>
<p class="text-gray-800">The correct answer is:</p>

<div class="flex flex-row flex-wrap gap-4">
<div
v-for="(fruit, index) in hiddenFruits"
:key="fruit"
class="flex flex-col items-center justify-center gap-2"
>
<FruitImage
:fruit="fruit"
class="w-16 h-16 lg:h-32 lg:w-32"
:class="{
'drop-shadow-[0_0_2em_#84cc16]':
hiddenFruits[index] === selectedFruits[index],
'drop-shadow-[0_0_2em_#ef4444]':
hiddenFruits[index] !== selectedFruits[index],
}"
/>
<span class="text-sm uppercase">{{ fruit }}</span>
</div>
</div>

<div class="mt-6">
<PrimaryButton @click="restartGame()">
<Icon name="heroicons:arrow-path-solid" class="inline-block w-5 h-5" />
Retry
</PrimaryButton>
</div>
</div>
</template>
46 changes: 46 additions & 0 deletions nuxt-app/components/history-section.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script setup>
import FruitImage from "./fruit-image.vue";

defineProps({
history: {
type: Array,
default: () => [],
},
});
</script>

<template>
<div>
<div class="grid grid-flow-row mt-4 border divide-y rounded-md">
<div v-for="items in history" :key="items">
<div
class="grid self-center grid-cols-5 place-content-center animate-slide-in"
>
<div
v-for="fruit in items.selectedFruits"
:key="fruit"
class="flex flex-col items-center justify-center"
>
<FruitImage :fruit="fruit" class="w-6 h-6" />
<span class="text-xs capitalize">
{{ fruit }}
</span>
</div>

<div class="border-l self-center flex flex-col items-center p-0.5">
<div class="flex items-center justify-center w-6 h-6 font-semibold">
{{ items.correctFruits }}
</div>
<span class="text-xs text-center">Correct Fruits</span>
</div>
<div class="flex flex-col items-center self-center p-1">
<div class="flex items-center justify-center w-6 h-6 font-semibold">
{{ items.correctFruitsOrder }}
</div>
<span class="text-xs text-center">Correct Fruits Order</span>
</div>
</div>
</div>
</div>
</div>
</template>
11 changes: 11 additions & 0 deletions nuxt-app/components/icons/GithubIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 496 512"
>
<!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path
d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"
/>
</svg>
</template>
12 changes: 12 additions & 0 deletions nuxt-app/components/icons/HeartCrackIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<svg
class="fill-red-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path
d="M119.4 44.1C142.7 40.22 166.2 42.2 187.1 49.43L237.8 126.9L162.3 202.3C160.8 203.9 159.1 205.1 160 208.2C160 210.3 160.1 212.4 162.6 213.9L274.6 317.9C277.5 320.6 281.1 320.7 285.1 318.2C288.2 315.6 288.9 311.2 286.8 307.8L226.4 209.7L317.1 134.1C319.7 131.1 320.7 128.5 319.5 125.3L296.8 61.74C325.4 45.03 359.2 38.53 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 0 232.4 0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.09V44.1z"
/>
</svg>
</template>
12 changes: 12 additions & 0 deletions nuxt-app/components/icons/TrophyIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<svg
class="fill-yellow-500"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 576 512"
>
<!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path
d="M572.1 82.38C569.5 71.59 559.8 64 548.7 64h-100.8c.2422-12.45 .1078-23.7-.1559-33.02C447.3 13.63 433.2 0 415.8 0H160.2C142.8 0 128.7 13.63 128.2 30.98C127.1 40.3 127.8 51.55 128.1 64H27.26C16.16 64 6.537 71.59 3.912 82.38C3.1 85.78-15.71 167.2 37.07 245.9c37.44 55.82 100.6 95.03 187.5 117.4c18.7 4.805 31.41 22.06 31.41 41.37C256 428.5 236.5 448 212.6 448H208c-26.51 0-47.99 21.49-47.99 48c0 8.836 7.163 16 15.1 16h223.1c8.836 0 15.1-7.164 15.1-16c0-26.51-21.48-48-47.99-48h-4.644c-23.86 0-43.36-19.5-43.36-43.35c0-19.31 12.71-36.57 31.41-41.37c86.96-22.34 150.1-61.55 187.5-117.4C591.7 167.2 572.9 85.78 572.1 82.38zM77.41 219.8C49.47 178.6 47.01 135.7 48.38 112h80.39c5.359 59.62 20.35 131.1 57.67 189.1C137.4 281.6 100.9 254.4 77.41 219.8zM498.6 219.8c-23.44 34.6-59.94 61.75-109 81.22C426.9 243.1 441.9 171.6 447.2 112h80.39C528.1 135.7 526.5 178.7 498.6 219.8z"
/>
</svg>
</template>