create-fate 1.3.3 → 1.5.0
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.
- package/bin/create-fate.mjs +41 -3
- package/package.json +1 -1
- package/templates/fate/_shared/vue-app/package.json +14 -16
- package/templates/fate/cloudflare/README.md +11 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/browserslist +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/esbuild +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/fate +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/fbtee +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/intent +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/jiti +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/oxlint +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/rolldown +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/tsc +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/tsx +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/vitest +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/void +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/vp +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/vpr +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/workerd +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/wrangler +22 -0
- package/templates/fate/cloudflare/client/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/cloudflare/client/package.json +26 -21
- package/templates/fate/cloudflare/client/pages/layout.tsx +2 -16
- package/templates/fate/cloudflare/client/src/lib/AvailableLanguages.tsx +3 -3
- package/templates/fate/cloudflare/client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/cloudflare/client/src/ui/LocaleSwitcher.tsx +26 -44
- package/templates/fate/cloudflare/client/start.mjs +11 -0
- package/templates/fate/cloudflare/client/translations/{de_DE.json → de-DE.json} +56 -113
- package/templates/fate/{graphql/client/translations/ja_JP.json → cloudflare/client/translations/ja-JP.json} +56 -113
- package/templates/fate/cloudflare/client/vite.config.ts +4 -8
- package/templates/fate/cloudflare/package.json +6 -10
- package/templates/fate/cloudflare/pnpm-workspace.yaml +4 -4
- package/templates/fate/cloudflare/server/db/migrations/20260508073357_initial_schema.sql +3 -2
- package/templates/fate/cloudflare/server/db/migrations/20260508120500_seed_cloudflare_demo.sql +10 -10
- package/templates/fate/cloudflare/server/db/migrations/meta/20260508073357_snapshot.json +10 -3
- package/templates/fate/cloudflare/server/db/schema.ts +2 -3
- package/templates/fate/cloudflare/server/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/esbuild +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/fate +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/intent +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/jiti +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/oxlint +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/tsc +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/tsx +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/vitest +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/vp +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/vpr +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/workerd +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/wrangler +22 -0
- package/templates/fate/cloudflare/server/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/cloudflare/server/package.json +3 -3
- package/templates/fate/cloudflare/server/src/fate/server.ts +5 -2
- package/templates/fate/cloudflare/server/src/lib/auth.ts +0 -2
- package/templates/fate/cloudflare/server/tsconfig.json +1 -1
- package/templates/fate/cloudflare/tsconfig.json +2 -11
- package/templates/fate/cloudflare/vite.config.ts +3 -0
- package/templates/fate/drizzle/README.md +11 -0
- package/templates/fate/drizzle/client/node_modules/.bin/browserslist +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/esbuild +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/fate +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/fbtee +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/intent +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/jiti +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/oxlint +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/rolldown +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/tsc +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/tsx +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/vitest +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/void +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/vp +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/vpr +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/workerd +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/wrangler +22 -0
- package/templates/fate/drizzle/client/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/drizzle/client/package.json +28 -24
- package/templates/fate/drizzle/client/pages/layout.tsx +2 -16
- package/templates/fate/drizzle/client/src/lib/AvailableLanguages.tsx +3 -3
- package/templates/fate/drizzle/client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/drizzle/client/src/ui/LocaleSwitcher.tsx +26 -44
- package/templates/fate/drizzle/client/start.mjs +11 -0
- package/templates/fate/{graphql/client/translations/de_DE.json → drizzle/client/translations/de-DE.json} +56 -113
- package/templates/fate/{cloudflare/client/translations/ja_JP.json → drizzle/client/translations/ja-JP.json} +56 -113
- package/templates/fate/drizzle/client/vite.config.ts +4 -8
- package/templates/fate/drizzle/package.json +6 -10
- package/templates/fate/drizzle/pnpm-workspace.yaml +4 -4
- package/templates/fate/drizzle/server/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/esbuild +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/fate +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/intent +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/jiti +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/nodemon +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/oxlint +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/tsc +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/tsx +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/vitest +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/vp +22 -0
- package/templates/fate/drizzle/server/node_modules/.bin/vpr +22 -0
- package/templates/fate/drizzle/server/package.json +9 -9
- package/templates/fate/drizzle/server/src/app.tsx +1 -1
- package/templates/fate/drizzle/server/src/drizzle/schema.ts +2 -3
- package/templates/fate/drizzle/server/src/drizzle/seed.tsx +1 -1
- package/templates/fate/drizzle/tsconfig.json +1 -10
- package/templates/fate/graphql/README.md +11 -0
- package/templates/fate/graphql/client/node_modules/.bin/browserslist +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/esbuild +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/fate +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/fbtee +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/intent +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/jiti +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/oxlint +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/rolldown +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/tsc +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/tsx +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/vitest +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/void +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/vp +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/vpr +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/workerd +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/wrangler +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/graphql/client/node_modules/.bin/yaml +22 -0
- package/templates/fate/graphql/client/package.json +27 -23
- package/templates/fate/graphql/client/pages/layout.tsx +2 -16
- package/templates/fate/graphql/client/src/lib/AvailableLanguages.tsx +3 -3
- package/templates/fate/graphql/client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/graphql/client/src/ui/LocaleSwitcher.tsx +26 -44
- package/templates/fate/graphql/client/src/ui/PostCard.tsx +1 -1
- package/templates/fate/graphql/client/start.mjs +11 -0
- package/templates/fate/{drizzle/client/translations/de_DE.json → graphql/client/translations/de-DE.json} +56 -113
- package/templates/fate/{http/client/translations/ja_JP.json → graphql/client/translations/ja-JP.json} +56 -113
- package/templates/fate/graphql/client/vite.config.ts +4 -8
- package/templates/fate/graphql/package.json +7 -11
- package/templates/fate/graphql/pnpm-workspace.yaml +4 -4
- package/templates/fate/graphql/server/package.json +25 -29
- package/templates/fate/graphql/server/prisma.config.ts +9 -1
- package/templates/fate/graphql/server/scripts/generate-graphql.tsx +1 -1
- package/templates/fate/graphql/server/src/index.tsx +1 -1
- package/templates/fate/graphql/server/src/prisma/schema.prisma +2 -1
- package/templates/fate/graphql/server/src/prisma/seed.tsx +1 -1
- package/templates/fate/graphql/server/tsconfig.json +1 -11
- package/templates/fate/graphql/tsconfig.json +1 -10
- package/templates/fate/graphql-client/README.md +9 -0
- package/templates/fate/graphql-client/_gitignore +3 -0
- package/templates/fate/graphql-client/package.json +27 -24
- package/templates/fate/graphql-client/pages/index.tsx +61 -27
- package/templates/fate/graphql-client/pages/layout.tsx +22 -15
- package/templates/fate/graphql-client/pnpm-workspace.yaml +6 -4
- package/templates/fate/graphql-client/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/graphql-client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/graphql-client/src/ui/LocaleSwitcher.tsx +34 -0
- package/templates/fate/graphql-client/translations/de-DE.json +225 -0
- package/templates/fate/graphql-client/translations/ja-JP.json +225 -0
- package/templates/fate/graphql-client/vite.config.ts +9 -13
- package/templates/fate/http/README.md +11 -0
- package/templates/fate/http/client/node_modules/.bin/browserslist +22 -0
- package/templates/fate/http/client/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/http/client/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/http/client/node_modules/.bin/esbuild +22 -0
- package/templates/fate/http/client/node_modules/.bin/fate +22 -0
- package/templates/fate/http/client/node_modules/.bin/fbtee +22 -0
- package/templates/fate/http/client/node_modules/.bin/intent +22 -0
- package/templates/fate/http/client/node_modules/.bin/jiti +22 -0
- package/templates/fate/http/client/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/http/client/node_modules/.bin/oxlint +22 -0
- package/templates/fate/http/client/node_modules/.bin/rolldown +22 -0
- package/templates/fate/http/client/node_modules/.bin/tsc +22 -0
- package/templates/fate/http/client/node_modules/.bin/tsx +22 -0
- package/templates/fate/http/client/node_modules/.bin/vitest +22 -0
- package/templates/fate/http/client/node_modules/.bin/void +22 -0
- package/templates/fate/http/client/node_modules/.bin/vp +22 -0
- package/templates/fate/http/client/node_modules/.bin/vpr +22 -0
- package/templates/fate/http/client/node_modules/.bin/workerd +22 -0
- package/templates/fate/http/client/node_modules/.bin/wrangler +22 -0
- package/templates/fate/http/client/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/http/client/package.json +26 -22
- package/templates/fate/http/client/pages/layout.tsx +2 -16
- package/templates/fate/http/client/src/lib/AvailableLanguages.tsx +3 -3
- package/templates/fate/http/client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/http/client/src/ui/LocaleSwitcher.tsx +26 -44
- package/templates/fate/http/client/start.mjs +11 -0
- package/templates/fate/http/client/translations/{de_DE.json → de-DE.json} +56 -113
- package/templates/fate/{drizzle/client/translations/ja_JP.json → http/client/translations/ja-JP.json} +56 -113
- package/templates/fate/http/client/vite.config.ts +4 -8
- package/templates/fate/http/package.json +6 -10
- package/templates/fate/http/pnpm-workspace.yaml +4 -4
- package/templates/fate/http/server/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/http/server/node_modules/.bin/esbuild +22 -0
- package/templates/fate/http/server/node_modules/.bin/fate +22 -0
- package/templates/fate/http/server/node_modules/.bin/intent +22 -0
- package/templates/fate/http/server/node_modules/.bin/jiti +22 -0
- package/templates/fate/http/server/node_modules/.bin/nodemon +22 -0
- package/templates/fate/http/server/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/http/server/node_modules/.bin/oxlint +22 -0
- package/templates/fate/http/server/node_modules/.bin/tsc +22 -0
- package/templates/fate/http/server/node_modules/.bin/tsx +22 -0
- package/templates/fate/http/server/node_modules/.bin/vitest +22 -0
- package/templates/fate/http/server/node_modules/.bin/vp +22 -0
- package/templates/fate/http/server/node_modules/.bin/vpr +22 -0
- package/templates/fate/http/server/package.json +8 -8
- package/templates/fate/http/server/src/app.tsx +1 -1
- package/templates/fate/http/server/src/drizzle/schema.ts +2 -3
- package/templates/fate/http/server/src/drizzle/seed.tsx +1 -1
- package/templates/fate/http/tsconfig.json +1 -10
- package/templates/fate/prisma/README.md +11 -0
- package/templates/fate/prisma/client/node_modules/.bin/browserslist +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/cf-wrangler +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/drizzle-kit +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/esbuild +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/fate +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/fbtee +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/intent +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/jiti +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/oxlint +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/rolldown +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/tsc +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/tsx +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/vitest +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/void +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/vp +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/vpr +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/workerd +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/wrangler +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/wrangler2 +22 -0
- package/templates/fate/prisma/client/node_modules/.bin/yaml +22 -0
- package/templates/fate/prisma/client/package.json +28 -24
- package/templates/fate/prisma/client/pages/layout.tsx +2 -16
- package/templates/fate/prisma/client/src/lib/AvailableLanguages.tsx +3 -3
- package/templates/fate/prisma/client/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/prisma/client/src/ui/LocaleSwitcher.tsx +26 -44
- package/templates/fate/prisma/client/start.mjs +11 -0
- package/templates/fate/prisma/client/translations/de-DE.json +632 -0
- package/templates/fate/prisma/client/translations/ja-JP.json +632 -0
- package/templates/fate/prisma/client/vite.config.ts +4 -8
- package/templates/fate/prisma/package.json +7 -11
- package/templates/fate/prisma/pnpm-workspace.yaml +4 -4
- package/templates/fate/prisma/server/node_modules/.bin/esbuild +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/fate +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/intent +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/jiti +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/nft +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/nodemon +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/oxfmt +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/oxlint +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/prisma +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/tsc +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/tsx +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/vitest +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/vp +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/vpr +22 -0
- package/templates/fate/prisma/server/node_modules/.bin/yaml +22 -0
- package/templates/fate/prisma/server/package.json +9 -9
- package/templates/fate/prisma/server/prisma.config.ts +2 -1
- package/templates/fate/prisma/server/src/app.tsx +1 -1
- package/templates/fate/prisma/server/src/prisma/schema.prisma +2 -1
- package/templates/fate/prisma/server/src/prisma/seed.tsx +1 -1
- package/templates/fate/prisma/tsconfig.json +1 -10
- package/templates/fate/void/README.md +9 -0
- package/templates/fate/void/_gitignore +3 -0
- package/templates/fate/void/db/migrations/20260508073357_initial_schema.sql +3 -2
- package/templates/fate/void/db/migrations/20260508120500_seed_void_demo.sql +10 -10
- package/templates/fate/void/db/migrations/meta/20260508073357_snapshot.json +10 -3
- package/templates/fate/void/db/schema.ts +2 -3
- package/templates/fate/void/middleware/01.shared.ts +3 -0
- package/templates/fate/void/package.json +30 -25
- package/templates/fate/void/pages/index.tsx +23 -10
- package/templates/fate/void/pages/layout.tsx +22 -19
- package/templates/fate/void/pages/login.tsx +22 -18
- package/templates/fate/void/pages/search.tsx +18 -4
- package/templates/fate/void/pnpm-workspace.yaml +4 -4
- package/templates/fate/void/src/fate/server.ts +2 -1
- package/templates/fate/void/src/lib/AvailableLanguages.tsx +5 -0
- package/templates/fate/void/src/lib/LocaleContext.tsx +61 -0
- package/templates/fate/void/src/ui/CategoryCard.tsx +22 -4
- package/templates/fate/void/src/ui/CreatePost.tsx +12 -7
- package/templates/fate/void/src/ui/Error.tsx +4 -2
- package/templates/fate/void/src/ui/EventCard.tsx +18 -5
- package/templates/fate/void/src/ui/Header.tsx +10 -4
- package/templates/fate/void/src/ui/LocaleSwitcher.tsx +34 -0
- package/templates/fate/void/src/ui/PostCard.tsx +29 -14
- package/templates/fate/void/src/ui/UserCard.tsx +15 -8
- package/templates/fate/void/translations/de-DE.json +863 -0
- package/templates/fate/void/translations/ja-JP.json +863 -0
- package/templates/fate/void/vite.config.ts +6 -6
- package/templates/fate/prisma/client/translations/de_DE.json +0 -689
- package/templates/fate/prisma/client/translations/ja_JP.json +0 -689
|
@@ -50,6 +50,13 @@
|
|
|
50
50
|
"notNull": false,
|
|
51
51
|
"autoincrement": false
|
|
52
52
|
},
|
|
53
|
+
"issuer": {
|
|
54
|
+
"name": "issuer",
|
|
55
|
+
"type": "text",
|
|
56
|
+
"primaryKey": false,
|
|
57
|
+
"notNull": true,
|
|
58
|
+
"autoincrement": false
|
|
59
|
+
},
|
|
53
60
|
"password": {
|
|
54
61
|
"name": "password",
|
|
55
62
|
"type": "text",
|
|
@@ -102,9 +109,9 @@
|
|
|
102
109
|
}
|
|
103
110
|
},
|
|
104
111
|
"indexes": {
|
|
105
|
-
"
|
|
106
|
-
"name": "
|
|
107
|
-
"columns": ["
|
|
112
|
+
"account_issuer_accountId_key": {
|
|
113
|
+
"name": "account_issuer_accountId_key",
|
|
114
|
+
"columns": ["issuer", "accountId"],
|
|
108
115
|
"isUnique": true
|
|
109
116
|
}
|
|
110
117
|
},
|
|
@@ -67,6 +67,7 @@ export const account = sqliteTable(
|
|
|
67
67
|
createdAt: timestampColumn(),
|
|
68
68
|
id: idColumn().primaryKey(),
|
|
69
69
|
idToken: text(),
|
|
70
|
+
issuer: text().notNull(),
|
|
70
71
|
password: text(),
|
|
71
72
|
providerId: text().notNull(),
|
|
72
73
|
refreshToken: text(),
|
|
@@ -77,9 +78,7 @@ export const account = sqliteTable(
|
|
|
77
78
|
.notNull()
|
|
78
79
|
.references(() => user.id, { onDelete: 'cascade' }),
|
|
79
80
|
},
|
|
80
|
-
(table) => [
|
|
81
|
-
uniqueIndex('account_providerId_accountId_key').on(table.providerId, table.accountId),
|
|
82
|
-
],
|
|
81
|
+
(table) => [uniqueIndex('account_issuer_accountId_key').on(table.issuer, table.accountId)],
|
|
83
82
|
);
|
|
84
83
|
|
|
85
84
|
export const category = sqliteTable(
|
|
@@ -10,13 +10,17 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "vp build",
|
|
13
|
+
"build": "vp run fbtee:all && vp build",
|
|
14
14
|
"db:generate": "void db generate",
|
|
15
15
|
"db:migrate": "void db migrate",
|
|
16
16
|
"db:seed": "void db seed --file db/seed.ts",
|
|
17
17
|
"dev": "vp dev",
|
|
18
|
-
"dev:setup": "vp run prepare:void && vp run db:seed && vp run fate:generate",
|
|
18
|
+
"dev:setup": "vp run fbtee:all && vp run prepare:void && vp run db:seed && vp run fate:generate",
|
|
19
19
|
"fate:generate": "vp exec fate generate",
|
|
20
|
+
"fbtee:all": "vp run fbtee:collect && vp run fbtee:translate",
|
|
21
|
+
"fbtee:collect": "vp exec fbtee collect",
|
|
22
|
+
"fbtee:prepare": "vp run fbtee:collect && vp exec fbtee prepare-translations --source-strings source_strings.json --output-dir translations --locales de-DE ja-JP",
|
|
23
|
+
"fbtee:translate": "vp exec fbtee translate --source-strings source_strings.json --output-dir src/translations --output-locale-style=bcp47",
|
|
20
24
|
"prepare:void": "void prepare",
|
|
21
25
|
"test:all": "vp check && vp test"
|
|
22
26
|
},
|
|
@@ -24,38 +28,39 @@
|
|
|
24
28
|
"@nkzw/core": "^1.3.1",
|
|
25
29
|
"@nkzw/fate": "latest",
|
|
26
30
|
"@nkzw/stack": "^2.3.2",
|
|
27
|
-
"@radix-ui/react-slot": "^1.
|
|
28
|
-
"@void/react": "^0.
|
|
29
|
-
"better-auth": "
|
|
31
|
+
"@radix-ui/react-slot": "^1.3.3",
|
|
32
|
+
"@void/react": "^0.10.12",
|
|
33
|
+
"better-auth": "1.7.2",
|
|
30
34
|
"class-variance-authority": "^0.7.1",
|
|
31
35
|
"clsx": "^2.1.1",
|
|
32
36
|
"drizzle-orm": "^0.45.2",
|
|
33
|
-
"
|
|
34
|
-
"react": "^
|
|
35
|
-
"react
|
|
36
|
-
"react-
|
|
37
|
+
"fbtee": "^4.0.0",
|
|
38
|
+
"lucide-react": "^1.34.0",
|
|
39
|
+
"react": "^19.2.8",
|
|
40
|
+
"react-dom": "^19.2.8",
|
|
41
|
+
"react-error-boundary": "^6.1.3",
|
|
37
42
|
"react-fate": "latest",
|
|
38
|
-
"tailwind-merge": "^3.
|
|
39
|
-
"void": "^0.
|
|
43
|
+
"tailwind-merge": "^3.6.0",
|
|
44
|
+
"void": "^0.10.12",
|
|
40
45
|
"void-fate": "latest",
|
|
41
46
|
"zod": "^4.4.3"
|
|
42
47
|
},
|
|
43
48
|
"devDependencies": {
|
|
49
|
+
"@cloudflare/workers-types": "4.20260702.1",
|
|
44
50
|
"@nkzw/eslint-plugin": "^2.0.0",
|
|
45
|
-
"@nkzw/
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@types/
|
|
51
|
-
"@
|
|
52
|
-
"@
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"ts-node": "^10.9.2",
|
|
51
|
+
"@nkzw/fbtee-cli": "^4.0.0",
|
|
52
|
+
"@nkzw/oxlint-config": "^2.0.1",
|
|
53
|
+
"@nkzw/vite-plugin-fbtee": "^4.0.0",
|
|
54
|
+
"@oxc-node/core": "^0.1.0",
|
|
55
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
56
|
+
"@types/node": "^26.4.0",
|
|
57
|
+
"@types/react": "^19.2.18",
|
|
58
|
+
"@types/react-dom": "^19.2.5",
|
|
59
|
+
"@vitejs/plugin-react": "^6.1.0",
|
|
60
|
+
"oxc-transform-react": "^0.147.0",
|
|
61
|
+
"pg": "8.22.0",
|
|
62
|
+
"tailwindcss": "^4.3.3",
|
|
63
|
+
"typescript": "^7.0.2",
|
|
59
64
|
"vite": "catalog:",
|
|
60
65
|
"vite-plus": "catalog:",
|
|
61
66
|
"vitest": "catalog:"
|
|
@@ -38,7 +38,9 @@ const PostFeed = ({
|
|
|
38
38
|
return posts.length ? (
|
|
39
39
|
<VStack gap={16}>
|
|
40
40
|
<Stack alignCenter between gap={16}>
|
|
41
|
-
<H2 className="pl-5">
|
|
41
|
+
<H2 className="pl-5">
|
|
42
|
+
<fbt desc="Latest posts header">Latest posts</fbt>
|
|
43
|
+
</H2>
|
|
42
44
|
<div>
|
|
43
45
|
<button
|
|
44
46
|
className={cx(
|
|
@@ -46,6 +48,7 @@ const PostFeed = ({
|
|
|
46
48
|
user ? 'active:translate-y-0.5 active:opacity-50' : 'pointer-events-none opacity-0',
|
|
47
49
|
)}
|
|
48
50
|
onClick={() => setShowPostEditor((showPostEditor) => !showPostEditor)}
|
|
51
|
+
type="button"
|
|
49
52
|
>
|
|
50
53
|
{showPostEditor ? (
|
|
51
54
|
<CircleMinus className="h-6 w-6" />
|
|
@@ -65,7 +68,7 @@ const PostFeed = ({
|
|
|
65
68
|
{loadNext ? (
|
|
66
69
|
<Stack center>
|
|
67
70
|
<Button onClick={loadNext} variant="ghost">
|
|
68
|
-
Load more posts
|
|
71
|
+
<fbt desc="Load more posts button">Load more posts</fbt>{' '}
|
|
69
72
|
</Button>
|
|
70
73
|
</Stack>
|
|
71
74
|
) : null}
|
|
@@ -77,7 +80,9 @@ const PostFeed = ({
|
|
|
77
80
|
const CategoryFeed = ({ categories }: { categories: Array<ViewRef<'Category'>> }) =>
|
|
78
81
|
categories.length ? (
|
|
79
82
|
<VStack gap={16}>
|
|
80
|
-
<H2 className="pl-5">
|
|
83
|
+
<H2 className="pl-5">
|
|
84
|
+
<fbt desc="index: Explore by theme">Explore by theme</fbt>
|
|
85
|
+
</H2>
|
|
81
86
|
<VStack gap={24}>
|
|
82
87
|
{categories.map((category) => (
|
|
83
88
|
<CategoryCard category={category} key={category.id} />
|
|
@@ -89,7 +94,9 @@ const CategoryFeed = ({ categories }: { categories: Array<ViewRef<'Category'>> }
|
|
|
89
94
|
const EventFeed = ({ events }: { events: Array<ViewRef<'Event'>> }) =>
|
|
90
95
|
events.length ? (
|
|
91
96
|
<VStack gap={16}>
|
|
92
|
-
<H2 className="pl-5">
|
|
97
|
+
<H2 className="pl-5">
|
|
98
|
+
<fbt desc="index: Events">Events</fbt>
|
|
99
|
+
</H2>
|
|
93
100
|
<VStack gap={24}>
|
|
94
101
|
{events.map((event) => (
|
|
95
102
|
<EventCard event={event} key={event.id} />
|
|
@@ -114,16 +121,20 @@ export default function HomePage() {
|
|
|
114
121
|
<Card className="border border-white/20 bg-linear-to-r from-blue-500 to-sky-500 text-white dark:from-blue-600 dark:to-sky-600">
|
|
115
122
|
<Stack alignCenter gap={12} wrap>
|
|
116
123
|
<span className="squircle bg-white/20 px-2 py-1 text-xs font-semibold tracking-widest uppercase">
|
|
117
|
-
<span className="lowercase italic">fate</span> demo
|
|
124
|
+
<span className="lowercase italic">fate</span> <fbt desc="index: demo">demo</fbt>{' '}
|
|
118
125
|
</span>
|
|
119
126
|
</Stack>
|
|
120
127
|
<div className="space-y-3">
|
|
121
128
|
<h1 className="text-3xl leading-tight font-semibold text-balance lg:text-4xl">
|
|
122
|
-
|
|
129
|
+
<fbt desc="Description of fate">
|
|
130
|
+
fate is a modern data client for React inspired by Relay and GraphQL.
|
|
131
|
+
</fbt>{' '}
|
|
123
132
|
</h1>
|
|
124
133
|
<p className="text-sm text-white/80 lg:text-base">
|
|
125
|
-
fate combines view composition, normalized caching, data masking, Async React
|
|
126
|
-
|
|
134
|
+
<fbt desc="index: fate combines view composition, normalized caching, data masking, Async React features, and type-safe data fetching.">
|
|
135
|
+
fate combines view composition, normalized caching, data masking, Async React
|
|
136
|
+
features, and type-safe data fetching.
|
|
137
|
+
</fbt>{' '}
|
|
127
138
|
</p>
|
|
128
139
|
</div>
|
|
129
140
|
<Stack alignCenter gap={12} wrap>
|
|
@@ -131,10 +142,12 @@ export default function HomePage() {
|
|
|
131
142
|
<>
|
|
132
143
|
<Button asChild size="sm" variant="secondary">
|
|
133
144
|
<Link className="squircle px-4 py-2 text-sm font-semibold" href="/login">
|
|
134
|
-
Login
|
|
145
|
+
<fbt desc="Login button">Login</fbt>{' '}
|
|
135
146
|
</Link>
|
|
136
147
|
</Button>
|
|
137
|
-
<span className="text-sm text-white/80">
|
|
148
|
+
<span className="text-sm text-white/80">
|
|
149
|
+
<fbt desc="Login button label">Sign in to post comments.</fbt>
|
|
150
|
+
</span>
|
|
138
151
|
</>
|
|
139
152
|
)}
|
|
140
153
|
</Stack>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import '../src/App.css';
|
|
2
1
|
import Stack from '@nkzw/stack';
|
|
2
|
+
import '../src/App.css';
|
|
3
3
|
import { useShared } from '@void/react';
|
|
4
4
|
import { ReactNode, Suspense } from 'react';
|
|
5
5
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
6
6
|
import { VoidFateClient } from 'void-fate/react';
|
|
7
|
+
import LocaleContext from '../src/lib/LocaleContext.tsx';
|
|
7
8
|
import type { SharedData } from '../src/lib/shared.ts';
|
|
8
9
|
import Card from '../src/ui/Card.tsx';
|
|
9
10
|
import Error from '../src/ui/Error.tsx';
|
|
@@ -13,7 +14,7 @@ import Section from '../src/ui/Section.tsx';
|
|
|
13
14
|
const Thinking = () => (
|
|
14
15
|
<Section>
|
|
15
16
|
<Stack center className="animate-pulse text-gray-500 italic" verticalPadding={48}>
|
|
16
|
-
Thinking
|
|
17
|
+
<fbt desc="Text for thinking/loading screen">Thinking...</fbt>
|
|
17
18
|
</Stack>
|
|
18
19
|
</Section>
|
|
19
20
|
);
|
|
@@ -24,23 +25,25 @@ export default function Layout({ children }: { children: ReactNode }) {
|
|
|
24
25
|
const origin = typeof window === 'undefined' ? shared.origin : window.location.origin;
|
|
25
26
|
|
|
26
27
|
return (
|
|
27
|
-
<
|
|
28
|
-
<
|
|
29
|
-
<div className="min-h-screen bg-
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
<LocaleContext>
|
|
29
|
+
<VoidFateClient origin={origin} userId={userId}>
|
|
30
|
+
<div className="min-h-screen bg-background text-foreground">
|
|
31
|
+
<div className="min-h-screen bg-[radial-gradient(circle_at_20%_20%,rgba(59,130,246,0.08),transparent_35%),radial-gradient(circle_at_80%_0,rgba(99,102,241,0.08),transparent_28%)]">
|
|
32
|
+
<Header />
|
|
33
|
+
<ErrorBoundary
|
|
34
|
+
fallbackRender={({ error }) => (
|
|
35
|
+
<Section>
|
|
36
|
+
<Card>
|
|
37
|
+
<Error error={error} />
|
|
38
|
+
</Card>
|
|
39
|
+
</Section>
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<Suspense fallback={<Thinking />}>{children}</Suspense>
|
|
43
|
+
</ErrorBoundary>
|
|
44
|
+
</div>
|
|
42
45
|
</div>
|
|
43
|
-
</
|
|
44
|
-
</
|
|
46
|
+
</VoidFateClient>
|
|
47
|
+
</LocaleContext>
|
|
45
48
|
);
|
|
46
49
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Stack, { VStack } from '@nkzw/stack';
|
|
2
2
|
import { useRouter, useShared } from '@void/react';
|
|
3
|
+
import { fbs } from 'fbtee';
|
|
3
4
|
import { ExternalLinkIcon } from 'lucide-react';
|
|
4
5
|
import { useActionState, useEffect, useState } from 'react';
|
|
5
6
|
import type { SharedData } from '../src/lib/shared.ts';
|
|
@@ -49,7 +50,9 @@ export default function LoginPage() {
|
|
|
49
50
|
return (
|
|
50
51
|
<Section>
|
|
51
52
|
<VStack center gap={16}>
|
|
52
|
-
<H2 className="pl-5">
|
|
53
|
+
<H2 className="pl-5">
|
|
54
|
+
<fbt desc="Sign in button">Sign In</fbt>
|
|
55
|
+
</H2>
|
|
53
56
|
<Stack gap={32} wrap>
|
|
54
57
|
<Card className="w-84">
|
|
55
58
|
<Stack gap vertical>
|
|
@@ -58,7 +61,7 @@ export default function LoginPage() {
|
|
|
58
61
|
className="w-48"
|
|
59
62
|
name="email"
|
|
60
63
|
onChange={(e) => setEmail(e.target.value)}
|
|
61
|
-
placeholder=
|
|
64
|
+
placeholder={fbs('email', 'login: placeholder')}
|
|
62
65
|
type="email"
|
|
63
66
|
value={email}
|
|
64
67
|
/>
|
|
@@ -66,13 +69,13 @@ export default function LoginPage() {
|
|
|
66
69
|
className="w-48"
|
|
67
70
|
name="password"
|
|
68
71
|
onChange={(e) => setPassword(e.target.value)}
|
|
69
|
-
placeholder=
|
|
72
|
+
placeholder={fbs('password', 'login: placeholder')}
|
|
70
73
|
type="password"
|
|
71
74
|
value={password}
|
|
72
75
|
/>
|
|
73
76
|
<div>
|
|
74
77
|
<AsyncButton type="submit" variant="outline">
|
|
75
|
-
Sign In
|
|
78
|
+
<fbt desc="Sign in button">Sign In</fbt>{' '}
|
|
76
79
|
</AsyncButton>
|
|
77
80
|
</div>
|
|
78
81
|
</VStack>
|
|
@@ -80,20 +83,21 @@ export default function LoginPage() {
|
|
|
80
83
|
</Card>
|
|
81
84
|
<Card className="w-84">
|
|
82
85
|
<p>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
<fbt desc="Example account instructions">
|
|
87
|
+
Try one of the{' '}
|
|
88
|
+
<Stack
|
|
89
|
+
alignCenter
|
|
90
|
+
as="a"
|
|
91
|
+
className="inline-flex! px-1 underline hover:no-underline"
|
|
92
|
+
gap={4}
|
|
93
|
+
href="https://github.com/nkzw-tech/fate/blob/main/packages/create-fate/templates/fate/void/seedData.ts#L1"
|
|
94
|
+
rel="noreferrer"
|
|
95
|
+
target="_blank"
|
|
96
|
+
>
|
|
97
|
+
Example Accounts <ExternalLinkIcon className="h-4 w-4" />
|
|
98
|
+
</Stack>{' '}
|
|
99
|
+
in the seed data.
|
|
100
|
+
</fbt>{' '}
|
|
97
101
|
</p>
|
|
98
102
|
</Card>
|
|
99
103
|
</Stack>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Stack, { VStack } from '@nkzw/stack';
|
|
2
|
+
import { fbs } from 'fbtee';
|
|
2
3
|
import { Suspense, useDeferredValue, useState } from 'react';
|
|
3
4
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
4
5
|
import { useRequest, useView, view, ViewRef } from 'react-fate';
|
|
@@ -39,7 +40,12 @@ const SearchResults = ({ isStale, query }: { isStale: boolean; query: string })
|
|
|
39
40
|
if (commentSearch.length === 0) {
|
|
40
41
|
return (
|
|
41
42
|
<p>
|
|
42
|
-
|
|
43
|
+
<fbt desc="Empty comment search results">
|
|
44
|
+
No matches for{' '}
|
|
45
|
+
<i>
|
|
46
|
+
"<fbt:param name="query">{query}</fbt:param>"
|
|
47
|
+
</i>
|
|
48
|
+
</fbt>
|
|
43
49
|
</p>
|
|
44
50
|
);
|
|
45
51
|
}
|
|
@@ -65,17 +71,25 @@ export default function SearchPage() {
|
|
|
65
71
|
<Input
|
|
66
72
|
className="w-64"
|
|
67
73
|
onChange={(e) => setQuery(e.target.value)}
|
|
68
|
-
placeholder=
|
|
74
|
+
placeholder={fbs('Search comments...', 'search: placeholder')}
|
|
69
75
|
ref={(ref) => ref?.focus()}
|
|
70
76
|
value={query}
|
|
71
77
|
/>
|
|
72
78
|
{isDevelopment ? (
|
|
73
|
-
<div className="text-xs text-muted-foreground">
|
|
79
|
+
<div className="text-xs text-muted-foreground">
|
|
80
|
+
<fbt desc="Slowdown label explanation">500ms artificial slowdown</fbt>
|
|
81
|
+
</div>
|
|
74
82
|
) : null}
|
|
75
83
|
</Stack>
|
|
76
84
|
|
|
77
85
|
<ErrorBoundary FallbackComponent={Error}>
|
|
78
|
-
<Suspense
|
|
86
|
+
<Suspense
|
|
87
|
+
fallback={
|
|
88
|
+
<h2>
|
|
89
|
+
<fbt desc="Text for thinking/loading screen">Thinking…</fbt>
|
|
90
|
+
</h2>
|
|
91
|
+
}
|
|
92
|
+
>
|
|
79
93
|
{query.trim().length > 0 ? <SearchResults isStale={isStale} query={query} /> : null}
|
|
80
94
|
</Suspense>
|
|
81
95
|
</ErrorBoundary>
|
|
@@ -8,13 +8,12 @@ allowBuilds:
|
|
|
8
8
|
workerd: true
|
|
9
9
|
|
|
10
10
|
catalog:
|
|
11
|
-
vite: npm:@voidzero-dev/vite-plus-core@^0.
|
|
12
|
-
vite-plus: ^0.
|
|
13
|
-
vitest:
|
|
11
|
+
vite: npm:@voidzero-dev/vite-plus-core@^0.3.0
|
|
12
|
+
vite-plus: ^0.3.0
|
|
13
|
+
vitest: ^4.1.11
|
|
14
14
|
|
|
15
15
|
minimumReleaseAgeExclude:
|
|
16
16
|
- '@voidzero-dev/vite-plus-core'
|
|
17
|
-
- '@voidzero-dev/vite-plus-test'
|
|
18
17
|
- vite-plus
|
|
19
18
|
|
|
20
19
|
onlyBuiltDependencies:
|
|
@@ -26,6 +25,7 @@ onlyBuiltDependencies:
|
|
|
26
25
|
- workerd
|
|
27
26
|
|
|
28
27
|
overrides:
|
|
28
|
+
better-auth: 1.7.2
|
|
29
29
|
kysely: 0.28.17
|
|
30
30
|
vite: 'catalog:'
|
|
31
31
|
vitest: 'catalog:'
|
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
hasNestedSelection,
|
|
8
8
|
} from '@nkzw/fate/server';
|
|
9
9
|
import { createDrizzleSourceAdapter, type DrizzleQueryExtra } from '@nkzw/fate/server/drizzle';
|
|
10
|
+
import { like } from 'drizzle-orm';
|
|
10
11
|
import { createVoidFateLive } from 'void-fate/server';
|
|
11
|
-
import { db, eq
|
|
12
|
+
import { db, eq } from 'void/db';
|
|
12
13
|
import { z } from 'zod';
|
|
13
14
|
import {
|
|
14
15
|
type CommentItem,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/// <reference types="fbtee/ReactTypes.d.ts" />
|
|
2
|
+
|
|
3
|
+
import { createLocaleContext, useLocaleContext } from 'fbtee';
|
|
4
|
+
import { ReactNode, startTransition, useEffect, useState } from 'react';
|
|
5
|
+
import AvailableLanguages from './AvailableLanguages.tsx';
|
|
6
|
+
|
|
7
|
+
const Context = createLocaleContext({
|
|
8
|
+
availableLanguages: AvailableLanguages,
|
|
9
|
+
// Keep the server and first client render identical; restore preferences after hydration.
|
|
10
|
+
clientLocales: ['en-US'],
|
|
11
|
+
fallbackLocale: 'en-US',
|
|
12
|
+
loadLocale: async (locale) => {
|
|
13
|
+
if (locale !== 'en-US' && AvailableLanguages.has(locale)) {
|
|
14
|
+
return (await import(`../translations/${locale}.json`)).default[locale];
|
|
15
|
+
}
|
|
16
|
+
return {};
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function RestoreLocale({ restored, onRestore }: { restored: boolean; onRestore: () => void }) {
|
|
21
|
+
const { locale, setLocale } = useLocaleContext();
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (restored) return;
|
|
24
|
+
onRestore();
|
|
25
|
+
let savedLocale: string | null = null;
|
|
26
|
+
try {
|
|
27
|
+
savedLocale = localStorage.getItem('fbtee:locale');
|
|
28
|
+
} catch {
|
|
29
|
+
// Browser storage can be unavailable.
|
|
30
|
+
}
|
|
31
|
+
const preferred = [savedLocale, ...navigator.languages, navigator.language]
|
|
32
|
+
.filter((value): value is string => !!value)
|
|
33
|
+
.map((value) => value.replaceAll('_', '-'));
|
|
34
|
+
const nextLocale = preferred
|
|
35
|
+
.map((value) =>
|
|
36
|
+
AvailableLanguages.has(value)
|
|
37
|
+
? value
|
|
38
|
+
: [...AvailableLanguages.keys()].find(
|
|
39
|
+
(available) => available.split('-')[0] === value.split('-')[0],
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
.find(Boolean);
|
|
43
|
+
if (nextLocale && nextLocale !== locale) {
|
|
44
|
+
startTransition(() => setLocale(nextLocale));
|
|
45
|
+
}
|
|
46
|
+
}, [locale, setLocale, restored, onRestore]);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
document.documentElement.lang = locale;
|
|
49
|
+
}, [locale]);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default function LocaleContext({ children }: { children: ReactNode }) {
|
|
54
|
+
const [restored, setRestored] = useState(false);
|
|
55
|
+
return (
|
|
56
|
+
<Context>
|
|
57
|
+
<RestoreLocale restored={restored} onRestore={() => setRestored(true)} />
|
|
58
|
+
{children}
|
|
59
|
+
</Context>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
@@ -33,11 +33,23 @@ const CategoryPost = ({ post: postRef }: { post: ViewRef<'Post'> }) => {
|
|
|
33
33
|
{post.title}
|
|
34
34
|
</span>
|
|
35
35
|
</Link>
|
|
36
|
-
<span className="text-xs text-muted-foreground">
|
|
36
|
+
<span className="text-xs text-muted-foreground">
|
|
37
|
+
<fbt desc="Post like count">
|
|
38
|
+
<fbt:plural count={post.likes} many="likes" showCount="yes">
|
|
39
|
+
like
|
|
40
|
+
</fbt:plural>
|
|
41
|
+
</fbt>
|
|
42
|
+
</span>
|
|
37
43
|
</Stack>
|
|
38
44
|
<Stack alignCenter gap wrap>
|
|
39
45
|
<span className="text-xs text-muted-foreground">
|
|
40
|
-
{author?.name ?
|
|
46
|
+
{author?.name ? (
|
|
47
|
+
<fbt desc="Post author">
|
|
48
|
+
by <fbt:param name="author">{author.name}</fbt:param>
|
|
49
|
+
</fbt>
|
|
50
|
+
) : (
|
|
51
|
+
<fbt desc="Anonymous post author">By an anonymous collaborator</fbt>
|
|
52
|
+
)}
|
|
41
53
|
</span>
|
|
42
54
|
{tags.length ? (
|
|
43
55
|
<Stack gap wrap>
|
|
@@ -82,7 +94,11 @@ export default function CategoryCard({ category: categoryRef }: { category: View
|
|
|
82
94
|
<p className="text-sm text-muted-foreground">{category.description}</p>
|
|
83
95
|
</div>
|
|
84
96
|
<Badge className="text-nowrap" variant="outline">
|
|
85
|
-
|
|
97
|
+
<fbt desc="Category post count">
|
|
98
|
+
<fbt:plural count={category.postCount} many="posts" showCount="yes">
|
|
99
|
+
post
|
|
100
|
+
</fbt:plural>
|
|
101
|
+
</fbt>{' '}
|
|
86
102
|
</Badge>
|
|
87
103
|
</Stack>
|
|
88
104
|
<VStack gap={12}>
|
|
@@ -92,7 +108,9 @@ export default function CategoryCard({ category: categoryRef }: { category: View
|
|
|
92
108
|
</VStack>
|
|
93
109
|
{category.posts?.pagination?.hasNext ? (
|
|
94
110
|
<span className="text-sm text-muted-foreground">
|
|
95
|
-
More posts available in this category...
|
|
111
|
+
<fbt desc="CategoryCard: More posts available in this category...">
|
|
112
|
+
More posts available in this category...
|
|
113
|
+
</fbt>{' '}
|
|
96
114
|
</span>
|
|
97
115
|
) : null}
|
|
98
116
|
</VStack>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Stack, { VStack } from '@nkzw/stack';
|
|
2
|
+
import { fbs } from 'fbtee';
|
|
2
3
|
import { KeyboardEvent, startTransition, useActionState, useState } from 'react';
|
|
3
4
|
import { useFateClient, useView, ViewRef } from 'react-fate';
|
|
4
5
|
import { Button } from '../ui/Button.tsx';
|
|
@@ -64,13 +65,15 @@ export default function CreatePost({ user: userRef }: { user: ViewRef<'User'> |
|
|
|
64
65
|
return (
|
|
65
66
|
<Card>
|
|
66
67
|
<VStack action={createPost} as="form" gap={16}>
|
|
67
|
-
<H3>
|
|
68
|
+
<H3>
|
|
69
|
+
<fbt desc="CreatePost: Create a Post">Create a Post</fbt>
|
|
70
|
+
</H3>
|
|
68
71
|
<Input
|
|
69
72
|
className="w-full"
|
|
70
73
|
disabled={isPending}
|
|
71
74
|
onChange={(event) => setTitleValue(event.target.value)}
|
|
72
75
|
onKeyDown={maybeSubmitPost}
|
|
73
|
-
placeholder=
|
|
76
|
+
placeholder={fbs('Post Title', 'CreatePost: placeholder')}
|
|
74
77
|
value={titleValue}
|
|
75
78
|
/>
|
|
76
79
|
<textarea
|
|
@@ -78,18 +81,20 @@ export default function CreatePost({ user: userRef }: { user: ViewRef<'User'> |
|
|
|
78
81
|
disabled={isPending}
|
|
79
82
|
onChange={(event) => setContentValue(event.target.value)}
|
|
80
83
|
onKeyDown={maybeSubmitPost}
|
|
81
|
-
placeholder={'Share your thoughts about fate...'}
|
|
84
|
+
placeholder={fbs('Share your thoughts about fate...', 'CreatePost: placeholder')}
|
|
82
85
|
value={contentValue}
|
|
83
86
|
/>
|
|
84
87
|
<Stack alignCenter between className="text-sm" gap={16}>
|
|
85
|
-
<span className="font-bold">
|
|
88
|
+
<span className="font-bold">
|
|
89
|
+
<fbt desc="CreatePost: Mutation Debug Options">Mutation Debug Options</fbt>
|
|
90
|
+
</span>
|
|
86
91
|
<Stack alignCenter as="label" gap>
|
|
87
92
|
<CheckBox
|
|
88
93
|
checked={missingMutationSelection}
|
|
89
94
|
disabled={isPending}
|
|
90
95
|
onChange={(event) => setMissingMutationSelection(event.target.checked)}
|
|
91
96
|
/>
|
|
92
|
-
Missing mutation selection
|
|
97
|
+
<fbt desc="CreatePost: Missing mutation selection">Missing mutation selection</fbt>{' '}
|
|
93
98
|
</Stack>
|
|
94
99
|
<Stack alignCenter as="label" gap>
|
|
95
100
|
<CheckBox
|
|
@@ -97,12 +102,12 @@ export default function CreatePost({ user: userRef }: { user: ViewRef<'User'> |
|
|
|
97
102
|
disabled={isPending}
|
|
98
103
|
onChange={(event) => setMissingOptimisticContent(event.target.checked)}
|
|
99
104
|
/>
|
|
100
|
-
Missing optimistic content
|
|
105
|
+
<fbt desc="CreatePost: Missing optimistic content">Missing optimistic content</fbt>{' '}
|
|
101
106
|
</Stack>
|
|
102
107
|
</Stack>
|
|
103
108
|
<Stack alignCenter end gap={16}>
|
|
104
109
|
<Button disabled={postingIsDisabled} size="sm" type="submit" variant="secondary">
|
|
105
|
-
Post comment
|
|
110
|
+
<fbt desc="Post comment button">Post comment</fbt>{' '}
|
|
106
111
|
</Button>
|
|
107
112
|
</Stack>
|
|
108
113
|
</VStack>
|