181 lines
8.3 kB
1
defmodule BlogWeb.PostLive.Index do
2
use BlogWeb, :live_view
3
alias BlogWeb.Presence
4
alias Blog.Content
5
6
@presence_topic "blog_presence"
7
8
# TODO add meta tags
9
def mount(_params, _session, socket) do
10
if connected?(socket) do
11
reader_id = "reader_#{:crypto.strong_rand_bytes(8) |> Base.encode16()}"
12
13
{:ok, _} =
14
Presence.track(self(), @presence_topic, reader_id, %{
15
page: "index",
16
joined_at: DateTime.utc_now()
17
})
18
19
Phoenix.PubSub.subscribe(Blog.PubSub, @presence_topic)
20
end
21
22
posts = Blog.Content.Post.all()
23
%{tech: tech_posts, non_tech: non_tech_posts} = Content.categorize_posts(posts)
24
total_readers = Presence.list(@presence_topic) |> map_size()
25
26
{:ok,
27
assign(socket,
28
tech_posts: tech_posts,
29
non_tech_posts: non_tech_posts,
30
total_readers: total_readers,
31
page_title: "Tidbits & Thoughts - A Retro Hacker Blog",
32
cursor_position: nil
33
)}
34
end
35
36
def handle_info(%{event: "presence_diff"}, socket) do
37
total_readers = Presence.list(@presence_topic) |> map_size()
38
{:noreply, assign(socket, total_readers: total_readers)}
39
end
40
41
def handle_event("mousemove", %{"x" => x, "y" => y}, socket) do
42
{:noreply, assign(socket, cursor_position: %{x: x, y: y})}
43
end
44
45
def render(assigns) do
46
~H"""
47
<div
48
class="py-12 px-4 sm:px-6 lg:px-8 min-h-screen"
49
id="cursor-tracker-container"
50
phx-hook="CursorTracker"
51
>
52
<%= if @cursor_position do %>
53
<div class="fixed top-4 right-4 bg-gradient-to-r from-fuchsia-500 to-cyan-500 text-white px-3 py-1 rounded-lg shadow-md text-sm font-mono z-50">
54
x: <%= @cursor_position.x %>, y: <%= @cursor_position.y %>
55
</div>
56
<% end %>
57
<div class="max-w-7xl mx-auto">
58
<!-- Header with retro styling -->
59
<header class="mb-12 text-center">
60
<div class="inline-block p-1 bg-gradient-to-r from-fuchsia-500 to-cyan-500 rounded-lg shadow-lg mb-6">
61
<h1 class="text-4xl md:text-5xl font-bold bg-white px-6 py-3 rounded-md">
62
<span class="text-transparent bg-clip-text bg-gradient-to-r from-fuchsia-600 to-cyan-600">
63
Thoughts & Tidbits
64
</span>
65
</h1>
66
</div>
67
68
<div class="flex justify-center items-center space-x-2 text-sm text-gray-600 mb-4">
69
<div class="inline-flex items-center px-3 py-1 rounded-full bg-gradient-to-r from-fuchsia-100 to-cyan-100 border border-fuchsia-200">
70
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1 text-fuchsia-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
71
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
72
</svg>
73
<span><%= @total_readers %> <%= if @total_readers == 1, do: "person", else: "people" %> browsing</span>
74
</div>
75
</div>
76
77
<p class="text-gray-600 max-w-2xl mx-auto">
78
A collection of thoughts on technology, life, and weird little things I make.
79
</p>
80
</header>
81
82
<!-- Two column layout for posts -->
83
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
84
<!-- Tech Posts Column -->
85
<div class="bg-gradient-to-br from-fuchsia-50 to-cyan-50 rounded-xl p-6 shadow-lg border border-fuchsia-100">
86
<div class="flex items-center mb-6">
87
<div class="w-3 h-3 rounded-full bg-fuchsia-400 mr-2"></div>
88
<div class="w-3 h-3 rounded-full bg-cyan-400 mr-2"></div>
89
<div class="w-3 h-3 rounded-full bg-indigo-400 mr-4"></div>
90
<h2 class="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-fuchsia-600 to-cyan-600">
91
Tech & Programming
92
</h2>
93
</div>
94
95
<div class="space-y-4">
96
<%= for post <- @tech_posts do %>
97
<div class="group bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-all duration-300 border-l-4 border-fuchsia-400">
98
<.link navigate={~p"/post/#{post.slug}"} class="block">
99
<h3 class="text-xl font-bold text-gray-800 group-hover:text-fuchsia-600 transition-colors">
100
<%= post.title %>
101
</h3>
102
<div class="flex flex-wrap gap-2 mt-2">
103
<%= for tag <- post.tags do %>
104
<span class="inline-block px-2 py-1 bg-gradient-to-r from-fuchsia-100 to-cyan-100 rounded-full text-xs font-medium text-gray-700">
105
<%= tag.name %>
106
</span>
107
<% end %>
108
</div>
109
</.link>
110
</div>
111
<% end %>
112
</div>
113
</div>
114
115
<!-- Non-Tech Posts Column -->
116
<div class="bg-gradient-to-br from-cyan-50 to-fuchsia-50 rounded-xl p-6 shadow-lg border border-cyan-100">
117
<div class="flex items-center mb-6">
118
<div class="w-3 h-3 rounded-full bg-cyan-400 mr-2"></div>
119
<div class="w-3 h-3 rounded-full bg-fuchsia-400 mr-2"></div>
120
<div class="w-3 h-3 rounded-full bg-indigo-400 mr-4"></div>
121
<h2 class="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-cyan-600 to-fuchsia-600">
122
Life & Everything Else
123
</h2>
124
</div>
125
126
<div class="space-y-4">
127
<%= for post <- @non_tech_posts do %>
128
<div class="group bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-all duration-300 border-l-4 border-cyan-400">
129
<.link navigate={~p"/post/#{post.slug}"} class="block">
130
<h3 class="text-xl font-bold text-gray-800 group-hover:text-cyan-600 transition-colors">
131
<%= post.title %>
132
</h3>
133
<div class="flex flex-wrap gap-2 mt-2">
134
<%= for tag <- post.tags do %>
135
<span class="inline-block px-2 py-1 bg-gradient-to-r from-cyan-100 to-fuchsia-100 rounded-full text-xs font-medium text-gray-700">
136
<%= tag.name %>
137
</span>
138
<% end %>
139
</div>
140
</.link>
141
</div>
142
<% end %>
143
</div>
144
</div>
145
146
<!-- Non-Tech Posts Column -->
147
<div class="bg-gradient-to-br from-cyan-50 to-fuchsia-50 rounded-xl p-6 shadow-lg border border-cyan-100">
148
<div class="flex items-center mb-6">
149
<div class="w-3 h-3 rounded-full bg-cyan-400 mr-2"></div>
150
<div class="w-3 h-3 rounded-full bg-fuchsia-400 mr-2"></div>
151
<div class="w-3 h-3 rounded-full bg-indigo-400 mr-4"></div>
152
<h2 class="text-2xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-cyan-600 to-fuchsia-600">
153
Tech Demos
154
</h2>
155
</div>
156
157
<div class="space-y-4">
158
<%= for post <- @non_tech_posts do %>
159
<div class="group bg-white rounded-lg p-4 shadow-sm hover:shadow-md transition-all duration-300 border-l-4 border-cyan-400">
160
<.link navigate={~p"/post/#{post.slug}"} class="block">
161
<h3 class="text-xl font-bold text-gray-800 group-hover:text-cyan-600 transition-colors">
162
<%= "Reddit Links Feed" %>
163
</h3>
164
</.link>
165
</div>
166
<% end %>
167
</div>
168
</div>
169
</div>
170
</div>
171
172
<!-- Retro footer -->
173
<footer class="mt-16 text-center">
174
<div class="inline-block px-4 py-2 bg-gradient-to-r from-fuchsia-100 to-cyan-100 rounded-full text-sm text-gray-700">
175
<span class="font-mono">/* Crafted with ♥ and Elixir */</span>
176
</div>
177
</footer>
178
</div>
179
"""
180
end
181
end
182