LinkedIn feed różni się od Twittera - tutaj dzielisz się aktualizacjami zawodowymi, sukcesami i insightami branżowymi.
1type PostType = 'text' | 'article' | 'image' | 'video' | 'job_change' | 'work_anniversary';
2
3interface FeedPost {
4 id: string;
5 type: PostType;
6 author: {
7 id: string;
8 name: string;
9 avatar: string;
10 headline: string;
11 };
12 content: string;
13 media?: {
14 type: 'image' | 'video' | 'document';
15 url: string;
16 thumbnail?: string;
17 };
18 likes: number;
19 comments: number;
20 reposts: number;
21 timestamp: Date;
22
23 // Special fields for job change posts
24 jobChange?: {
25 previousCompany: string;
26 newCompany: string;
27 newPosition: string;
28 };
29}1'use client';
2
3import { useState } from 'react';
4
5function FeedPostCard({ post }: { post: FeedPost }) {
6 const [liked, setLiked] = useState(false);
7 const [showComments, setShowComments] = useState(false);
8
9 return (
10 <div className="bg-white rounded-lg shadow mb-3">
11 {/* Header */}
12 <div className="flex items-start gap-3 p-6 pb-3">
13 <img
14 src={post.author.avatar}
15 alt={post.author.name}
16 className="w-12 h-12 rounded-full"
17 />
18 <div className="flex-1">
19 <div className="flex items-start justify-between">
20 <div>
21 <h3 className="font-bold hover:underline cursor-pointer">
22 {post.author.name}
23 </h3>
24 <p className="text-sm text-gray-600">{post.author.headline}</p>
25 <p className="text-xs text-gray-500 mt-1">
26 {formatTimeAgo(post.timestamp)} • 🌍
27 </p>
28 </div>
29 <button className="text-gray-500 hover:bg-gray-100 rounded-full p-2">
30 •••
31 </button>
32 </div>
33 </div>
34 </div>
35
36 {/* Content */}
37 <div className="px-6 pb-3">
38 {/* Job Change Celebration */}
39 {post.type === 'job_change' && post.jobChange && (
40 <div className="mb-3 bg-gradient-to-r from-blue-50 to-green-50 border border-blue-200 rounded-lg p-4">
41 <p className="font-semibold mb-2">🎉 Started a new position</p>
42 <p className="text-sm text-gray-700">
43 {post.jobChange.newPosition} at {post.jobChange.newCompany}
44 </p>
45 </div>
46 )}
47
48 {/* Text Content */}
49 <p className="text-gray-900 whitespace-pre-wrap mb-3">{post.content}</p>
50
51 {/* Media */}
52 {post.media && post.media.type === 'image' && (
53 <img
54 src={post.media.url}
55 alt="Post media"
56 className="w-full rounded-lg"
57 />
58 )}
59 </div>
60
61 {/* Stats */}
62 <div className="px-6 py-2 border-t border-b flex items-center justify-between text-sm text-gray-600">
63 <button className="hover:underline">
64 {post.likes} likes
65 </button>
66 <div className="flex gap-3">
67 <button className="hover:underline">
68 {post.comments} comments
69 </button>
70 <button className="hover:underline">
71 {post.reposts} reposts
72 </button>
73 </div>
74 </div>
75
76 {/* Actions */}
77 <div className="px-6 py-2 flex items-center justify-around">
78 <button
79 onClick={() => setLiked(!liked)}
80 className={`flex items-center gap-2 px-4 py-2 rounded hover:bg-gray-100 transition ${
81 liked ? 'text-blue-600 font-semibold' : 'text-gray-600'
82 }`}
83 >
84 <span className="text-xl">{liked ? '👍' : '👍🏻'}</span>
85 Like
86 </button>
87 <button
88 onClick={() => setShowComments(!showComments)}
89 className="flex items-center gap-2 px-4 py-2 rounded hover:bg-gray-100 text-gray-600"
90 >
91 <span className="text-xl">💬</span>
92 Comment
93 </button>
94 <button className="flex items-center gap-2 px-4 py-2 rounded hover:bg-gray-100 text-gray-600">
95 <span className="text-xl">🔄</span>
96 Repost
97 </button>
98 <button className="flex items-center gap-2 px-4 py-2 rounded hover:bg-gray-100 text-gray-600">
99 <span className="text-xl">📤</span>
100 Send
101 </button>
102 </div>
103
104 {/* Comment Input */}
105 {showComments && (
106 <div className="px-6 pb-4 border-t pt-4">
107 <div className="flex gap-3">
108 <img
109 src="/current-user-avatar.jpg"
110 alt="You"
111 className="w-10 h-10 rounded-full"
112 />
113 <input
114 type="text"
115 className="flex-1 px-4 py-2 border rounded-full hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500"
116 />
117 </div>
118 </div>
119 )}
120 </div>
121 );
122}1'use client';
2
3import { useState } from 'react';
4
5export default function CreatePostModal({ onClose, onSubmit }: {
6 onClose: () => void;
7 onSubmit: (content: string) => void;
8}) {
9 const [content, setContent] = useState('');
10
11 return (
12 <div className="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4">
13 <div className="bg-white rounded-lg max-w-2xl w-full">
14 <div className="flex items-center justify-between p-4 border-b">
15 <h2 className="text-xl font-bold">Create a post</h2>
16 <button
17 onClick={onClose}
18 className="text-gray-500 hover:text-gray-700 text-2xl"
19 >
20 ✕
21 </button>
22 </div>
23
24 <div className="p-4">
25 <div className="flex gap-3 mb-4">
26 <img
27 src="/current-user-avatar.jpg"
28 alt="You"
29 className="w-12 h-12 rounded-full"
30 />
31 <div>
32 <h3 className="font-bold">Your Name</h3>
33 <button className="text-sm text-gray-600 hover:underline">
34 Post to anyone 🌍
35 </button>
36 </div>
37 </div>
38
39 <textarea
40 value={content}
41 onChange={(e) => setContent(e.target.value)}
42 className="w-full p-3 text-lg resize-none outline-none"
43 rows={8}
44 autoFocus
45 />
46
47 <div className="flex items-center gap-2 text-gray-500 mt-4">
48 <button className="p-2 hover:bg-gray-100 rounded text-xl">📷</button>
49 <button className="p-2 hover:bg-gray-100 rounded text-xl">🎬</button>
50 <button className="p-2 hover:bg-gray-100 rounded text-xl">📄</button>
51 <button className="p-2 hover:bg-gray-100 rounded text-xl">📊</button>
52 </div>
53 </div>
54
55 <div className="p-4 border-t flex justify-end">
56 <button
57 onClick={() => {
58 onSubmit(content);
59 onClose();
60 }}
61 disabled={!content.trim()}
62 className="px-6 py-2 bg-blue-600 text-white rounded-full font-bold hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed"
63 >
64 Post
65 </button>
66 </div>
67 </div>
68 </div>
69 );
70}1interface Connection {
2 id: string;
3 name: string;
4 avatar: string;
5 headline: string;
6 mutualConnections: number;
7 connectedDate: Date;
8}
9
10function ConnectionCard({ connection }: { connection: Connection }) {
11 return (
12 <div className="bg-white border rounded-lg p-4 hover:shadow-lg transition">
13 <div className="flex items-start gap-3">
14 <img
15 src={connection.avatar}
16 alt={connection.name}
17 className="w-16 h-16 rounded-full"
18 />
19 <div className="flex-1">
20 <h3 className="font-bold hover:underline cursor-pointer mb-1">
21 {connection.name}
22 </h3>
23 <p className="text-sm text-gray-600 mb-2 line-clamp-2">
24 {connection.headline}
25 </p>
26 <p className="text-xs text-gray-500">
27 {connection.mutualConnections} mutual connections
28 </p>
29 </div>
30 </div>
31
32 <div className="flex gap-2 mt-4">
33 <button className="flex-1 py-2 border-2 border-blue-600 text-blue-600 rounded-full font-semibold hover:bg-blue-50">
34 Message
35 </button>
36 <button className="px-4 py-2 border border-gray-300 rounded-full hover:bg-gray-50">
37 •••
38 </button>
39 </div>
40 </div>
41 );
42}
43
44export default function ConnectionsPage({ connections }: { connections: Connection[] }) {
45 return (
46 <div className="max-w-6xl mx-auto p-4">
47 <div className="bg-white rounded-lg shadow p-6 mb-4">
48 <h1 className="text-2xl font-bold mb-4">
49 {connections.length} Connections
50 </h1>
51 <input
52 type="text"
53 className="w-full px-4 py-2 border rounded-lg"
54 />
55 </div>
56
57 <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
58 {connections.map(conn => (
59 <ConnectionCard key={conn.id} connection={conn} />
60 ))}
61 </div>
62 </div>
63 );
64}✅ Feed post types - text, job change, article, media ✅ Feed post card - likes, comments, reposts ✅ Create post - modal with media options ✅ Job change celebration - special badge ✅ Engagement actions - like, comment, repost, send ✅ Professional tone - business-focused content ✅ Connections page - network management ✅ Connection cards - mutual connections, message button
Masz teraz kompletny LinkedIn clone z profiles, jobs i networking! 💼
Do zobaczenia! 🚀