Portfolio Page Vuetify

User
create portfolipage in vutify
Assistant
Here's a basic example of a **Portfolio Page** built using **Vue 3 + Vuetify 3** that displays a list/grid of portfolio items using cards:

### βœ… PortfolioPage.vue (Full Component)

<template>
  <v-container class="my-10">
    <v-row>
      <v-col cols="12" class="text-center mb-8">
        <h1 class="text-h4 font-weight-bold">My Portfolio</h1>
        <p class="text-subtitle-1">Projects I've worked on</p>
      </v-col>

      <v-col
        v-for="(project, index) in portfolioItems"
        :key="index"
        cols="12"
        sm="6"
        md="4"
      >
        <v-card class="elevation-3">
          <v-img
            :src="project.image"
            height="200px"
            cover
          ></v-img>

          <v-card-title>{{ project.title }}</v-card-title>

          <v-card-text>{{ project.description }}</v-card-text>

          <v-card-actions>
            <v-btn :href="project.link" target="_blank" color="primary" variant="flat">
              View Project
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script setup>
import { ref } from 'vue'

const portfolioItems = ref([
  {
    title: 'Project One',
    description: 'A web app built with Vue.js and Firebase.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project1'
  },
  {
    title: 'Project Two',
    description: 'Landing page built using Vuetify.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project2'
  },
  {
    title: 'Project Three',
    description: 'Mobile-first design for a startup.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project3'
  }
])
</script>

### πŸ’„ Optional Styling (Scoped if needed)

<style scoped>
.v-card {
  transition: transform 0.3s ease;
}
.v-card:hover {
  transform: scale(1.03);
}
</style>

### βœ… Add It to Router
If you're using Vue Router, add this to your router config:

{
  path: '/portfolio',
  name: 'Portfolio',
  component: () => import('@/views/PortfolioPage.vue'),
}

Would you like this page to also include filters or categories? Or animated transitions?

User
add interface in types folder vue
Assistant
Sure! To organize your types properly in a Vue 3 + TypeScript + Vuetify project, you can define an interface for your portfolio items and place it in a `types` folder. Here's how you can structure it:

### πŸ—‚ `src/types/PortfolioItem.ts`

export interface PortfolioItem {
  title: string
  description: string
  image: string
  link: string
}

### πŸ“ Update in `PortfolioPage.vue`

<script setup lang="ts">
import { ref } from 'vue'
import type { PortfolioItem } from '@/types/PortfolioItem'

const portfolioItems = ref<PortfolioItem[]>([
  {
    title: 'Project One',
    description: 'A web app built with Vue.js and Firebase.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project1'
  },
  {
    title: 'Project Two',
    description: 'Landing page built using Vuetify.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project2'
  },
  {
    title: 'Project Three',
    description: 'Mobile-first design for a startup.',
    image: 'https://via.placeholder.com/400x200',
    link: 'https://example.com/project3'
  }
])
</script>

### πŸ“ Folder Structure Suggestion

src/
β”‚
β”œβ”€β”€ types/
β”‚   └── PortfolioItem.ts
β”‚
β”œβ”€β”€ views/
β”‚   └── PortfolioPage.vue

Let me know if you'd like to split the description or add tags/tech stack to each item in the interface too.

User
const fetchPortfolioItems = async () => {
portfolioItems.value = await fetchPortfolioItems() as PortfolioItem[]
}
const fetchPortfolioCategories = async () => {
portfolioCategories.value = await fetchPortfolioCategories() as PortfolioCategory[]
}
Conversion of type 'void' to type 'PortfolioItem[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.ts-plugin(2352)
Assistant
That TypeScript error occurs because the function `fetchPortfolioItems()` is calling **itself recursively** β€” which returns `void`, not the actual portfolio data.

You're likely doing something like:

const fetchPortfolioItems = async () => {
  portfolioItems.value = await fetchPortfolioItems() as PortfolioItem[]
}

Here, you're defining a function called `fetchPortfolioItems`, and inside it, you’re calling the same function β€” which results in an infinite loop and incorrect typing.

### βœ… Correct Way

You need to call **another function** (maybe an API utility), not the one you’re declaring. For example:

#### 1. **Create an API function** in `@/services/portfolio.ts`

// src/services/portfolio.ts
import type { PortfolioItem, PortfolioCategory } from '@/types/PortfolioItem'

export const getPortfolioItems = async (): Promise<PortfolioItem[]> => {
  // Simulating fetch with dummy data or use actual API call
  return [
    {
      title: 'Project One',
      description: 'Vue + Firebase app',
      image: 'https://via.placeholder.com/400x200',
      link: 'https://example.com/project1'
    }
  ]
}

export const getPortfolioCategories = async (): Promise<PortfolioCategory[]> => {
  return [
    { id: 1, name: 'Web Development' },
    { id: 2, name: 'Mobile App' }
  ]
}

#### 2. **Use inside your component**

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { PortfolioItem, PortfolioCategory } from '@/types/PortfolioItem'
import { getPortfolioItems, getPortfolioCategories } from '@/services/portfolio'

const portfolioItems = ref<PortfolioItem[]>([])
const portfolioCategories = ref<PortfolioCategory[]>([])

const fetchPortfolioItems = async () => {
  portfolioItems.value = await getPortfolioItems()
}

const fetchPortfolioCategories = async () => {
  portfolioCategories.value = await getPortfolioCategories()
}

onMounted(() => {
  fetchPortfolioItems()
  fetchPortfolioCategories()
})
</script>

### 🧾 Optional Interface

Add this to `PortfolioItem.ts`:

export interface PortfolioItem {
  title: string
  description: string
  image: string
  link: string
}

export interface PortfolioCategory {
  id: number
  name: string
}

Let me know if you want to connect this to a real API endpoint or simulate delays using `setTimeout`.

User
src/components/MyPortfolio.vue:7:10 – error TS2307: Cannot find module '@/dbstore/firebase/myPortfolio' or its corresponding type declarations.

7 } from '@/dbstore/firebase/myPortfolio'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
exist but give error in yarn buiold

Assistant
This error during `yarn build` (but not necessarily during dev) usually means one of the following:

### βœ… 1. **Path Alias `@` Not Recognized in Production**

When using `@` for aliasing (`@/dbstore/firebase/myPortfolio`), your `vite.config.ts` must have the alias configured **correctly**.

#### πŸ“Œ Check this in `vite.config.ts`:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // πŸ‘ˆ this line is required
    },
  },
})

### βœ… 2. **Case Sensitivity (Especially on Linux Servers)**

Check that the filename and folder names are **exactly** correct. For example:

If your import is:

import { getPortfolioData } from '@/dbstore/firebase/myPortfolio'

Make sure the actual file path is:

src/dbstore/firebase/myPortfolio.ts

βœ… NOT:
– `MyPortfolio.ts`
– `myportfolio.ts`
– `myportfolio.js`

Linux-based build systems (e.g. Netlify, Vercel, most CI/CD) are **case-sensitive**, unlike Windows.

### βœ… 3. **Missing `.ts` Extension in TypeScript Declaration**

If the file is `.ts` but you're importing something like:

import myPortfolio from '@/dbstore/firebase/myPortfolio'

TypeScript will infer `.ts` **only if the path resolves properly**. But on build, if there’s no corresponding `.d.ts` file (or incorrect config), it may break.

To be safe, try:

import myPortfolio from '@/dbstore/firebase/myPortfolio.ts'

But usually, with a correct alias, this isn't needed.

### βœ… 4. **Clear Cache & Rebuild**

Sometimes Vite or Yarn caches mess things up.

Try:

rm -rf node_modules dist .vite
yarn cache clean
yarn install
yarn build

Let me know:
– your `vite.config.ts`
– and folder structure for `src/dbstore/firebase/myPortfolio.ts`

…if it's still not working. I can help spot the exact issue.

User
import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import nightwatchPlugin from 'vite-plugin-nightwatch'

// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
nightwatchPlugin(),
],
server: {
port: 5185,
strictPort: true,
origin: 'http://localhost:5185',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
proxy: {
'/api': {
target: 'http://ec2-51-20-60-238.eu-north-1.compute.amazonaws.com/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^/api/, ''),
},
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})

Assistant
Thanks for sharing your `vite.config.ts` β€” it looks correct, and your alias for `@` is properly set up using:

resolve: {
  alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url))
  }
}

So if you're getting the error **during `yarn build`**:

Cannot find module '@/dbstore/firebase/myPortfolio' or its corresponding type declarations.

Here are the most likely causes and fixes:

### βœ… 1. **Check the actual file exists:**

Ensure the file is located exactly at:

src/dbstore/firebase/myPortfolio.ts

βœ”οΈ Make sure:
– The folder and file names match **exactly**.
– You're not accidentally naming it like `myportfolio.ts` (lowercase "P"), which works on Windows but fails in build (Linux is case-sensitive).

### βœ… 2. **Check file extension in import (Optional)**

This should be fine:

import { getPortfolioData } from '@/dbstore/firebase/myPortfolio'

…but for debugging, test it once like:

import { getPortfolioData } from '@/dbstore/firebase/myPortfolio.ts'

If this fixes it, the issue is with Vite not resolving the extension properly β€” but this is rare unless some plugin is interfering.

### βœ… 3. **Restart Vite, Clear Cache**

Sometimes Vite’s build cache causes weird resolution issues. Run:

rm -rf dist node_modules .vite
yarn cache clean
yarn install
yarn build

### βœ… 4. **Verify TS config paths (optional)**

Check your `tsconfig.json` has path mappings, though this isn’t required for Vite, it helps IDEs and may avoid errors:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Then restart your editor (VSCode, etc.) to make sure it's picked up.

### βœ… 5. **Wrong default export or no export**

Make sure your `myPortfolio.ts` file **exports something** like:

export const getPortfolioData = async () => {
  // your logic
}

Not:

const getPortfolioData = () => { ... } // β›” no export

### Want me to review the `myPortfolio.ts` file content or file tree?
Paste the path and top part of that file β€” happy to help!

User
@ this is not working
Assistant
Got it β€” if the `@` alias **is working in dev** but **fails during `yarn build`**, and you’re sure the path and case are correct, then the issue may be one of the following:

## βœ… Fix: Add `baseUrl` & `paths` in `tsconfig.json`

Even though Vite handles `@` during build, TypeScript also needs to know how to resolve it **especially in type checking during build**.

### πŸ”§ `tsconfig.json`:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "types": ["vite/client"]
  }
}

> βœ… Restart your editor after editing `tsconfig.json`.

## βœ… Fix: Use Relative Import (Quick Bypass)

If you're in a rush, temporarily change:

import { getPortfolioData } from '@/dbstore/firebase/myPortfolio'

to:

import { getPortfolioData } from '../../dbstore/firebase/myPortfolio'

…depending on your current file’s depth.

> This confirms whether it's purely an alias issue or something else (like case or missing file).

## βœ… Confirm: File location and naming

Make sure the file exists exactly here:

src/dbstore/firebase/myPortfolio.ts

Run this to confirm:

ls -l src/dbstore/firebase/

If it's `MyPortfolio.ts` (capital "M") it will fail on `@/dbstore/firebase/myPortfolio`.

## βœ… Clean Cache and Rebuild

rm -rf node_modules dist .vite
yarn cache clean
yarn install
yarn build

If this still doesn't resolve the issue, feel free to:

– Share the folder path of `myPortfolio.ts`
– Or share the error after trying the `tsconfig` fix

I’ll get it working with you fast.

User
src/components/MySelf.vue:33:22 – error TS2307: Cannot find module '../assets/images/myimage.png' or its corresponding type declarations.

33 import myimage from '../assets/images/myimage.png';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/dbstore/firebase/myPortfolio.ts:1:29 – error TS2307: Cannot find module '@/firebase' or its corresponding type declarations.

1 import { db, storage } from '@/firebase'

Assistant
Thanks β€” these TypeScript errors tell us that your project is **missing type declarations for non-code assets** and **your `@` alias isn't being respected by TypeScript** during `yarn build`.

## βœ… Fix 1: Support Importing `.png` and Other Assets

TypeScript doesn’t know how to handle image imports by default. You need to declare the module type.

### βž• Add `src/types/shims.d.ts` (or `globals.d.ts`)

// src/types/shims.d.ts
declare module '*.png' {
  const value: string
  export default value
}

You can also include JPEG, SVG, etc., like this:

declare module '*.jpg'
declare module '*.jpeg'
declare module '*.svg'
declare module '*.gif'

## βœ… Fix 2: Make TypeScript recognize `@` alias

Even though your `vite.config.ts` has:

resolve: {
  alias: {
    '@': fileURLToPath(new URL('./src', import.meta.url))
  }
}

…TypeScript **needs the same alias defined in `tsconfig.json`**.

### πŸ“„ `tsconfig.json` (add this if missing):

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Then **restart your editor** so it can reload the config.

## βœ… Bonus: Clean and Rebuild

After changes:

rm -rf node_modules dist .vite
yarn cache clean
yarn install
yarn build

## βœ… Summary

| Issue | Fix |
|——————————-|———————————————————|
| TS2307 for `.png` | Add a module declaration in `shims.d.ts` |
| TS2307 for `@/firebase` | Define path alias in `tsconfig.json` |
| Still failing after fix | Restart editor + clear `.vite`, `node_modules`, `dist` |

Let me know if you want me to generate a ready `shims.d.ts` file or verify your `tsconfig.json`.

Leave a Comment

Your email address will not be published. Required fields are marked *