@tscircuit/fake-snippets 0.0.112 → 0.0.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@ export default withRouteSpec({
15
15
  ),
16
16
  auth: "optional_session",
17
17
  jsonResponse: z.object({
18
- members: z.array(accountSchema),
18
+ members: z.array(accountSchema.extend({ joined_at: z.string() })),
19
19
  }),
20
20
  })(async (req, ctx) => {
21
21
  const params = req.commonParams as { org_id?: string; name?: string }
@@ -37,13 +37,17 @@ export default withRouteSpec({
37
37
 
38
38
  const members = ctx.db.orgAccounts
39
39
  .map((m) => {
40
- if (m.org_id == org.org_id) return ctx.db.getAccount(m.account_id)
41
- return undefined
40
+ if (m.org_id !== org.org_id) return undefined
41
+ const account = ctx.db.getAccount(m.account_id)
42
+ if (!account) return undefined
43
+ return {
44
+ ...account,
45
+ joined_at: m.created_at,
46
+ }
42
47
  })
43
48
  .filter(
44
49
  (member): member is NonNullable<typeof member> => member !== undefined,
45
50
  )
46
-
47
51
  const hasOwner = members.some((m) => m?.account_id === org.owner_account_id)
48
52
  let fullMembers = members
49
53
 
@@ -52,7 +56,13 @@ export default withRouteSpec({
52
56
  (acc) => acc.account_id === org.owner_account_id,
53
57
  )
54
58
  if (owner) {
55
- fullMembers = [...members, owner]
59
+ fullMembers = [
60
+ ...members,
61
+ {
62
+ ...owner,
63
+ joined_at: org.created_at,
64
+ },
65
+ ]
56
66
  }
57
67
  }
58
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/fake-snippets",
3
- "version": "0.0.112",
3
+ "version": "0.0.113",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,16 +5,18 @@ export const GithubAvatarWithFallback = ({
5
5
  fallback,
6
6
  className,
7
7
  fallbackClassName,
8
+ size,
8
9
  }: {
9
10
  username?: string | null
10
11
  fallback?: string | null
11
12
  className?: string
12
13
  fallbackClassName?: string
14
+ size?: number
13
15
  }) => {
14
16
  return (
15
17
  <Avatar className={`border-4 border-gray-100 ${className}`}>
16
18
  <AvatarImage
17
- src={`https://github.com/${username}.png`}
19
+ src={`https://github.com/${username}.png${size ? `?size=${size}` : ""}`}
18
20
  alt={`${username || fallback} avatar`}
19
21
  className="object-cover"
20
22
  />
@@ -35,7 +35,7 @@ export const HeaderLogin = () => {
35
35
  <DropdownMenuTrigger asChild>
36
36
  <Avatar className="w-8 h-8 login-avatar">
37
37
  <AvatarImage
38
- src={`https://github.com/${session?.github_username}.png`}
38
+ src={`https://github.com/${session?.github_username}.png?size=40`}
39
39
  alt={`${session?.github_username}'s profile picture`}
40
40
  />
41
41
  <AvatarFallback aria-label="User avatar fallback">
@@ -4,15 +4,13 @@ import { OrganizationProfilePageContent } from "@/pages/organization-profile"
4
4
  import { UserProfilePage } from "@/pages/user-profile"
5
5
  import NotFoundPage from "@/pages/404"
6
6
  import { FullPageLoader } from "@/App"
7
- import { useOrgByName } from "@/hooks/use-org-by-org-name"
7
+ import { useOrganization } from "@/hooks/use-organization"
8
8
 
9
9
  const ProfileRouter: React.FC = () => {
10
10
  const { username } = useParams()
11
- const {
12
- data: organization,
13
- isLoading,
14
- error,
15
- } = useOrgByName(username || null)
11
+ const { organization, isLoading, error } = useOrganization({
12
+ orgName: username,
13
+ })
16
14
 
17
15
  if (!username) {
18
16
  return <NotFoundPage heading="Username Not Provided" />
@@ -36,7 +36,7 @@ export const UserCard: React.FC<UserCardProps> = ({
36
36
  <div className="flex items-start gap-4">
37
37
  <div className="w-16 h-16 flex-shrink-0 rounded-md overflow-hidden bg-gray-50 border flex items-center justify-center">
38
38
  <img
39
- src={`https://github.com/${account.github_username}.png`}
39
+ src={`https://github.com/${account.github_username}.png?size=69`}
40
40
  alt={`${account.github_username} avatar`}
41
41
  className="object-cover h-full w-full transition-transform duration-300 hover:scale-110"
42
42
  onError={(e) => {
@@ -1,4 +1,4 @@
1
- import { CheckCircle, XCircle, Clock, Loader2 } from "lucide-react"
1
+ import { CheckCircle, XCircle, Clock, Loader2, Hourglass } from "lucide-react"
2
2
  import { Link, useParams } from "wouter"
3
3
 
4
4
  export interface BuildStep {
@@ -28,7 +28,7 @@ export const BuildStatus = ({ step, packageReleaseId }: BuildStatusProps) => {
28
28
  <Loader2 className="h-4 w-4 text-blue-600 animate-spin dark:text-[#8b949e]" />
29
29
  )}
30
30
  {step.status === "pending" && (
31
- <Clock className="h-4 w-4 text-yellow-600 dark:text-[#8b949e]" />
31
+ <Hourglass className="h-4 w-4 text-gray-500 dark:text-[#8b949e]" />
32
32
  )}
33
33
  <span className="text-sm text-gray-500 dark:text-[#8b949e]">
34
34
  {step.name}
@@ -94,6 +94,7 @@ export const OrganizationCard: React.FC<OrganizationCardProps> = ({
94
94
  }
95
95
  fallback={organization.name}
96
96
  fallbackClassName=" font-semibold text-lg"
97
+ size={40}
97
98
  />
98
99
  </div>
99
100
 
@@ -45,6 +45,7 @@ export const OrganizationHeader: React.FC<OrganizationHeaderProps> = ({
45
45
  fallback={organization.name}
46
46
  className="shadow-sm size-16 md:size-20 lg:size-24"
47
47
  fallbackClassName="font-bold text-xl md:text-2xl lg:text-3xl"
48
+ size={300}
48
49
  />
49
50
 
50
51
  <div>
@@ -122,12 +122,13 @@ export const OrganizationMembers: React.FC<OrganizationMembersProps> = ({
122
122
  </p>
123
123
  </div>
124
124
  </div>
125
-
126
- <div className="text-right flex-shrink-0 hidden sm:block">
127
- <p className="text-xs text-gray-500">
128
- Joined {timeAgo(new Date())}
129
- </p>
130
- </div>
125
+ {member.joined_at && (
126
+ <div className="text-right flex-shrink-0 hidden sm:block">
127
+ <p className="text-xs text-gray-500">
128
+ Joined {timeAgo(new Date(member.joined_at))}
129
+ </p>
130
+ </div>
131
+ )}
131
132
  </div>
132
133
  </Link>
133
134
  ))}
@@ -62,8 +62,8 @@ export const PackageReleasesDashboard = ({
62
62
  {/* Project Header */}
63
63
  <div className="bg-gray-50 border-b md:py-10">
64
64
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
65
- <div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6">
66
- <div className="flex flex-col sm:flex-row sm:items-center gap-4">
65
+ <div className="flex flex-col md:justify-between md:flex-row lg:items-center lg:justify-between gap-6">
66
+ <div className="flex flex-col md:flex-row md:items-center gap-4">
67
67
  <div className="w-12 hidden md:block h-12 rounded-lg overflow-hidden flex-shrink-0">
68
68
  <img
69
69
  src="https://github.com/tscircuit.png"
@@ -180,7 +180,7 @@ export const PackageReleasesDashboard = ({
180
180
  <MoreHorizontal className="w-4 h-4" />
181
181
  </Button>
182
182
  </DropdownMenuTrigger>
183
- <DropdownMenuContent align="end">
183
+ <DropdownMenuContent align="end" className="ml-2">
184
184
  {pkg.github_repo_full_name && (
185
185
  <DropdownMenuItem asChild>
186
186
  <a
@@ -2,12 +2,16 @@ import { useQuery } from "react-query"
2
2
  import { useAxios } from "@/hooks/use-axios"
3
3
  import type { Account } from "fake-snippets-api/lib/db/schema"
4
4
 
5
+ interface MemberAccount extends Account {
6
+ joined_at?: string
7
+ }
8
+
5
9
  export const useListOrgMembers = ({
6
10
  orgId,
7
11
  orgName,
8
12
  }: { orgId?: string; orgName?: string }) => {
9
13
  const axios = useAxios()
10
- return useQuery<Account[], Error & { status: number }>(
14
+ return useQuery<MemberAccount[], Error & { status: number }>(
11
15
  ["orgs", "members", orgId || orgName],
12
16
  async () => {
13
17
  if (!orgId && !orgName) {
@@ -170,30 +170,32 @@ export default function ReleaseDetailPage() {
170
170
  </div>
171
171
 
172
172
  {/* Images Section - Always show with skeletons while loading */}
173
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
174
- <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
175
- {availableViews.length > 0
176
- ? availableViews.map((view) => (
177
- <div
178
- key={view.id}
179
- className="flex items-center justify-center border rounded-lg bg-gray-50 overflow-hidden h-48"
180
- >
181
- {view.isLoading ? (
182
- <Skeleton className="w-full h-full" />
183
- ) : (
184
- <img
185
- src={view.imageUrl}
186
- alt={`${view.label} preview`}
187
- className={`w-full h-full object-contain ${view.label.toLowerCase() == "pcb" ? "bg-black" : view.label.toLowerCase() == "schematic" ? "bg-[#F5F1ED]" : "bg-gray-100"}`}
188
- />
189
- )}
190
- </div>
191
- ))
192
- : [1, 2, 3].map((i) => (
193
- <Skeleton key={i} className="h-48 rounded-lg" />
194
- ))}
173
+ {Boolean(latestBuild) && (
174
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
175
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
176
+ {availableViews.length > 0
177
+ ? availableViews.map((view) => (
178
+ <div
179
+ key={view.id}
180
+ className="flex items-center justify-center border rounded-lg bg-gray-50 overflow-hidden h-48"
181
+ >
182
+ {view.isLoading ? (
183
+ <Skeleton className="w-full h-full" />
184
+ ) : (
185
+ <img
186
+ src={view.imageUrl}
187
+ alt={`${view.label} preview`}
188
+ className={`w-full h-full object-contain ${view.label.toLowerCase() == "pcb" ? "bg-black" : view.label.toLowerCase() == "schematic" ? "bg-[#F5F1ED]" : "bg-gray-100"}`}
189
+ />
190
+ )}
191
+ </div>
192
+ ))
193
+ : [1, 2, 3].map((i) => (
194
+ <Skeleton key={i} className="h-48 rounded-lg" />
195
+ ))}
196
+ </div>
195
197
  </div>
196
- </div>
198
+ )}
197
199
 
198
200
  {/* Main Content */}
199
201
  <ConnectedRepoOverview
@@ -154,7 +154,7 @@ export const UserProfilePage = () => {
154
154
  <div className="flex items-center gap-4 mb-6">
155
155
  <Avatar className="h-16 w-16">
156
156
  <AvatarImage
157
- src={`https://github.com/${githubUsername}.png`}
157
+ src={`https://github.com/${githubUsername}.png?size=300`}
158
158
  draggable={false}
159
159
  />
160
160
  <AvatarFallback className="select-none">
@@ -1,24 +0,0 @@
1
- import { useQuery } from "react-query"
2
- import { useAxios } from "@/hooks/use-axios"
3
- import type { PublicOrgSchema } from "fake-snippets-api/lib/db/schema"
4
-
5
- export const useOrgByName = (name: string | null) => {
6
- const axios = useAxios()
7
- return useQuery<PublicOrgSchema, Error & { status: number }>(
8
- ["orgs", "by-org-name", name],
9
- async () => {
10
- if (!name) {
11
- throw new Error("Organisation name is required")
12
- }
13
- const { data } = await axios.get("/orgs/get", {
14
- params: { org_name: name },
15
- })
16
- return data.org
17
- },
18
- {
19
- enabled: Boolean(name),
20
- retry: false,
21
- refetchOnWindowFocus: false,
22
- },
23
- )
24
- }