import { useState, useEffect, useCallback } from 'react'
import { NextPage, GetServerSideProps } from 'next'
import { useRouter } from 'next/router'
import { prisma } from '../lib/prisma'
import { debounce } from 'lodash'

interface User {
  id: string
  name: string
  email: string
  avatar?: string
  role: 'admin' | 'user'
  isActive: boolean
  createdAt: Date
  updatedAt: Date
}
const fetchUsers = useCallback(async (page: number = 1, search: string = '') => {
    try {
      setLoading(true)
      setError(null)
      
      const queryParams = new URLSearchParams({
        page: page.toString(),
        limit: '20',
        ...search && { search: search }
      })
      
      const response = await fetch(`/api/users?${queryParams}`)
      
      if (!response.ok) {
        const errorData = await response.json()
        throw new Error(errorData.message || 'Failed to fetch users')
      }
      
      const { users: fetchedUsers, total } = await response.json()
      setUsers(fetchedUsers)
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  {users.map((user) => (
    <div
      key={user.id}
      onClick={() => handleUserClick(user.id)}
      className="bg-white rounded-lg shadow-md p-6 cursor-pointer hover:shadow-lg transition-shadow"
    >
      <div className="flex items-center space-x-4">
        {user.avatar && (
          <img
            src={user.avatar}
            alt="User avatar"
            className="w-12 h-12 rounded-full object-cover"
          />
        )}
        <div>
          <h2 className="text-xl font-semibold text-gray-900">{user.name}</h2>
          <p className="text-gray-600">{user.email}</p>
          <span className=`inline-block px-2 py-1 text-xs rounded ${user.role === 'admin' ? 'bg-red-100 text-red-800' : 'bg-blue-100 text-blue-800'}`>
            {user.role}
          </span>
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<User[] | { error: string }>
) {
  const { method, query } = req
  const { page = '1', limit = '20', search = '' } = query
  
  const pageNumber = parseInt(page as string, 10)
  const limitNumber = parseInt(limit as string, 10)
  const offset = (pageNumber - 1) * limitNumber

  if (method === 'GET') {
    try {
      const whereClause = search ? {
        OR: [
          { name: { contains: search as string, mode: 'insensitive' } },
          { email: { contains: search as string, mode: 'insensitive' } }
        ]
      } : {}
個人開発者

SHIBAYAMA HIROKI

Former Engineer & AI-Driven

最新のAIテクノロジーと共に、

革新的なWebサービス、アプリを作成します。

View My Work

About Me

私は個人開発者として、フロントエンドからバックエンドまで幅広い技術領域で開発を行っています。 特にNext.js, React、Node.jsを使用したモダンなWebアプリケーション開発を得意としています。

Skills

Next.js React Rails AWS Security

AI

Claude Code Devin Volt.new

Projects

🚧

プロジェクトを準備中です

新しいプロジェクトを開発中です。近日公開予定です。

Blog

✍️

記事を執筆中です

新しい技術記事を準備中です。しばらくお待ちください。

Contact