Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Ring Platform provides every user with a personalized public profile page at /[locale]/[username]. This is a fully server-rendered Next.js 16 App Router page with dynamic SEO metadata, NFT galleries, blog integration, and staking portfolio display.
/[locale]/[username] → Public profile page
/[locale]/[username]/[slug] → Blog article pageExamples: /en/ray, /uk/ivan, /ru/alex
The route is a Next.js 16 App Router dynamic segment at app/[locale]/[username]/page.tsx. The server-side getUserByUsername() function performs a case-insensitive lookup in the users collection.
photoURL with optimized Next.js Image component<h1> rendered with user.name@{user.username}user.bio, rendered with max-w-2xlisVerified is true from Telegram Bot verification/api/nft-market/listings?username=... (public GET, no auth required)/blog/{username}/{slug}/news feed via the News Kingdom pipelineUsers control their profile's public visibility through the SetUsernameModal:
@usernameIndividual toggles per contact field (email, phone, location, social links, Telegram) will allow founders to selectively display contact information on their public profile.
| Visibility | Behavior |
|---|---|
| Public | Profile page at /[locale]/[username] is fully visible with avatar, name, bio, NFT listings, and blog |
| Private | Profile route returns a 404 Not Found |
Users can enhance their profile credibility with Telegram account verification:
features/auth/components/telegram-linking-modal.tsx)app/api/auth/telegram/callback/route.ts validates the auth hash.toLowerCase())next-intl locale supportgenerateMetadata() — title and description derived from user name and bionotFound() when username doesn't existapp/[locale]/[username]/[slug]/page.tsx resolves blog articles from the news collection| Endpoint | Method | Purpose |
|---|---|---|
/api/auth/check-username?username={name} | GET | Check username availability |
/api/nft-market/listings?username={name} | GET | Get user's NFT listings (public) |
/api/nft-market/listings | POST | Create NFT listing (requires auth) |
/api/auth/telegram/callback | POST | Telegram bot verification callback |
/api/user/favorites | POST | Bookmark a user's blog article |
Ring Platform provides every user with a personalized public profile page at /[locale]/[username]. This is a fully server-rendered Next.js 16 App Router page with dynamic SEO metadata, NFT galleries, blog integration, and staking portfolio display.
/[locale]/[username] → Public profile page
/[locale]/[username]/[slug] → Blog article pageExamples: /en/ray, /uk/ivan, /ru/alex
The route is a Next.js 16 App Router dynamic segment at app/[locale]/[username]/page.tsx. The server-side getUserByUsername() function performs a case-insensitive lookup in the users collection.
photoURL with optimized Next.js Image component<h1> rendered with user.name@{user.username}user.bio, rendered with max-w-2xlisVerified is true from Telegram Bot verification/api/nft-market/listings?username=... (public GET, no auth required)/blog/{username}/{slug}/news feed via the News Kingdom pipelineUsers control their profile's public visibility through the SetUsernameModal:
@usernameIndividual toggles per contact field (email, phone, location, social links, Telegram) will allow founders to selectively display contact information on their public profile.
| Visibility | Behavior |
|---|---|
| Public | Profile page at /[locale]/[username] is fully visible with avatar, name, bio, NFT listings, and blog |
| Private | Profile route returns a 404 Not Found |
Users can enhance their profile credibility with Telegram account verification:
features/auth/components/telegram-linking-modal.tsx)app/api/auth/telegram/callback/route.ts validates the auth hash.toLowerCase())next-intl locale supportgenerateMetadata() — title and description derived from user name and bionotFound() when username doesn't existapp/[locale]/[username]/[slug]/page.tsx resolves blog articles from the news collection| Endpoint | Method | Purpose |
|---|---|---|
/api/auth/check-username?username={name} | GET | Check username availability |
/api/nft-market/listings?username={name} | GET | Get user's NFT listings (public) |
/api/nft-market/listings | POST | Create NFT listing (requires auth) |
/api/auth/telegram/callback | POST | Telegram bot verification callback |
/api/user/favorites | POST | Bookmark a user's blog article |
Ring Platform provides every user with a personalized public profile page at /[locale]/[username]. This is a fully server-rendered Next.js 16 App Router page with dynamic SEO metadata, NFT galleries, blog integration, and staking portfolio display.
/[locale]/[username] → Public profile page
/[locale]/[username]/[slug] → Blog article pageExamples: /en/ray, /uk/ivan, /ru/alex
The route is a Next.js 16 App Router dynamic segment at app/[locale]/[username]/page.tsx. The server-side getUserByUsername() function performs a case-insensitive lookup in the users collection.
photoURL with optimized Next.js Image component<h1> rendered with user.name@{user.username}user.bio, rendered with max-w-2xlisVerified is true from Telegram Bot verification/api/nft-market/listings?username=... (public GET, no auth required)/blog/{username}/{slug}/news feed via the News Kingdom pipelineUsers control their profile's public visibility through the SetUsernameModal:
@usernameIndividual toggles per contact field (email, phone, location, social links, Telegram) will allow founders to selectively display contact information on their public profile.
| Visibility | Behavior |
|---|---|
| Public | Profile page at /[locale]/[username] is fully visible with avatar, name, bio, NFT listings, and blog |
| Private | Profile route returns a 404 Not Found |
Users can enhance their profile credibility with Telegram account verification:
features/auth/components/telegram-linking-modal.tsx)app/api/auth/telegram/callback/route.ts validates the auth hash.toLowerCase())next-intl locale supportgenerateMetadata() — title and description derived from user name and bionotFound() when username doesn't existapp/[locale]/[username]/[slug]/page.tsx resolves blog articles from the news collection| Endpoint | Method | Purpose |
|---|---|---|
/api/auth/check-username?username={name} | GET | Check username availability |
/api/nft-market/listings?username={name} | GET | Get user's NFT listings (public) |
/api/nft-market/listings | POST | Create NFT listing (requires auth) |
/api/auth/telegram/callback | POST | Telegram bot verification callback |
/api/user/favorites | POST | Bookmark a user's blog article |
// app/[locale]/[username]/page.tsx
export default async function PublicProfilePage(props: LocalePageProps<PublicProfileParams>) {
const params = await props.params
const user = await getUserByUsername(params.username)
if (!user) return notFound() // 404 if username doesn't exist
// Render profile: avatar, name, bio, NFT listings, blog, staking
}
// features/auth/services/get-user-by-username.ts
export const getUserByUsername = cache(async (username: string) => {
const result = await db().queryDocs({
collection: 'users',
filters: [{ field: 'username', operator: '=', value: username.trim().toLowerCase() }],
pagination: { limit: 1 }
})
if (!result.success || result.data.length === 0) return null
return mapRowToAuthUser(result.data[0])
})
// app/[locale]/[username]/page.tsx
export default async function PublicProfilePage(props: LocalePageProps<PublicProfileParams>) {
const params = await props.params
const user = await getUserByUsername(params.username)
if (!user) return notFound() // 404 if username doesn't exist
// Render profile: avatar, name, bio, NFT listings, blog, staking
}
// features/auth/services/get-user-by-username.ts
export const getUserByUsername = cache(async (username: string) => {
const result = await db().queryDocs({
collection: 'users',
filters: [{ field: 'username', operator: '=', value: username.trim().toLowerCase() }],
pagination: { limit: 1 }
})
if (!result.success || result.data.length === 0) return null
return mapRowToAuthUser(result.data[0])
})
// app/[locale]/[username]/page.tsx
export default async function PublicProfilePage(props: LocalePageProps<PublicProfileParams>) {
const params = await props.params
const user = await getUserByUsername(params.username)
if (!user) return notFound() // 404 if username doesn't exist
// Render profile: avatar, name, bio, NFT listings, blog, staking
}
// features/auth/services/get-user-by-username.ts
export const getUserByUsername = cache(async (username: string) => {
const result = await db().queryDocs({
collection: 'users',
filters: [{ field: 'username', operator: '=', value: username.trim().toLowerCase() }],
pagination: { limit: 1 }
})
if (!result.success || result.data.length === 0) return null
return mapRowToAuthUser(result.data[0])
})