{tweet.content}
+ )} + + {tweet.media && tweet.media.length > 0 && ( +{error}
} +diff --git a/assets/js/App.tsx b/assets/js/App.tsx
new file mode 100644
index 0000000..8d4aa8a
--- /dev/null
+++ b/assets/js/App.tsx
@@ -0,0 +1,200 @@
+import React, { useState } from "react";
+import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
+import { AuthCtx } from "./context";
+import { useIsDesktop } from "./hooks";
+import { ComposeTweet } from "./components/compose";
+import { Feed, FollowingFeed, RefreshButton } from "./components/feed";
+import { TweetDetail } from "./components/tweet-detail";
+import { UserList, UserDetail } from "./components/users";
+import { MyProfile } from "./components/profile";
+import { MobileNav, MobileComposePage } from "./components/nav";
+
+const queryClient = new QueryClient({
+ defaultOptions: { queries: { staleTime: 10_000 } },
+});
+
+export function App() {
+ const appEl = document.getElementById("app")!;
+ const email = appEl.dataset.currentUserEmail ?? "";
+ const userId = appEl.dataset.currentUserId ?? "";
+ const username = appEl.dataset.currentUserUsername ?? "";
+ const displayName = appEl.dataset.currentUserDisplayName ?? "";
+ const avatarUrl = appEl.dataset.currentUserAvatarUrl ?? "";
+ const tweetId = appEl.dataset.tweetId || null;
+ const page = appEl.dataset.page ?? "feed";
+ const profileUserId = appEl.dataset.userId || null;
+
+ const [mobileCompose, setMobileCompose] = useState(false);
+ const isDesktop = useIsDesktop();
+
+ const onFeedPage = page === "feed" || page === "tweet";
+ const onFollowingPage = page === "following";
+ const onUsersPage = page === "users" || page === "user-detail";
+ const onProfilePage = page === "profile";
+
+ function renderMain() {
+ switch (page) {
+ case "tweet":
+ return (
+ <>
+ Tweet
+ Following
+ Users
+ Profile
+ My Profile
+ Feed
+
Sign in to start mixing.
+ Sign in ++ A minimal social feed built with Ash Framework, Phoenix, and React. +
+Nothing posted yet
+Be the first to mix something in.
+Nothing here yet
++ Follow some people from the{" "} + Users + {" "}page to fill this feed. +
+Sign in to start mixing.
+ Sign in +{avatarError}
} +3–30 characters. Letters, numbers, underscores only.
+{saveError}
} + {saveSuccess &&✓ Saved!
} + +{tweet.content}
+ )} + + {tweet.media && tweet.media.length > 0 && ( +{error}
} +{comment.content}
+ {comment.media && comment.media.length > 0 &&{error}
} +{tweet.content}
+ )} + + {tweet.media && tweet.media.length > 0 && ( +{error}
} +Sign in to reply.
+No replies yet. Be the first!
+No users yet
+Be the first to sign up.
+No posts yet
+{tweet.content}
- )} - - {tweet.media && tweet.media.length > 0 && ( -{error}
} -{tweet.content}
- )} - - {tweet.media && tweet.media.length > 0 && ( -{error}
} -Sign in to reply.
-No replies yet. Be the first!
-{comment.content}
- {comment.media && comment.media.length > 0 &&{error}
} -Nothing here yet
-- Follow some people from the{" "} - Users - {" "}page to fill this feed. -
-Nothing posted yet
-Be the first to mix something in.
-No users yet
-Be the first to sign up.
-No posts yet
-{avatarError}
} -3–30 characters. Letters, numbers, underscores only.
-{saveError}
} - {saveSuccess &&✓ Saved!
} - -Sign in to start mixing.
- Sign in -Sign in to start mixing.
- Sign in -- A minimal social feed built with Ash Framework, Phoenix, and React. -
-