Profil

Bir yapay zeka ürününün ayarlarındaki Profil bölümü. Fotoğrafı daire içine kırpın, siz yazarken kontrol edilen bir kullanıcı adı seçin, yeni e-postayı 6 haneli bir kodla onaylayın, siteyi tanıyan bağlantılar ekleyin ve başkalarının sizi nasıl gördüğünü canlı bir kartta izleyin.

ProfileSettings, Claude veya Cursor gibi bir üründeki Profil sayfasıdır ve herhangi bir SettingsShell bölümüne eklenecek şekilde geliştirilmiştir. Ona kayıtlı profili ve bir onSave verin, gerisini o halleder: yalnızca siz söylediğinizde kaydedilen bir taslak, kontrollerinizden ya da sunucunuzdan gelen alan hataları ve ⌘S ile Settings'teki yüzen kaydetme çubuğu.

En üstteki bir kart, başkalarının profilinizi nasıl gördüğünü gösterir ve siz yazdıkça değişir: fotoğraf, ad, kullanıcı adı, biyografi ve bağlantılar. Show my profile'ı kapatırsanız kart soluklaşır ve yalnızca sizin görebildiğinizi söyler. Copy link profil URL'sini panoya koyar.

Bir fotoğraf seçin ya da satıra bırakın; bir kırpma iletişim kutusunda açılır. Taşımak için sürükleyin, kaydırıcı, tekerlek ya da dokunmatik yüzey kıstırmasıyla yakınlaştırın; fotoğraf onSave'e data URL olarak ulaşmadan önce tarayıcıda kareye kırpılır. Yanlış türde, çok büyük ya da 128 pikselden küçük dosyalar satırda nedeniyle reddedilir.

Kullanıcı adı, yazmayı yavaşlatmadan siz yazarken denetlenir. Denetimler son tuştan sonra 350ms bekler, eski denetimler bir AbortSignal ile iptal edilir ve daha önce denetlediğiniz adlar anında yanıtlanır. Alınmış bir ad, önerilerinizi tek dokunuşluk düzeltmeler olarak gösterir. Bir denetim bitmeden kaydederseniz kaydetme onu bekler.

E-posta taslağın parçası değildir. Change iki adımlı bir iletişim kutusu açar: yeni adresi girin, ardından ona gönderilen 6 haneli kodu; son rakam girildiğinde kod kendini denetler. Yanlış kod sallanır ve temizlenir, Resend 30 saniye sonra açılır ve kod onaylanınca satır güncellenir. Doğrulanmamış bir adres Resend link gösterir.

Bağlantılar, insanların yapıştırdığı her şeyi alır: github.com/you, tam bir URL ya da bir www adresi. Bilinen siteler simgelerini, diğerleri ilk harflerini alır. Kaydederken https URL'lerine normalleştirilir ve boş olanlar atılır. Bağlantı olmayan ya da başka birini tekrar eden adresler tek tek işaretlenir.

  1. Pro registry'yi components.json dosyasına ekleyin

    components.json
    {
      "registries": {
        "@hextaui-pro": {
          "url": "https://hextaui.com/r/pro/{name}.json",
          "headers": {
            "Authorization": "Bearer ${HEXTAUI_PRO_TOKEN}"
          }
        }
      }
    }
  2. Token'ınızı ekleyin

    Hesap sayfanızda bir token oluşturun ve .env.local dosyasına HEXTAUI_PRO_TOKEN olarak ekleyin.

  3. Bloğu ekleyin

    pnpm dlx shadcn@latest add @hextaui-pro/profile

API'nize bağlayın

Kayıtlı profili ve alan hataları döndüren ya da hata fırlatan bir onSave iletin. checkUsername bir AbortSignal alır; böylece insanlar yazdıkça eski denetimler iptal edilir.

"use client"

import { SettingsSection, SettingsShell } from "../settings/settings"

import { ProfileSettings, type ProfileValues } from "@/components/blocks/profile/profile"

export function ProfilePage({ profile, email }: { profile: ProfileValues; email: string }) {
  return (
    <SettingsShell sections={[{ id: "profile", label: "Profile" }]} className="h-svh">
      <SettingsSection id="profile">
        <ProfileSettings
          profile={profile}
          email={email}
          checkUsername={async (username, signal) => {
            const response = await fetch(`/api/usernames/${username}`, { signal })
            return response.json()
          }}
          onSave={async (values) => {
            const response = await fetch("/api/profile", {
              method: "PATCH",
              body: JSON.stringify(values),
            })
            if (response.status === 409) return { username: "That username is taken." }
            if (!response.ok) throw new Error("Check your connection and try again.")
          }}
        />
      </SettingsSection>
    </SettingsShell>
  )
}

E-postayı değiştirin ve doğrulayın

Change düğmesini açmak için onRequestEmailCode ve onVerifyEmailCode ekleyin. Bir adresi reddetmek için onRequestEmailCode'dan bir mesaj, yanlış bir kod için onVerifyEmailCode'dan false döndürün.

"use client"

import * as React from "react"

import { SettingsSection, SettingsShell } from "../settings/settings"

import { ProfileSettings, type ProfileValues } from "@/components/blocks/profile/profile"

export function ProfileWithEmail({ profile, account }: {
  profile: ProfileValues
  account: { email: string; verified: boolean }
}) {
  const [email, setEmail] = React.useState(account.email)

  return (
    <SettingsShell sections={[{ id: "profile", label: "Profile" }]} className="h-svh">
      <SettingsSection id="profile">
        <ProfileSettings
          profile={profile}
          email={email}
          emailVerified={account.verified}
          onSave={(values) => fetch("/api/profile", { method: "PATCH", body: JSON.stringify(values) }).then(() => {})}
          onResendVerification={() => fetch("/api/email/verify", { method: "POST" })}
          onRequestEmailCode={async (next) => {
            const response = await fetch("/api/email/change", {
              method: "POST",
              body: JSON.stringify({ email: next }),
            })
            if (response.status === 409) return "That address belongs to another account."
            if (!response.ok) throw new Error("Couldn’t send the code. Try again.")
          }}
          onVerifyEmailCode={async (next, code) => {
            const response = await fetch("/api/email/change/verify", {
              method: "POST",
              body: JSON.stringify({ email: next, code }),
            })
            return response.ok
          }}
          onEmailChange={setEmail}
        />
      </SettingsSection>
    </SettingsShell>
  )
}

Yapı

Dıştan içe doğru birleştirdiğiniz parçalar.

ParçaAçıklama
ProfileSettingsBölüm: önizleme kartı, fotoğraf, ad, asistanın size ne dediği, kullanıcı adı, biyografi, herkese açık profil, bağlantılar ve e-posta.
ProfileCardHerkese açık profilin Copy link içeren canlı önizlemesi. Tek başına kullanılabilir.
AvatarCropDialogBir görseli sürükleme, yakınlaştırma ve klavyeyle kare olarak kırpar ve bir data URL döndürür.
ChangeEmailDialogİki adımlı e-posta değişikliği: yeni adres, ardından 6 haneli bir kod.
useUsernameCheckBir kullanıcı adı için debounce'lu, iptal edilebilir, önbellekli uygunluk denetimleri.

ProfileSettings

Bir SettingsSection içinde kullanın.

PropTürVarsayılan
profileŞu an kayıtlı olan: { avatar, name, nickname, username, bio, links, public }. Değiştiğinde ve düzenleme yoksa taslak onu izler.
ProfileValues–
onSaveKırpılmış değerler ve normalleştirilmiş bağlantılarla çağrılır. Alan hataları için { field: message } döndürün ya da mesajı kaydetme çubuğunda göstermek için hata fırlatın.
(values) => void | errors | Promise<void | errors>–
emailOturum açma adresi.
string–
emailVerifiedVerified ya da Resend link ile Not verified gösterir.
booleantrue
checkUsernameBir kullanıcı adının boş olup olmadığını denetler. Küçük harfli adı ve bir AbortSignal alır. Verilmezse yalnızca biçim denetlenir.
(username, signal) => Promise<{ available, message?, suggestions? }>–
onRequestEmailCodeYeni bir adrese kod gönderir. Adresi reddetmek için bir mesaj döndürün. onVerifyEmailCode ile birlikte Change'i açar.
(email) => Promise<void | string>–
onVerifyEmailCodeKodu denetler. Yanlış kod için false döndürün ya da mesajınızı göstermek için hata fırlatın.
(email, code) => Promise<boolean>–
onEmailChangeYeni adres onaylandığında çağrılır.
(email) => void–
onResendVerificationAdres doğrulanmamışken Resend link ekler.
() => Promise<unknown>–
profileUrlKullanıcı adının altında gösterilen ve Copy link ile kopyalanan herkese açık profil URL'si.
(username) => stringhttps://hexta.app/@username
assistantName“What should Hexta call you?” içinde kullanılır.
string"Hexta"
maxAvatarBytesKabul edilen en büyük fotoğraf.
number5 MB
maxLinksBir profilin kaç bağlantısı olabileceği.
number5
maxBioSayaçlı biyografi uzunluğu.
number160
PropTürVarsayılan
profileNe gösterileceği.
{ avatar, name, username, bio, links, public }–
urlGösterilecek ve kopyalanacak profil URL'si.
string–
onCopiedBağlantı kopyalandıktan sonra çağrılır.
() => void–
PropTürVarsayılan
sourceKırpılacak görsel. Ayarlıyken açıktır.
{ url, width, height } | null–
onOpenChangeKapandığında kaynağı temizler.
(open) => void–
onApplyKırpılan kareyi WebP olarak, WebP desteklenmiyorsa PNG olarak verir.
(dataUrl) => void–
outputSizeÇıktının piksel cinsinden en büyük kenarı. Kırpmanın ötesinde asla büyütmez.
number512
maxZoomNe kadar yakınlaştırabileceğiniz.
number4
PropTürVarsayılan
openAçık olup olmadığı.
boolean–
currentEmailGirişte gösterilir ve yeni adres olarak reddedilir.
string–
onRequestCodeKodu gönderir. Reddetmek için bir mesaj döndürün.
(email) => Promise<void | string>–
onVerifyCodeKodu denetler.
(email, code) => Promise<boolean>–
onChangedKod onaylandıktan sonra, iletişim kutusu kapanmadan önce çağrılır.
(email) => void–
resendAfterResend code'un açılmasına kalan saniye.
number30

useUsernameCheck(username, options)

{ status, result, problem, retry, resolve } döndürür. status idle, invalid, checking, available, taken veya error olabilir.

PropTürVarsayılan
currentKayıtlı kullanıcı adı; asla denetlenmez.
string–
checkUygunluk denetiminiz.
(username, signal) => Promise<UsernameCheck>–
delayYazma durduktan sonra beklenecek milisaniye.
number350
TuşAction
EnterSon bağlantıda bir bağlantı daha ekler ve ona geçer.
←→↑↓Kırpma iletişim kutusunda fotoğrafı taşır. Shift daha uzağa taşır.
+−Kırpma iletişim kutusunda yakınlaştırır ve uzaklaştırır. 0 sıfırlar.
⌘SKaydedilmemiş bir şey varken kaydeder. Windows ve Linux'ta Ctrl+S.
EscBir iletişim kutusunu kapatır ve odağı onu açan düğmeye döndürür.
  • Her alan satırının adını taşır ve bir sözcüğü tekrar eden düğmeler neyi etkilediğini söyler: Upload photo, Change email, Remove link 2, github.com/you.
  • Kullanıcı adı sonuçları, kopyalanan bağlantılar, fotoğraf değişiklikleri, kaldırılan bağlantılar ve değişen bir e-posta polite olarak duyurulur. Denetimin kendisi duyurulmaz; böylece yazma sessiz kalır.
  • Alan hataları yalnızca hatalı alanı işaretler ve bir kaydetme reddedildiğinde odak ilkine geçer. E-posta kodu denetleniyor, onaylandı ve yanlış durumlarını duyurur.
  • Bir bağlantıyı kaldırmak odağı sonraki bağlantıya, kalmadıysa Add link'e taşır. Fotoğrafı kaldırmak odağı Upload'a taşır.
  • Kırpma alanı odaklanabilir ve ok tuşları ile artı ve eksi ile çalışır; yakınlaştırma kaydırıcısı değerini yüzde olarak söyler.
  • Dokunmatik ekranlarda input'lar iOS yakınlaştırmasın diye 16px metin kullanır ve simge düğmelerinin 44px hedefleri vardır.

Şunlarla geliştirildi

Profile bloğunun yapıldığı ücretsiz HextaUI bileşenleri. Her biri tek başına yüklenir.

Kod

6 dosya, components/blocks/profile konumuna eklendi.