+5
assets/css/app.css
+5
assets/css/app.css
···
23
23
[data-phx-session], [data-phx-teleported-src] { display: contents }
24
24
25
25
/* This file is for your main application CSS */
26
+
@theme {
27
+
--color-brand-light: #ffa34e;
28
+
--color-brand-dark: #ff4400;
29
+
--font-sans: "Work Sans Variable", ui-sans-serif, system-ui, sans-serif;
30
+
}
+1
assets/js/app.js
+1
assets/js/app.js
···
19
19
20
20
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
21
21
import "phoenix_html"
22
+
import "@fontsource-variable/work-sans"
22
23
// Establish Phoenix Socket and LiveView configuration.
23
24
import {Socket} from "phoenix"
24
25
import {LiveSocket} from "phoenix_live_view"
+6
-2
config/config.exs
+6
-2
config/config.exs
···
36
36
version: "0.25.4",
37
37
comet: [
38
38
args:
39
-
~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
39
+
~w(js/app.js --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --loader:.woff2=file --alias:@=.),
40
40
cd: Path.expand("../assets", __DIR__),
41
41
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
42
42
]
···
52
52
cd: Path.expand("..", __DIR__)
53
53
],
54
54
version_check: false,
55
-
path: System.get_env("TAILWINDCSS_PATH", Path.expand("../assets/node_modules/.bin/tailwindcss", __DIR__))
55
+
path:
56
+
System.get_env(
57
+
"TAILWINDCSS_PATH",
58
+
Path.expand("../assets/node_modules/.bin/tailwindcss", __DIR__)
59
+
)
56
60
57
61
# Configure Elixir's Logger
58
62
config :logger, :default_formatter,
-16
lib/comet_app/components/post_preview.ex
-16
lib/comet_app/components/post_preview.ex
···
1
-
defmodule CometApp.Components.PostPreview do
2
-
use Hologram.Component
3
-
alias Hologram.UI.Link
4
-
5
-
prop :post, :map
6
-
7
-
def template do
8
-
~HOLO"""
9
-
<article class="post-preview">
10
-
<h2>{@post.title}</h2>
11
-
<p>{@post.excerpt}</p>
12
-
<Link to={CometApp.PostPage, id: @post.id}>Read more</Link>
13
-
</article>
14
-
"""
15
-
end
16
-
end
+11
lib/comet_app/components/title.ex
+11
lib/comet_app/components/title.ex
+22
-1
lib/comet_app/layouts/main.ex
+22
-1
lib/comet_app/layouts/main.ex
···
1
1
defmodule CometApp.MainLayout do
2
2
use Hologram.Component
3
3
4
-
alias Hologram.UI.Link
4
+
alias CometApp.Components.Title
5
5
alias Hologram.UI.Runtime
6
+
7
+
prop :page_title, :string, default: nil
8
+
9
+
def template do
10
+
~HOLO"""
11
+
<!DOCTYPE html>
12
+
<html lang="en">
13
+
<head>
14
+
<meta charset="utf-8" />
15
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
16
+
<link rel="stylesheet" href="/assets/js/app.css" />
17
+
<link rel="stylesheet" href="/assets/css/app.css" />
18
+
<Title text={@page_title} />
19
+
<Runtime />
20
+
</head>
21
+
<body class="from-amber-900 bg-linear-to-tl to-stone-950 to-80% bg-fixed text-white p-10 w-screen h-screen flex justify-center flex-col">
22
+
<slot/>
23
+
</body>
24
+
</html>
25
+
"""
26
+
end
6
27
end
-18
lib/comet_app/layouts/main.holo
-18
lib/comet_app/layouts/main.holo
···
1
-
<!DOCTYPE html>
2
-
<html lang="en">
3
-
<head>
4
-
<meta charset="utf-8" />
5
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
6
-
<title>Comet App</title>
7
-
<link phx-track-static rel="stylesheet" href="/assets/css/app.css" />
8
-
<Runtime />
9
-
</head>
10
-
<body>
11
-
<nav class="bg-red-500 text-2xl">
12
-
<Link to={CometApp.HomePage}>Home</Link>
13
-
</nav>
14
-
<main>
15
-
<slot />
16
-
</main>
17
-
</body>
18
-
</html>
+15
-17
lib/comet_app/pages/home.ex
+15
-17
lib/comet_app/pages/home.ex
···
1
1
defmodule CometApp.HomePage do
2
2
use Hologram.Page
3
-
alias CometApp.Components.PostPreview
4
3
5
4
route "/"
6
5
7
-
layout CometApp.MainLayout
6
+
layout CometApp.MainLayout, page_title: "Home"
8
7
9
-
def init(_params, component, _server) do
10
-
# In real app, fetch from database
11
-
posts = [
12
-
%{id: 1, title: "First Post", excerpt: "This is my first post"},
13
-
%{id: 2, title: "Second Post", excerpt: nil}
14
-
]
8
+
# def init(_params, component, _server) do
9
+
# # In real app, fetch from database
10
+
# posts = [
11
+
# %{id: 1, title: "First Post", excerpt: "This is my first post"},
12
+
# %{id: 2, title: "Second Post", excerpt: nil}
13
+
# ]
15
14
16
-
put_state(component, :posts, posts)
17
-
end
15
+
# put_state(component, :posts, posts)
16
+
# end
18
17
19
18
def template do
20
19
~HOLO"""
21
-
<h1>Welcome to my Blog</h1>
22
-
23
-
<div class="posts">
24
-
{%for post <- @posts}
25
-
<PostPreview post={post} />
26
-
{/for}
27
-
</div>
20
+
<h1 class="italic text-9xl tracking-tighter leading-30 mb-10 font-thin">
21
+
<span class="font-medium">Comet</span> is the next-generation of music streaming.
22
+
</h1>
23
+
<p class="text-2xl font-light">
24
+
Powered by the AT Protocol, we're putting the power back in the hands of musicians.
25
+
</p>
28
26
"""
29
27
end
30
28
end
-48
lib/comet_app/pages/post_view.ex
-48
lib/comet_app/pages/post_view.ex
···
1
-
defmodule CometApp.PostPage do
2
-
use Hologram.Page
3
-
4
-
route "/posts/:id"
5
-
6
-
param :id, :integer
7
-
8
-
layout CometApp.MainLayout
9
-
10
-
def init(params, component, _server) do
11
-
# In real app, fetch from database
12
-
post = %{
13
-
id: params.id,
14
-
title: "Example Post",
15
-
content: "This is the full content...",
16
-
likes: 0
17
-
}
18
-
19
-
put_state(component, :post, post)
20
-
end
21
-
22
-
def template do
23
-
~HOLO"""
24
-
<article>
25
-
<h1>{@post.title}</h1>
26
-
<p>{@post.content}</p>
27
-
28
-
<div class="likes">
29
-
Likes: {@post.likes}
30
-
<button $click="like_post">Like</button>
31
-
</div>
32
-
</article>
33
-
"""
34
-
end
35
-
36
-
def action(:like_post, _params, component) do
37
-
# Update likes locally first for instant feedback
38
-
component
39
-
|> put_state([:post, :likes], component.state.post.likes + 1)
40
-
|> put_command(:save_like, post_id: component.state.post.id)
41
-
end
42
-
43
-
def command(:save_like, params, server) do
44
-
# In real app, save to database
45
-
IO.puts("Liked post #{params.post_id}")
46
-
server
47
-
end
48
-
end
+1
lib/comet_web/components/layouts/root.html.heex
+1
lib/comet_web/components/layouts/root.html.heex
···
7
7
<.live_title default="Comet" suffix=" · Phoenix Framework">
8
8
{assigns[:page_title]}
9
9
</.live_title>
10
+
<link phx-track-static rel="stylesheet" href={~p"/assets/js/app.css"} />
10
11
<link phx-track-static rel="stylesheet" href={~p"/assets/css/app.css"} />
11
12
<script defer phx-track-static type="text/javascript" src={~p"/assets/js/app.js"}>
12
13
</script>
+4
-1
package.json
+4
-1
package.json
+9
pnpm-lock.yaml
+9
pnpm-lock.yaml
···
7
7
importers:
8
8
9
9
.:
10
+
dependencies:
11
+
'@fontsource-variable/work-sans':
12
+
specifier: ^5.2.8
13
+
version: 5.2.8
10
14
devDependencies:
11
15
'@tailwindcss/cli':
12
16
specifier: ^4.1.17
···
25
29
version: 5.9.3
26
30
27
31
packages:
32
+
33
+
'@fontsource-variable/work-sans@5.2.8':
34
+
resolution: {integrity: sha512-8uWtTt0/B5NxGie9xUVD5y5Ch4Q+Hy7kFYKtUpwYbzSAgJEoaMxT8rMnfnK7zfAYSLC8GnGO1/tXrFtKIYYQVQ==}
28
35
29
36
'@jridgewell/gen-mapping@0.3.13':
30
37
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
···
431
438
hasBin: true
432
439
433
440
snapshots:
441
+
442
+
'@fontsource-variable/work-sans@5.2.8': {}
434
443
435
444
'@jridgewell/gen-mapping@0.3.13':
436
445
dependencies: