Skip to content

レポート2 #20

@kmc2629

Description

@kmc2629

import React, { useState } from "react";

// ダミーデータ
const initialPosts = [
{
id: 1,
name: "あい",
grade: "一年",
sp: "SONY",
birthday: "01-15",
mbti: "INTJ",
tags: ["静か", "分析好き"],
image: "https://via.placeholder.com/300",
updatedAt: Date.now()
}
];

export default function App() {
const [posts, setPosts] = useState(initialPosts);
const [search, setSearch] = useState("");
const [sort, setSort] = useState("name");

const filtered = posts
.filter(p =>
p.name.includes(search) ||
p.tags.some(tag => tag.includes(search))
)
.sort((a, b) => {
if (sort === "name") return a.name.localeCompare(b.name, "ja");
if (sort === "birthday") return a.birthday.localeCompare(b.birthday);
if (sort === "updated") return b.updatedAt - a.updatedAt;
return 0;
});

return (


画像投稿アプリ

  {/* 検索・ソート */}
  <div className="flex gap-2 mb-4">
    <input
      className="border rounded-2xl p-2 flex-1"
      placeholder="名前・タグ検索"
      value={search}
      onChange={e => setSearch(e.target.value)}
    />
    <select
      className="border rounded-2xl p-2"
      value={sort}
      onChange={e => setSort(e.target.value)}
    >
      <option value="name">名前順</option>
      <option value="birthday">誕生日順</option>
      <option value="updated">更新順</option>
    </select>
  </div>

  {/* 投稿一覧 */}
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
    {filtered.map(post => (
      <PostCard key={post.id} post={post} setPosts={setPosts} posts={posts} />
    ))}
  </div>
</div>

);
}

function PostCard({ post, posts, setPosts }) {
const [newTag, setNewTag] = useState("");

const addTag = () => {
if (!newTag || post.tags.length >= 10) return;
const updated = posts.map(p =>
p.id === post.id
? { ...p, tags: [...p.tags, newTag], updatedAt: Date.now() }
: p
);
setPosts(updated);
setNewTag("");
};

return (


{/* 名前 */}

{post.name}

  {/* タグ */}
  <div className="flex flex-wrap gap-2 my-2">
    {[post.grade, post.sp, post.birthday, post.mbti, ...post.tags].map((tag, i) => (
      <span key={i} className="text-sm border px-2 py-1 rounded-full">
        #{tag}
      </span>
    ))}
  </div>

  {/* 画像 */}
  <img src={post.image} alt="" className="rounded-xl w-full" />

  {/* タグ追加 */}
  <div className="flex gap-2 mt-2">
    <input
      className="border rounded-2xl p-1 flex-1"
      value={newTag}
      onChange={e => setNewTag(e.target.value)}
      placeholder="タグ追加"
    />
    <button
      className="bg-black text-white px-3 rounded-2xl"
      onClick={addTag}
    >
      追加
    </button>
  </div>
</div>

);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions