Merge branch 'main' into feat/story-blurred-background

This commit is contained in:
Paulo Castellano 2026-07-07 11:13:59 -03:00 committed by GitHub
commit c74170a25a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
379 changed files with 35503 additions and 303 deletions

View file

@ -0,0 +1,65 @@
name: 'Setup Laravel test environment'
description: 'Set up PHP, Composer, optional Node, the app key, database, and Passport keys for a test job.'
inputs:
node:
description: 'Also set up Node.js and install npm dependencies.'
default: 'false'
db-port:
description: 'Host port mapped to the Postgres service.'
required: true
redis-port:
description: 'Host port mapped to the Redis service.'
required: true
runs:
using: 'composite'
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_pgsql, bcmath, intl, gd, redis
coverage: none
- name: Setup Node.js
if: inputs.node == 'true'
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
- name: Cache Composer dependencies
uses: actions/cache@v6
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Prepare environment
shell: bash
run: cp .env.ci .env
- name: Install Composer dependencies
shell: bash
run: composer install --no-interaction --prefer-dist --optimize-autoloader
- name: Install npm dependencies
if: inputs.node == 'true'
shell: bash
run: npm ci
- name: Generate application key
shell: bash
run: php artisan key:generate
- name: Run migrations
shell: bash
env:
DB_PORT: ${{ inputs.db-port }}
REDIS_PORT: ${{ inputs.redis-port }}
run: php artisan migrate --force
- name: Generate Passport keys
shell: bash
run: php artisan passport:keys --force

View file

@ -17,7 +17,7 @@ jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2

View file

@ -36,7 +36,7 @@ jobs:
platform: ${{ matrix.platform }}
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Docker metadata (labels)
id: meta
@ -76,7 +76,7 @@ jobs:
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
@ -92,7 +92,7 @@ jobs:
packages: write
steps:
- name: Download digests
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: ${{ runner.temp }}/digests
pattern: digests-*

View file

@ -6,18 +6,19 @@ on:
pull_request:
branches: [main, develop]
env:
DB_CONNECTION: pgsql
DB_DATABASE: trypost_test
DB_USERNAME: postgres
DB_PASSWORD: password
BROADCAST_CONNECTION: "null"
CACHE_STORE: array
QUEUE_CONNECTION: sync
SESSION_DRIVER: array
jobs:
tests:
backend:
runs-on: ubuntu-latest
env:
DB_CONNECTION: pgsql
DB_DATABASE: trypost_test
DB_USERNAME: postgres
DB_PASSWORD: password
BROADCAST_CONNECTION: "null"
CACHE_STORE: array
QUEUE_CONNECTION: sync
SESSION_DRIVER: array
services:
postgres:
@ -46,54 +47,89 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
- name: Setup test environment
uses: ./.github/actions/setup-laravel
with:
php-version: '8.4'
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_pgsql, bcmath, intl, gd, redis
coverage: none
db-port: ${{ job.services.postgres.ports['5432'] }}
redis-port: ${{ job.services.redis.ports['6379'] }}
- name: Setup Node.js
uses: actions/setup-node@v4
- name: Run backend tests
env:
DB_PORT: ${{ job.services.postgres.ports['5432'] }}
REDIS_PORT: ${{ job.services.redis.ports['6379'] }}
run: php artisan test --compact --parallel
e2e:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2]
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: trypost_test
ports:
- 5432/tcp
options: >-
--health-cmd="pg_isready"
--health-interval=10s
--health-timeout=5s
--health-retries=3
redis:
image: redis:7
ports:
- 6379/tcp
options: >-
--health-cmd="redis-cli ping"
--health-interval=10s
--health-timeout=5s
--health-retries=3
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup test environment
uses: ./.github/actions/setup-laravel
with:
node-version: '22'
cache: 'npm'
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Prepare environment
run: cp .env.ci .env
- name: Install Composer dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader
- name: Install npm dependencies
run: npm ci
- name: Generate application key
run: php artisan key:generate
node: 'true'
db-port: ${{ job.services.postgres.ports['5432'] }}
redis-port: ${{ job.services.redis.ports['6379'] }}
- name: Build assets
run: npm run build
- name: Run migrations
run: php artisan migrate --force
- name: Install Playwright browsers
run: npx playwright install --with-deps chromium
- name: Run browser tests
env:
DB_PORT: ${{ job.services.postgres.ports['5432'] }}
REDIS_PORT: ${{ job.services.redis.ports['6379'] }}
run: php artisan test tests/Browser --compact --shard=${{ matrix.shard }}/2
- name: Generate Passport keys
run: php artisan passport:keys --force
- name: Upload Playwright artifacts
if: failure()
uses: actions/upload-artifact@v7
with:
name: playwright-artifacts-${{ matrix.shard }}
path: tests/Browser/Screenshots
if-no-files-found: ignore
retention-days: 7
- name: Run tests
run: php artisan test --compact --parallel
env:
DB_PORT: ${{ job.services.postgres.ports['5432'] }}
REDIS_PORT: ${{ job.services.redis.ports['6379'] }}
e2e-gate:
if: always()
needs: e2e
runs-on: ubuntu-latest
steps:
- name: Require all e2e shards to pass
run: '[ "${{ needs.e2e.result }}" = "success" ] || exit 1'

1
.gitignore vendored
View file

@ -1,6 +1,7 @@
/.phpunit.cache
/bootstrap/ssr
/node_modules
/tests/Browser/Screenshots
/public/build
/lang/php_*.json
/public/hot

View file

@ -24,7 +24,7 @@ public static function execute(User $user, array $data): Workspace
'brand_color' => data_get($data, 'brand_color'),
'background_color' => data_get($data, 'background_color'),
'text_color' => data_get($data, 'text_color'),
'content_language' => data_get($data, 'content_language'),
'content_language' => data_get($data, 'content_language', app()->getLocale()),
], static fn ($value): bool => $value !== null);
$workspace = DB::transaction(function () use ($user, $attributes): Workspace {

View file

@ -5,6 +5,7 @@
namespace App\Ai\Agents;
use App\Enums\Workspace\BrandVoiceTrait;
use App\Enums\Workspace\ContentLanguage;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
@ -20,6 +21,9 @@ public function instructions(): string
return view('prompts.brand_analyzer', [
'voice_groups' => BrandVoiceTrait::grouped(),
'single_select_groups' => BrandVoiceTrait::singleSelectGroups(),
'content_languages' => collect(ContentLanguage::values())
->map(fn (string $code) => "`{$code}`")
->implode(', '),
])->render();
}
@ -47,7 +51,7 @@ public function schema(JsonSchema $schema): array
->description('A concise 2-3 sentence brand description summarizing what the company does, who they serve, and what makes them unique. Written in the detected content language.')
->required(),
'language' => $schema->string()
->enum(['en', 'pt-BR', 'es'])
->enum(ContentLanguage::values())
->description('The primary language of the content.')
->required(),
'brand_color' => $schema->string()

View file

@ -4,17 +4,25 @@
namespace App\Console\Commands;
use App\Enums\SocialAccount\Platform;
use App\Enums\SocialAccount\Status;
use App\Jobs\RefreshSocialToken;
use App\Models\SocialAccount;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
class RefreshExpiringTokens extends Command
{
protected $signature = 'social:refresh-expiring-tokens';
protected $description = 'Proactively refresh tokens expiring in the next 2 hours (or already expired)';
protected $description = 'Proactively refresh social tokens before they expire';
/**
* Rotating refresh_token platforms only need a short lead: verify() won't
* rotate a still-valid token, so we catch them right before or after expiry.
* Extension-model platforms (Instagram/Threads) can't be refreshed once
* expired, so they get a much wider lead to survive queue backlog.
*/
public function handle(): void
{
$count = 0;
@ -22,7 +30,15 @@ public function handle(): void
SocialAccount::query()
->where('status', Status::Connected)
->whereNotNull('token_expires_at')
->where('token_expires_at', '<=', now()->addHours(2))
->where(function (Builder $query) {
$query->where(function (Builder $extension) {
$extension->whereIn('platform', Platform::accessTokenExtendingPlatformValues())
->where('token_expires_at', '<=', now()->addDay());
})->orWhere(function (Builder $rotating) {
$rotating->whereNotIn('platform', Platform::accessTokenExtendingPlatformValues())
->where('token_expires_at', '<=', now()->addMinutes(30));
});
})
->chunk(50, function ($accounts) use (&$count) {
foreach ($accounts as $account) {
RefreshSocialToken::dispatch($account);

View file

@ -261,6 +261,60 @@ public function requiresContent(): bool
};
}
/**
* Whether this platform refreshes by extending the access_token itself
* (Instagram/Threads long-lived tokens) instead of exchanging a separate
* refresh_token. Extension-model tokens cannot be refreshed once expired,
* so they must be refreshed proactively while still valid — the opposite
* of rotating refresh_token platforms, which we avoid refreshing until
* they actually expire so we don't rotate a still-valid single-use token.
*/
public function extendsAccessTokenOnRefresh(): bool
{
return match ($this) {
self::Instagram, self::Threads => true,
default => false,
};
}
/**
* The `platform` column values of the platforms that refresh by extending
* their access token in place (Instagram and Threads — see
* extendsAccessTokenOnRefresh), for use in database whereIn/whereNotIn
* filters. Derived from extendsAccessTokenOnRefresh() so the two never drift.
*
* @return array<int, string>
*/
public static function accessTokenExtendingPlatformValues(): array
{
return array_values(array_map(
fn (self $platform): string => $platform->value,
array_filter(self::cases(), fn (self $platform): bool => $platform->extendsAccessTokenOnRefresh()),
));
}
/**
* The token lifetime, in seconds, to assume when the provider's OAuth
* response omits expires_in. Each value is that network's own documented
* default:
*
* - X: a 2-hour access token.
* - Instagram / Threads: Meta's 60-day long-lived token.
*
* Networks that always return expires_in (LinkedIn, TikTok, YouTube,
* Pinterest), whose refresh sets a fixed lifetime directly (Bluesky), or
* whose tokens never expire (Facebook, Mastodon, Telegram, Discord) have no
* fallback here and return null.
*/
public function defaultTokenTtlSeconds(): ?int
{
return match ($this) {
self::X => 7200,
self::Instagram, self::Threads => 5184000,
default => null,
};
}
public function queue(): string
{
return 'social-'.$this->value;

View file

@ -0,0 +1,146 @@
<?php
declare(strict_types=1);
namespace App\Enums\Workspace;
/**
* The set of languages the app supports, and the single source of truth for it:
* request validation, the brand analyzer's structured-output enum, homepage
* language detection, the AI image prompt's language name, the content-language
* picker options, and the right-to-left direction of the UI all derive from it.
*
* The string value is the language code stored on the workspace and passed
* straight to the content prompts (`content_language`); the same codes also back
* the application's UI locales, so `direction()` drives the document `dir` attribute.
*/
enum ContentLanguage: string
{
case English = 'en';
case PortugueseBrazil = 'pt-BR';
case Spanish = 'es';
case French = 'fr';
case German = 'de';
case Italian = 'it';
case Dutch = 'nl';
case Polish = 'pl';
case Greek = 'el';
case Japanese = 'ja';
case Korean = 'ko';
case Chinese = 'zh';
case Russian = 'ru';
case Turkish = 'tr';
case Arabic = 'ar';
public const DEFAULT = self::English;
/**
* The language's own name, shown in the content-language picker.
*/
public function label(): string
{
return match ($this) {
self::English => 'English',
self::PortugueseBrazil => 'Português (Brasil)',
self::Spanish => 'Español',
self::French => 'Français',
self::German => 'Deutsch',
self::Italian => 'Italiano',
self::Dutch => 'Nederlands',
self::Polish => 'Polski',
self::Greek => 'Ελληνικά',
self::Japanese => '日本語',
self::Korean => '한국어',
self::Chinese => '中文',
self::Russian => 'Русский',
self::Turkish => 'Türkçe',
self::Arabic => 'العربية',
};
}
/**
* The English name of the language, injected into AI image prompts so the
* in-image text is rendered in the workspace's content language.
*/
public function englishName(): string
{
return match ($this) {
self::English => 'English',
self::PortugueseBrazil => 'Brazilian Portuguese',
self::Spanish => 'Spanish',
self::French => 'French',
self::German => 'German',
self::Italian => 'Italian',
self::Dutch => 'Dutch',
self::Polish => 'Polish',
self::Greek => 'Greek',
self::Japanese => 'Japanese',
self::Korean => 'Korean',
self::Chinese => 'Chinese',
self::Russian => 'Russian',
self::Turkish => 'Turkish',
self::Arabic => 'Arabic',
};
}
/**
* The text direction (`ltr` or `rtl`) for the document root when this is the
* active UI locale — only Arabic is written right to left.
*/
public function direction(): string
{
return $this === self::Arabic ? 'rtl' : 'ltr';
}
/**
* Resolve a raw `<html lang>` value (e.g. "pt-PT", "zh-Hans") to a supported
* language by matching its primary subtag, or null if none is supported.
*/
public static function fromHtmlLang(string $lang): ?self
{
$subtag = self::primarySubtag($lang);
if (strlen($subtag) < 2) {
return null;
}
foreach (self::cases() as $language) {
if (self::primarySubtag($language->value) === $subtag) {
return $language;
}
}
return null;
}
/**
* The lowercased primary subtag of a BCP 47 language tag ("pt-BR" => "pt").
*/
private static function primarySubtag(string $tag): string
{
return strtolower(explode('-', trim($tag), 2)[0]);
}
/**
* @return array<int, string>
*/
public static function values(): array
{
return array_map(fn (self $language) => $language->value, self::cases());
}
/**
* @return array<int, array{value: string, label: string, englishName: string}>
*/
public static function options(): array
{
return array_map(
fn (self $language) => [
'value' => $language->value,
'label' => $language->label(),
'englishName' => $language->englishName(),
],
self::cases(),
);
}
}

View file

@ -150,9 +150,15 @@ public function connect(Request $request): Response|RedirectResponse
'network' => $platform->network(),
])->values();
$plan = Plan::where('slug', Slug::Workspace)->firstOrFail();
return Inertia::render('onboarding/Connect', [
'platforms' => $platforms,
'accounts' => SocialAccountResource::collection($accounts)->resolve(),
'plan' => [
'name' => $plan->name,
'interval' => 'monthly',
],
]);
}

View file

@ -9,6 +9,7 @@
use App\Actions\Workspace\DeleteWorkspace;
use App\Enums\Workspace\BrandFont;
use App\Enums\Workspace\BrandVoiceTrait;
use App\Enums\Workspace\ContentLanguage;
use App\Enums\Workspace\ImageStyle;
use App\Http\Requests\App\Workspace\AutofillBrandRequest;
use App\Http\Requests\App\Workspace\StoreWorkspaceRequest;
@ -20,12 +21,10 @@
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Support\Facades\Log;
use Inertia\Inertia;
use Inertia\Response;
use RuntimeException;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
use Throwable;
class WorkspaceController extends Controller
{
@ -80,6 +79,7 @@ public function create(Request $request): Response|RedirectResponse
'availableFonts' => BrandFont::values(),
'availableImageStyles' => ImageStyle::values(),
'availableVoiceTraits' => BrandVoiceTrait::grouped(),
'availableContentLanguages' => ContentLanguage::options(),
]);
}
@ -103,15 +103,7 @@ public function store(StoreWorkspaceRequest $request, LogoAttacher $logoAttacher
$workspace = CreateWorkspace::execute($user, $validated);
if ($logoUrl = data_get($validated, 'logo_url')) {
try {
$logoAttacher->attach($workspace, $logoUrl);
} catch (Throwable $e) {
Log::warning('Logo attach failed during workspace creation', [
'workspace_id' => $workspace->id,
'logo_url' => $logoUrl,
'error' => $e->getMessage(),
]);
}
$logoAttacher->attach($workspace, $logoUrl);
}
return redirect()->route('app.accounts')
@ -163,6 +155,7 @@ public function brandSettings(Request $request): Response|RedirectResponse
'availableFonts' => BrandFont::values(),
'availableImageStyles' => ImageStyle::values(),
'availableVoiceTraits' => BrandVoiceTrait::grouped(),
'availableContentLanguages' => ContentLanguage::options(),
]);
}
@ -195,7 +188,7 @@ public function deleteLogo(Request $request): RedirectResponse
return back()->with('flash.success', __('settings.flash.logo_deleted'));
}
public function updateSettings(UpdateWorkspaceRequest $request): RedirectResponse
public function updateSettings(UpdateWorkspaceRequest $request, LogoAttacher $logoAttacher): RedirectResponse
{
$user = $request->user();
$workspace = $user->currentWorkspace;
@ -206,7 +199,16 @@ public function updateSettings(UpdateWorkspaceRequest $request): RedirectRespons
$this->authorize('update', $workspace);
$workspace->update($request->validated());
$validated = $request->validated();
$logoUrl = data_get($validated, 'logo_url');
unset($validated['logo_url']);
$workspace->update($validated);
if ($logoUrl) {
$logoAttacher->attach($workspace, $logoUrl);
}
return back()->with('flash.success', __('settings.flash.workspace_updated'));
}

View file

@ -69,7 +69,7 @@ public function callback(Request $request): InertiaResponse
$avatarPath = $socialUser->getAvatar() ? uploadFromUrl($socialUser->getAvatar()) : null;
// Calculate token expiration (long-lived tokens last 60 days)
$expiresIn = $socialUser->expiresIn ?? 5184000; // 60 days in seconds
$expiresIn = $socialUser->expiresIn ?? $this->platform->defaultTokenTtlSeconds();
$tokenExpiresAt = now()->addSeconds($expiresIn);
$workspace->socialAccounts()->updateOrCreate(

View file

@ -8,6 +8,7 @@
use App\Enums\SocialAccount\Status;
use App\Exceptions\SocialAccount\NetworkAlreadyConnectedException;
use App\Models\Workspace;
use App\Services\Social\TokenRedactor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
@ -90,7 +91,7 @@ public function callback(Request $request): InertiaResponse
if ($tokenResponse->failed()) {
Log::error('Threads token exchange failed', [
'status' => $tokenResponse->status(),
'body' => $tokenResponse->body(),
'body' => TokenRedactor::redact($tokenResponse->body()),
]);
throw new \Exception('Failed to exchange token');
}
@ -106,15 +107,18 @@ public function callback(Request $request): InertiaResponse
'access_token' => $shortLivedToken,
]);
$longLivedToken = $shortLivedToken;
$expiresIn = null;
if ($longLivedResponse->successful()) {
$longLivedData = $longLivedResponse->json();
$longLivedToken = $longLivedData['access_token'] ?? $shortLivedToken;
$expiresIn = $longLivedData['expires_in'] ?? null;
if ($longLivedResponse->failed()) {
Log::error('Threads long-lived token exchange failed', [
'status' => $longLivedResponse->status(),
'body' => TokenRedactor::redact($longLivedResponse->body()),
]);
throw new \Exception('Failed to exchange long-lived token');
}
$longLivedData = $longLivedResponse->json();
$longLivedToken = $longLivedData['access_token'] ?? $shortLivedToken;
$expiresIn = $longLivedData['expires_in'] ?? $this->platform->defaultTokenTtlSeconds();
// Fetch user profile
$profileResponse = Http::get(config('trypost.platforms.threads.graph_api')."/{$userId}", [
'access_token' => $longLivedToken,
@ -142,7 +146,7 @@ public function callback(Request $request): InertiaResponse
'avatar_url' => $avatarPath,
'access_token' => $longLivedToken,
'refresh_token' => null,
'token_expires_at' => $expiresIn ? now()->addSeconds($expiresIn) : null,
'token_expires_at' => now()->addSeconds($expiresIn),
'scopes' => $this->scopes,
'status' => Status::Connected,
'error_message' => null,

View file

@ -4,9 +4,11 @@
namespace App\Http\Middleware\App;
use App\Enums\Workspace\ContentLanguage;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\View;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
@ -19,8 +21,11 @@ public function handle(Request $request, Closure $next): Response
$available = config('languages.available');
$locale = $request->cookie('locale');
$isValid = $locale && array_key_exists($locale, $available);
$activeLocale = $isValid ? $locale : config('languages.default');
$language = ContentLanguage::tryFrom($activeLocale) ?? ContentLanguage::DEFAULT;
App::setLocale($isValid ? $locale : config('languages.default'));
App::setLocale($activeLocale);
View::share('htmlDir', $language->direction());
$response = $next($request);

View file

@ -6,6 +6,7 @@
use App\Enums\Workspace\BrandFont;
use App\Enums\Workspace\BrandVoiceTrait;
use App\Enums\Workspace\ContentLanguage;
use App\Enums\Workspace\ImageStyle;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -32,7 +33,7 @@ public function rules(): array
'text_color' => $hex,
'brand_font' => ['sometimes', 'string', Rule::in(BrandFont::values())],
'image_style' => ['sometimes', 'string', Rule::in(ImageStyle::values())],
'content_language' => ['nullable', 'string', 'in:en,pt-BR,es'],
'content_language' => ['nullable', 'string', Rule::in(ContentLanguage::values())],
'logo_url' => ['nullable', 'url', 'max:1024'],
];
}

View file

@ -6,6 +6,7 @@
use App\Enums\Workspace\BrandFont;
use App\Enums\Workspace\BrandVoiceTrait;
use App\Enums\Workspace\ContentLanguage;
use App\Enums\Workspace\ImageStyle;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -32,7 +33,8 @@ public function rules(): array
'text_color' => $hex,
'brand_font' => ['sometimes', 'required', 'string', Rule::in(BrandFont::values())],
'image_style' => ['sometimes', 'required', 'string', Rule::in(ImageStyle::values())],
'content_language' => ['sometimes', 'string', 'in:en,pt-BR,es'],
'content_language' => ['sometimes', 'string', Rule::in(ContentLanguage::values())],
'logo_url' => ['nullable', 'url', 'max:1024'],
];
}

View file

@ -24,7 +24,14 @@ public function __construct(public SocialAccount $account) {}
public function handle(ConnectionVerifier $verifier): void
{
try {
$verifier->refreshToken($this->account);
if ($this->account->platform->extendsAccessTokenOnRefresh()) {
// Instagram/Threads extend the long-lived token itself and
// can't be refreshed once expired, so extend it while it's
// still valid instead of waiting for it to fail.
$verifier->refreshToken($this->account);
} else {
$verifier->verify($this->account);
}
} catch (PlatformUnavailableException $e) {
Log::warning('Token refresh skipped: platform unavailable', [
'account_id' => $this->account->id,

View file

@ -93,6 +93,19 @@ protected function isTokenExpiringSoon(): Attribute
);
}
/**
* Whether the token should be refreshed before use. Rotating-refresh-token
* platforms are only refreshed once actually expired, to avoid rotating a
* still-valid single-use refresh_token; extension-model platforms
* (Instagram/Threads) must be refreshed while still valid because their
* token can't be extended once expired.
*/
public function needsProactiveTokenRefresh(): bool
{
return $this->is_token_expired
|| ($this->platform->extendsAccessTokenOnRefresh() && $this->is_token_expiring_soon);
}
protected function avatarUrl(): Attribute
{
return Attribute::make(

View file

@ -4,6 +4,7 @@
namespace App\Services\Ai;
use App\Enums\Workspace\ContentLanguage;
use App\Enums\Workspace\ImageStyle;
use App\Support\HexColorName;
use Illuminate\Support\Facades\Log;
@ -89,11 +90,7 @@ public function generate(
private function languageName(string $code): string
{
return match ($code) {
'pt-BR' => 'Brazilian Portuguese',
'es' => 'Spanish',
default => 'English',
};
return (ContentLanguage::tryFrom($code) ?? ContentLanguage::DEFAULT)->englishName();
}
/**

View file

@ -4,6 +4,7 @@
namespace App\Services\Brand;
use App\Enums\Workspace\ContentLanguage;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\UriResolver;
@ -291,14 +292,7 @@ private function extractLanguage(Crawler $crawler): ?string
return null;
}
$lower = strtolower($lang);
return match (true) {
str_starts_with($lower, 'pt') => 'pt-BR',
str_starts_with($lower, 'es') => 'es',
str_starts_with($lower, 'en') => 'en',
default => null,
};
return ContentLanguage::fromHtmlLang($lang)?->value;
}
private function extractLogoUrl(Crawler $crawler, string $baseUrl): ?string

View file

@ -6,6 +6,7 @@
use App\Models\Workspace;
use Illuminate\Support\Facades\Log;
use Throwable;
class LogoAttacher
{
@ -77,6 +78,10 @@ public function attach(Workspace $workspace, string $logoUrl): bool
);
return true;
} catch (Throwable $e) {
Log::warning('Logo rejected — persistence error', ['url' => $logoUrl, 'error' => $e->getMessage()]);
return false;
} finally {
if (file_exists($tempPath)) {
@unlink($tempPath);

View file

@ -15,7 +15,7 @@ class GiphyService
public function __construct()
{
$this->apiKey = config('services.giphy.api_key', '');
$this->apiKey = (string) config('services.giphy.api_key', '');
}
/**

View file

@ -66,7 +66,7 @@ public function publish(PostPlatform $postPlatform): array
$this->account = $postPlatform->socialAccount;
$this->hasRetried = false;
if ($this->account->is_token_expired || $this->account->is_token_expiring_soon) {
if ($this->account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($this->account);
}

View file

@ -48,7 +48,7 @@ public function publish(PostPlatform $postPlatform): array
$service = $account->meta['service'] ?? config('trypost.platforms.bluesky.default_service');
// Refresh token if needed
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -9,6 +9,7 @@
use App\Exceptions\TokenExpiredException;
use App\Models\SocialAccount;
use App\Services\Social\Discord\DiscordClient;
use App\Services\Social\Meta\GraphError;
use App\Services\Social\Telegram\TelegramApi;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
@ -31,9 +32,7 @@ public function verify(SocialAccount $account): bool
// refresh, so proactive refreshes during races cause false-positive
// disconnects even though the access_token still works fine.
if ($account->is_token_expired) {
$this->refreshToken($account);
return $this->callVerifyEndpoint($account);
return $this->refreshThenVerify($account);
}
try {
@ -41,13 +40,40 @@ public function verify(SocialAccount $account): bool
} catch (TokenExpiredException $e) {
// Verify returned 401: the access_token is actually invalid.
// Refresh and retry once with the new token.
try {
$this->refreshToken($account);
} catch (TokenExpiredException) {
throw $e;
}
return $this->refreshThenVerify($account, $e);
}
}
/**
* Refresh the token, then verify with the new one.
*
* If either the refresh is rejected (4xx) or the verify that follows it hits
* a token a concurrent refresh has already rotated — including the sub-commit
* window where a lock-skipped refresh reloads a not-yet-persisted token —
* reload and, when another process has since persisted a fresh access_token,
* verify with that instead of giving up. X (and other providers that
* single-use their refresh_token) would otherwise disconnect a still-usable
* account whenever two refreshes race and one loses.
*
* @throws TokenExpiredException
* @throws PlatformUnavailableException
*/
private function refreshThenVerify(SocialAccount $account, ?TokenExpiredException $original = null): bool
{
$accessTokenBeforeRefresh = $account->access_token;
try {
$this->refreshToken($account);
return $this->callVerifyEndpoint($account);
} catch (TokenExpiredException $e) {
$account->refresh();
if ($account->access_token !== $accessTokenBeforeRefresh) {
return $this->callVerifyEndpoint($account);
}
throw $original ?? $e;
}
}
@ -155,7 +181,7 @@ private function refreshXToken(SocialAccount $account): void
$account->update([
'access_token' => data_get($data, 'access_token'),
'refresh_token' => data_get($data, 'refresh_token', $account->refresh_token),
'token_expires_at' => now()->addSeconds(data_get($data, 'expires_in', 7200)),
'token_expires_at' => now()->addSeconds(data_get($data, 'expires_in', $account->platform->defaultTokenTtlSeconds())),
]);
$account->refresh();
@ -288,10 +314,13 @@ private function refreshPinterestToken(SocialAccount $account): void
private function refreshThreadsToken(SocialAccount $account): void
{
// Threads uses long-lived tokens that can be refreshed
$response = TokenRefreshClient::for(Platform::Threads)->send(fn () => Http::get(config('trypost.platforms.threads.auth_api').'/refresh_access_token', [
'grant_type' => 'th_refresh_token',
'access_token' => $account->access_token,
]));
$response = TokenRefreshClient::for(Platform::Threads)->send(
fn () => Http::get(config('trypost.platforms.threads.auth_api').'/refresh_access_token', [
'grant_type' => 'th_refresh_token',
'access_token' => $account->access_token,
]),
GraphError::indicatesInvalidToken(...),
);
$data = $response->json();
$newToken = data_get($data, 'access_token');
@ -299,7 +328,7 @@ private function refreshThreadsToken(SocialAccount $account): void
$account->update([
'access_token' => $newToken,
'refresh_token' => $newToken,
'token_expires_at' => data_get($data, 'expires_in') ? now()->addSeconds(data_get($data, 'expires_in')) : null,
'token_expires_at' => now()->addSeconds(data_get($data, 'expires_in', $account->platform->defaultTokenTtlSeconds())),
]);
$account->refresh();
@ -307,10 +336,13 @@ private function refreshThreadsToken(SocialAccount $account): void
private function refreshInstagramToken(SocialAccount $account): void
{
$response = TokenRefreshClient::for(Platform::Instagram)->send(fn () => Http::get(config('trypost.platforms.instagram.auth_api').'/refresh_access_token', [
'grant_type' => 'ig_refresh_token',
'access_token' => $account->access_token,
]));
$response = TokenRefreshClient::for(Platform::Instagram)->send(
fn () => Http::get(config('trypost.platforms.instagram.auth_api').'/refresh_access_token', [
'grant_type' => 'ig_refresh_token',
'access_token' => $account->access_token,
]),
GraphError::indicatesInvalidToken(...),
);
$data = $response->json();
$newToken = data_get($data, 'access_token');
@ -318,7 +350,7 @@ private function refreshInstagramToken(SocialAccount $account): void
$account->update([
'access_token' => $newToken,
'refresh_token' => $newToken,
'token_expires_at' => data_get($data, 'expires_in') ? now()->addSeconds(data_get($data, 'expires_in')) : null,
'token_expires_at' => now()->addSeconds(data_get($data, 'expires_in', $account->platform->defaultTokenTtlSeconds())),
]);
$account->refresh();
@ -385,13 +417,8 @@ private function verifyInstagram(SocialAccount $account): bool
$body = $response->json() ?? [];
if (isset($body['error'])) {
$errorCode = $body['error']['code'] ?? null;
$errorType = $body['error']['type'] ?? null;
if ($errorType === 'OAuthException' || $errorCode === 190) {
throw new TokenExpiredException('Instagram access token is invalid or expired');
}
if (GraphError::indicatesInvalidToken($body)) {
throw new TokenExpiredException('Instagram access token is invalid or expired');
}
return $response->successful();
@ -406,13 +433,8 @@ private function verifyFacebook(SocialAccount $account): bool
$body = $response->json() ?? [];
if (isset($body['error'])) {
$errorCode = $body['error']['code'] ?? null;
$errorType = $body['error']['type'] ?? null;
if ($errorType === 'OAuthException' || $errorCode === 190) {
throw new TokenExpiredException('Facebook access token is invalid or expired');
}
if (GraphError::indicatesInvalidToken($body)) {
throw new TokenExpiredException('Facebook access token is invalid or expired');
}
return $response->successful();
@ -427,13 +449,8 @@ private function verifyThreads(SocialAccount $account): bool
$body = $response->json() ?? [];
if (isset($body['error'])) {
$errorCode = $body['error']['code'] ?? null;
$errorType = $body['error']['type'] ?? null;
if ($errorType === 'OAuthException' || $errorCode === 190) {
throw new TokenExpiredException('Threads access token is invalid or expired');
}
if (GraphError::indicatesInvalidToken($body)) {
throw new TokenExpiredException('Threads access token is invalid or expired');
}
return $response->successful();

View file

@ -44,7 +44,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
$this->baseUrl = $account->platform->instagramGraphBaseUrl();
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -87,7 +87,7 @@ private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $si
{
$this->baseUrl = $account->platform->instagramGraphBaseUrl();
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -28,7 +28,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
$this->baseUrl = $account->platform->instagramGraphBaseUrl();
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -50,7 +50,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
return ['unsupported' => true, 'reason' => 'missing_post_id'];
}
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -79,7 +79,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $since, CarbonInterface $until): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App\Services\Social\Meta;
/**
* Interprets Meta Graph API (Facebook / Instagram / Threads) error responses.
*
* Meta returns rate-limit and transient failures as an ordinary HTTP 4xx with
* type "OAuthException" (e.g. code 4 / 17 "too many calls", code 1 / 2
* "temporary problem"), so neither the HTTP status nor the error type can tell
* a dead token from a throttle. Only error code 190 means the access token
* itself is invalid or expired — the same signal the platform publish
* exceptions already use to decide a disconnect.
*/
class GraphError
{
/**
* Whether the given Meta Graph error body means the access token is
* genuinely invalid or expired (code 190), as opposed to a rate-limit or
* transient error that must not disconnect a still-valid token.
*
* @param array<string, mixed>|null $body
*/
public static function indicatesInvalidToken(?array $body): bool
{
return data_get($body, 'error.code') === 190;
}
}

View file

@ -46,7 +46,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
return ['unsupported' => true, 'reason' => 'missing_post_id'];
}
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -90,7 +90,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $since, CarbonInterface $until): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -34,7 +34,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -407,7 +407,7 @@ private function waitForMediaProcessing(SocialAccount $account, string $mediaId,
*/
public function getBoards(SocialAccount $account): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -46,7 +46,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
return ['unsupported' => true, 'reason' => 'missing_post_id'];
}
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -77,7 +77,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $since, CarbonInterface $until): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -30,7 +30,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -35,7 +35,7 @@ public function getMetrics(SocialAccount $account): array
private function fetchMetricsFromApi(SocialAccount $account): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -58,7 +58,7 @@ public function fetch(SocialAccount $account): array
*/
private function fetchFresh(SocialAccount $account): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -43,7 +43,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -16,13 +16,18 @@
* Normalizes the failure modes of an OAuth token-refresh request:
*
* - ConnectionException (timeout / DNS / refused) → PlatformUnavailableException
* - HTTP 5xx → PlatformUnavailableException
* - HTTP 4xx → TokenExpiredException
* - HTTP 5xx or 429 → PlatformUnavailableException
* - other HTTP 4xx → TokenExpiredException
*
* Providers that return rate-limit or transient errors as an ordinary 4xx
* (Meta: Instagram/Threads) can pass an `$isTokenInvalid` classifier to
* `send()`; only a genuinely dead token then disconnects, while every other
* 4xx is treated as transient (PlatformUnavailableException).
*
* Callers configure the actual HTTP call through the closure passed to
* `send()`, so platform-specific quirks (form vs JSON body, auth headers,
* basic auth, etc.) stay where they belong — in the per-platform refresh
* method — while the failure semantics are uniform across providers.
* method.
*/
class TokenRefreshClient
{
@ -35,11 +40,14 @@ public static function for(Platform $platform): self
/**
* @param Closure():Response $request
* @param (Closure(array<string, mixed>|null):bool)|null $isTokenInvalid Given the parsed
* response body, returns whether a non-5xx/429 failure means the token itself is dead.
* When it returns false, the failure is treated as transient (PlatformUnavailableException).
*
* @throws PlatformUnavailableException
* @throws TokenExpiredException
*/
public function send(Closure $request): Response
public function send(Closure $request, ?Closure $isTokenInvalid = null): Response
{
$name = $this->platform->label();
@ -62,6 +70,14 @@ public function send(Closure $request): Response
]);
$body = $response->json();
if ($isTokenInvalid !== null && ! $isTokenInvalid($body)) {
throw new PlatformUnavailableException(
"{$name} API returned {$response->status()} during token refresh",
$response->status(),
);
}
$message = data_get($body, 'error_description')
?? data_get($body, 'error.message')
?? "Failed to refresh {$name} token";

View file

@ -46,7 +46,7 @@ public function getMetrics(SocialAccount $account, ?CarbonInterface $since = nul
private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $since, CarbonInterface $until): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -161,7 +161,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
return ['unsupported' => true, 'reason' => 'missing_post_id'];
}
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -37,8 +37,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
// Refresh token if expired or expiring soon
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -46,7 +46,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
return ['unsupported' => true, 'reason' => 'missing_post_id'];
}
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}
@ -97,7 +97,7 @@ public function fetchPostMetrics(PostPlatform $postPlatform): array
private function fetchMetricsFromApi(SocialAccount $account, CarbonInterface $since, CarbonInterface $until): array
{
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -33,7 +33,7 @@ public function publish(PostPlatform $postPlatform): array
$account = $postPlatform->socialAccount;
if ($account->is_token_expired || $account->is_token_expiring_soon) {
if ($account->needsProactiveTokenRefresh()) {
app(ConnectionVerifier::class)->refreshToken($account);
}

View file

@ -15,7 +15,7 @@ class UnsplashService
public function __construct()
{
$this->accessKey = config('services.unsplash.access_key', '');
$this->accessKey = (string) config('services.unsplash.access_key', '');
}
/**

View file

@ -74,6 +74,7 @@
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.6",
"pestphp/pest": "^4.4",
"pestphp/pest-plugin-browser": "^4.3",
"pestphp/pest-plugin-laravel": "^4.1"
},
"autoload": {
@ -120,6 +121,10 @@
"@test:lint",
"@php artisan test"
],
"test:all": [
"@test",
"@php artisan test tests/Browser"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"

1573
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,18 @@
'en' => 'English',
'es' => 'Español',
'pt-BR' => 'Português',
'fr' => 'Français',
'de' => 'Deutsch',
'it' => 'Italiano',
'nl' => 'Nederlands',
'pl' => 'Polski',
'el' => 'Ελληνικά',
'ja' => '日本語',
'ko' => '한국어',
'zh' => '中文',
'ru' => 'Русский',
'tr' => 'Türkçe',
'ar' => 'العربية',
],
/*

148
lang/ar/accounts.php Normal file
View file

@ -0,0 +1,148 @@
<?php
return [
'title' => 'الاتصالات',
'page_title' => 'الحسابات الاجتماعية',
'description' => 'نظرة عامة على جميع حساباتك الاجتماعية المتصلة',
'connect_cta' => 'ربط',
'not_connected' => 'غير متصل',
'connect' => 'ربط',
'connection_lost' => 'انقطع الاتصال',
'reconnect' => 'إعادة الربط',
'reconnect_account' => 'إعادة ربط الحساب',
'view_profile' => 'عرض الملف الشخصي',
'disconnect' => 'فصل',
'descriptions' => [
'linkedin' => 'اربط ملفك الشخصي أو صفحة شركتك على LinkedIn',
'linkedin-page' => 'اربط صفحة شركة على LinkedIn',
'x' => 'اربط حسابك على X (Twitter)',
'tiktok' => 'اربط حسابك على TikTok',
'youtube' => 'اربط قناة على YouTube',
'facebook' => 'اربط صفحة على Facebook',
'instagram' => 'اربط حساب Instagram احترافيًا',
'instagram-facebook' => 'اربط Instagram عبر صفحة Facebook',
'threads' => 'اربط حسابك على Threads',
'pinterest' => 'اربط حسابك على Pinterest',
'bluesky' => 'اربط حسابك على Bluesky',
'mastodon' => 'اربط حسابك على Mastodon',
'telegram' => 'اربط قناة أو مجموعة على Telegram',
'discord' => 'اربط خادم Discord',
],
'disconnect_modal' => [
'title' => 'فصل الحساب',
'description' => 'هل أنت متأكد من رغبتك في فصل هذا الحساب؟ يمكنك إعادة ربطه في أي وقت.',
'confirm' => 'فصل',
'cancel' => 'إلغاء',
],
'bluesky' => [
'title' => 'ربط Bluesky',
'description' => 'أدخل بيانات اعتمادك للربط',
'email' => 'البريد الإلكتروني',
'email_placeholder' => 'yourhandle.bsky.social',
'app_password' => 'كلمة مرور التطبيق',
'app_password_placeholder' => 'xxxx-xxxx-xxxx-xxxx',
'app_password_hint' => 'استخدم <strong>كلمة مرور التطبيق</strong> لمزيد من الأمان. أنشئ واحدة من <a href="https://bsky.app/settings/app-passwords" target="_blank" class="underline">bsky.app/settings</a>.',
'submit' => 'ربط Bluesky',
'submitting' => 'جارٍ الاتصال...',
],
'mastodon' => [
'title' => 'ربط Mastodon',
'description' => 'أدخل خادم Mastodon الخاص بك',
'instance_url' => 'رابط الخادم',
'instance_placeholder' => 'https://mastodon.social',
'instance_hint' => 'أدخل رابط خادم Mastodon الخاص بك (مثل mastodon.social، techhub.social)',
'submit' => 'المتابعة عبر Mastodon',
'submitting' => 'جارٍ الاتصال...',
],
'telegram' => [
'title' => 'ربط Telegram',
'description' => 'اربط قناة أو مجموعة',
'step_admin' => 'أضِف :bot كمشرف على قناتك أو مجموعتك على Telegram.',
'step_command' => 'انشر هذا الأمر في القناة أو المجموعة:',
'waiting' => 'في انتظار اتصال القناة…',
'connected' => 'تم اتصال القناة!',
'connected_toast' => 'تم ربط قناة Telegram بنجاح!',
'copied_toast' => 'تم نسخ الأمر إلى الحافظة',
'copy_tooltip' => 'نسخ الأمر',
'expired' => 'انتهت صلاحية هذا الرمز. أنشئ رمزًا جديدًا للمحاولة مرة أخرى.',
'new_code' => 'إنشاء رمز جديد',
'retry' => 'إعادة المحاولة',
'error_generic' => 'تعذر بدء الاتصال. يرجى المحاولة مرة أخرى.',
'network_taken' => 'تحتوي مساحة العمل هذه بالفعل على قناة Telegram متصلة. افصلها أولًا.',
],
'facebook' => [
'title' => 'اختيار صفحة Facebook',
'description' => 'اختر الصفحة التي تريد ربطها',
'no_pages' => 'لم يتم العثور على صفحات',
'no_pages_description' => 'أنت لست مشرفًا على أي صفحة Facebook.',
'page_label' => 'صفحة Facebook',
'view' => 'عرض',
'choose' => 'اختيار',
],
'instagram_facebook' => [
'title' => 'اختيار حساب Instagram',
'description' => 'اختر حساب Instagram الذي تريد ربطه',
'no_pages' => 'لم يتم العثور على حسابات Instagram',
'no_pages_description' => 'لم يتم العثور على صفحات Facebook مرتبطة بحسابات Instagram للأعمال.',
'view' => 'عرض',
'choose' => 'اختيار',
],
'linkedin' => [
'title' => 'اختيار صفحة LinkedIn',
'description' => 'اختر الصفحة التي تريد ربطها',
'no_pages' => 'لم يتم العثور على صفحات',
'no_pages_description' => 'أنت لست مشرفًا على أي صفحة LinkedIn.',
'page_label' => 'صفحة LinkedIn',
'select_title' => 'أين تريد النشر؟',
'select_subtitle' => 'انشر باسمك أو اختر صفحة شركة تديرها.',
'person_tag' => 'شخص',
'organization_tag' => 'مؤسسة',
'view' => 'عرض',
'choose' => 'اختيار',
],
'flash' => [
'disconnected' => 'تم فصل الحساب بنجاح!',
'connected' => 'تم ربط الحساب بنجاح!',
'session_expired' => 'انتهت الجلسة. يرجى المحاولة مرة أخرى.',
'workspace_not_found' => 'لم يتم العثور على مساحة العمل.',
'activated' => 'تم تفعيل الحساب!',
'deactivated' => 'تم إلغاء تفعيل الحساب!',
'already_connected' => 'هذه المنصة متصلة بالفعل.',
'no_youtube_channels' => 'لم يتم العثور على قنوات YouTube. يرجى إنشاء قناة أولًا.',
],
'popup_callback' => [
'title_success' => 'تم الاتصال',
'title_error' => 'خطأ',
'closing' => 'ستُغلق هذه النافذة تلقائيًا...',
'manual_close' => 'يمكنك إغلاق هذه النافذة.',
'popup_blocked' => 'تعذر فتح نافذة الاتصال. يرجى السماح بالنوافذ المنبثقة والمحاولة مرة أخرى.',
'connected' => 'تم ربط الحساب!',
'reconnected' => 'تمت إعادة ربط الحساب!',
'error_connecting' => 'خطأ في ربط الحساب. يرجى المحاولة مرة أخرى.',
'network_taken' => 'تحتوي مساحة العمل هذه بالفعل على حساب لهذه الشبكة. افصله أولًا.',
'error_connecting_page' => 'خطأ في ربط الصفحة. يرجى المحاولة مرة أخرى.',
'error_connecting_channel' => 'خطأ في ربط القناة. يرجى المحاولة مرة أخرى.',
'session_expired' => 'انتهت الجلسة. يرجى المحاولة مرة أخرى.',
'workspace_not_found' => 'لم يتم العثور على مساحة العمل.',
'invalid_state' => 'حالة غير صالحة. يرجى المحاولة مرة أخرى.',
'failed_to_authenticate' => 'فشلت المصادقة.',
'failed_to_get_profile' => 'فشل جلب الملف الشخصي.',
'page_not_found' => 'لم يتم العثور على الصفحة.',
'channel_not_found' => 'لم يتم العثور على القناة.',
'no_facebook_pages' => 'لم يتم العثور على صفحات Facebook. يجب أن تكون مشرفًا على صفحة واحدة على الأقل.',
'no_facebook_instagram_pages' => 'لم يتم العثور على صفحات Facebook مرتبطة بحسابات Instagram.',
'no_youtube_channels' => 'لم يتم العثور على قنوات YouTube. يرجى إنشاء قناة أولًا.',
'not_linkedin_admin' => 'أنت لست مشرفًا على أي صفحة LinkedIn.',
],
];

55
lang/ar/analytics.php Normal file
View file

@ -0,0 +1,55 @@
<?php
return [
'no_accounts' => 'لا توجد حسابات متصلة تحتوي على تحليلات.',
'no_accounts_match' => 'لا توجد حسابات مطابقة.',
'search_account' => 'البحث عن حساب…',
'select_account' => 'اختر حسابًا لعرض التحليلات.',
'no_data' => 'لا تتوفر بيانات تحليلات.',
'metrics' => [
'avg_view_duration' => 'متوسط مدة المشاهدة (ث)',
'avg_view_percentage' => 'متوسط نسبة المشاهدة',
'bookmarks' => 'الإشارات المرجعية',
'clicks' => 'النقرات',
'comments' => 'التعليقات',
'custom_reaction' => 'مخصص',
'engagement' => 'التفاعل',
'favourites' => 'المفضلة',
'followers' => 'المتابِعون',
'following' => 'المتابَعون',
'impressions' => 'مرات الظهور',
'interactions' => 'التفاعلات',
'likes' => 'الإعجابات',
'members' => 'الأعضاء',
'minutes_watched' => 'دقائق المشاهدة',
'organic_followers' => 'المتابِعون العضويون',
'outbound_clicks' => 'النقرات الصادرة',
'page_followers' => 'متابِعو الصفحة',
'page_reach' => 'وصول الصفحة',
'page_views' => 'مشاهدات الصفحة',
'paid_followers' => 'المتابِعون المدفوعون',
'pin_click_rate' => 'معدل النقر على الدبوس',
'pin_clicks' => 'نقرات الدبوس',
'posts_engagement' => 'تفاعل المنشورات',
'posts_reach' => 'وصول المنشورات',
'quotes' => 'الاقتباسات',
'reach' => 'الوصول',
'reblogs' => 'إعادات التدوين',
'recent_comments' => 'أحدث التعليقات',
'recent_likes' => 'أحدث الإعجابات',
'recent_shares' => 'أحدث المشاركات',
'replies' => 'الردود',
'reposts' => 'إعادات النشر',
'retweets' => 'إعادات التغريد',
'saves' => 'مرات الحفظ',
'shares' => 'المشاركات',
'subscribers' => 'المشتركون',
'subscribers_gained' => 'المشتركون الجدد',
'subscribers_lost' => 'المشتركون المفقودون',
'total_likes' => 'إجمالي الإعجابات',
'video_views' => 'مشاهدات الفيديو',
'videos' => 'مقاطع الفيديو',
'views' => 'المشاهدات',
],
];

52
lang/ar/assets.php Normal file
View file

@ -0,0 +1,52 @@
<?php
return [
'title' => 'الوسائط',
'tabs' => [
'my_uploads' => 'ملفاتي المرفوعة',
'stock_photos' => 'صور مجانية',
'gifs' => 'صور GIF',
],
'upload' => [
'drag_drop' => 'اسحب ملفاتك وأفلتها هنا، أو انقر للاختيار',
'formats' => 'JPEG، PNG، GIF، WebP، MP4، PDF',
'uploading' => 'جارٍ الرفع...',
'failed' => 'تعذر رفع :file. يرجى المحاولة مرة أخرى.',
],
'empty' => [
'title' => 'لا توجد وسائط بعد',
'description' => 'ارفع الصور ومقاطع الفيديو لبناء مكتبة الوسائط الخاصة بك.',
],
'save_to_assets' => 'حفظ في الوسائط',
'saved' => 'تم الحفظ في وسائطك!',
'create_post' => 'إنشاء منشور',
'add_to_post' => 'إضافة إلى المنشور',
'search_placeholder' => 'البحث في الوسائط...',
'delete' => [
'title' => 'حذف الوسائط',
'description' => 'هل أنت متأكد من رغبتك في حذف هذا العنصر؟ لا يمكن التراجع عن هذا الإجراء.',
'confirm' => 'حذف',
'cancel' => 'إلغاء',
],
'unsplash' => [
'search_placeholder' => 'البحث عن صور مجانية...',
'no_results' => 'لم يتم العثور على صور',
'no_results_description' => 'جرّب كلمة بحث مختلفة.',
'trending' => 'الرائج على Unsplash',
'start_searching' => 'ابحث عن صور مجانية من Unsplash',
],
'giphy' => [
'trending' => 'الرائج على Giphy',
'search_placeholder' => 'البحث عن صور GIF...',
'no_results' => 'لم يتم العثور على صور GIF',
'no_results_description' => 'جرّب كلمة بحث مختلفة.',
'powered_by' => 'مقدَّم من GIPHY',
],
];

141
lang/ar/auth.php Normal file
View file

@ -0,0 +1,141 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'بيانات الاعتماد هذه لا تطابق سجلاتنا.',
'password' => 'كلمة المرور المُدخلة غير صحيحة.',
'throttle' => 'عدد كبير جدًا من محاولات تسجيل الدخول. يرجى المحاولة مرة أخرى بعد :seconds ثانية.',
'flash' => [
'welcome' => 'مرحبًا بك في TryPost!',
'welcome_trial' => 'مرحبًا بك في TryPost! لقد بدأت فترتك التجريبية.',
],
'legal' => 'بمتابعتك، فإنك توافق على <a href="https://trypost.it/terms" target="_blank">شروط الخدمة</a> و<a href="https://trypost.it/privacy" target="_blank">سياسة الخصوصية</a>.',
'slides' => [
'calendar' => [
'title' => 'تقويم مرئي',
'description' => 'خطّط لمحتواك وجدوِله باستخدام تقويم بديهي يعتمد على السحب والإفلات عبر جميع حساباتك الاجتماعية.',
],
'scheduling' => [
'title' => 'جدولة ذكية',
'description' => 'جدوِل المنشورات عبر LinkedIn وX وInstagram وTikTok وYouTube والمزيد — كل ذلك من مكان واحد.',
],
'media' => [
'title' => 'وسائط غنية',
'description' => 'انشر الصور والعروض الدائرية والقصص ومقاطع الريلز. تحصل كل منصة على التنسيق المناسب تلقائيًا.',
],
'video' => [
'title' => 'نشر الفيديو',
'description' => 'ارفع مقاطع الفيديو مرة واحدة وانشرها على TikTok وYouTube Shorts وInstagram Reels وFacebook Reels.',
],
'team' => [
'title' => 'مساحات عمل جماعية',
'description' => 'ادعُ فريقك، وعيّن الأدوار، وأدِر عدة علامات تجارية من مساحات عمل منفصلة.',
],
'signatures' => [
'title' => 'التوقيعات',
'description' => 'احفظ توقيعات قابلة لإعادة الاستخدام (وسوم، روابط، خواتيم) وأضِفها إلى المنشورات بنقرة واحدة.',
],
],
'or_continue_with' => 'أو تابع باستخدام',
'or_continue_with_email' => 'أو تابع باستخدام البريد الإلكتروني',
'google_login' => 'تسجيل الدخول عبر Google',
'google_signup' => 'التسجيل عبر Google',
'github_login' => 'تسجيل الدخول عبر GitHub',
'github_signup' => 'التسجيل عبر GitHub',
'github_email_unavailable' => 'تعذر جلب بريدك الإلكتروني من GitHub. اجعل بريدك على GitHub عامًا أو امنح نطاق الوصول إلى البريد، ثم حاول مرة أخرى.',
'signup_success' => [
'page_title' => 'مرحبًا',
'title' => 'جارٍ إعداد حسابك',
'description' => 'يستغرق هذا عادةً بضع ثوانٍ فقط...',
],
'login' => [
'title' => 'تسجيل الدخول إلى حسابك',
'description' => 'أدخل بريدك الإلكتروني وكلمة المرور أدناه لتسجيل الدخول',
'page_title' => 'تسجيل الدخول',
'email' => 'البريد الإلكتروني',
'password' => 'كلمة المرور',
'forgot_password' => 'نسيت كلمة المرور؟',
'remember_me' => 'تذكّرني',
'submit' => 'تسجيل الدخول',
'no_account' => 'ليس لديك حساب؟',
'sign_up' => 'إنشاء حساب',
],
'register' => [
'title' => 'تقويمك الاجتماعي بالكامل، في مكان واحد',
'description' => 'أنشئ حسابك وابدأ جدولة المنشورات عبر كل شبكة.',
'page_title' => 'التسجيل',
'signup_with_email' => 'التسجيل بالبريد الإلكتروني',
'name' => 'الاسم',
'name_placeholder' => 'الاسم الكامل',
'email' => 'البريد الإلكتروني',
'password' => 'كلمة المرور',
'show_password' => 'إظهار كلمة المرور',
'hide_password' => 'إخفاء كلمة المرور',
'submit' => 'إنشاء حساب',
'has_account' => 'هل لديك حساب بالفعل؟',
'log_in' => 'تسجيل الدخول',
],
'forgot_password' => [
'title' => 'نسيت كلمة المرور',
'description' => 'أدخل بريدك الإلكتروني لاستلام رابط إعادة تعيين كلمة المرور',
'page_title' => 'نسيت كلمة المرور',
'email' => 'البريد الإلكتروني',
'submit' => 'إرسال رابط إعادة تعيين كلمة المرور',
'return_to' => 'أو، العودة إلى',
'log_in' => 'تسجيل الدخول',
],
'reset_password' => [
'title' => 'إعادة تعيين كلمة المرور',
'description' => 'يرجى إدخال كلمة المرور الجديدة أدناه',
'page_title' => 'إعادة تعيين كلمة المرور',
'email' => 'البريد الإلكتروني',
'password' => 'كلمة المرور',
'confirm_password' => 'تأكيد كلمة المرور',
'confirm_placeholder' => 'تأكيد كلمة المرور',
'submit' => 'إعادة تعيين كلمة المرور',
],
'verify_email' => [
'title' => 'تأكيد البريد الإلكتروني',
'description' => 'يرجى تأكيد بريدك الإلكتروني بالنقر على الرابط الذي أرسلناه إليك للتو.',
'page_title' => 'تأكيد البريد الإلكتروني',
'link_sent' => 'تم إرسال رابط تأكيد جديد إلى البريد الإلكتروني الذي قدّمته أثناء التسجيل.',
'resend' => 'إعادة إرسال بريد التأكيد',
'log_out' => 'تسجيل الخروج',
],
'accept_invite' => [
'page_title' => 'قبول الدعوة',
'title' => 'لقد تمت دعوتك!',
'description' => 'لقد تمت دعوتك للانضمام إلى مساحة العمل :workspace.',
'workspace' => 'مساحة العمل',
'your_role' => 'دورك',
'email' => 'البريد الإلكتروني',
'accept' => 'قبول الدعوة',
'decline' => 'رفض الدعوة',
'login_prompt' => 'سجّل الدخول أو أنشئ حسابًا لقبول هذه الدعوة.',
'log_in' => 'تسجيل الدخول',
'create_account' => 'إنشاء حساب',
],
];

411
lang/ar/automations.php Normal file
View file

@ -0,0 +1,411 @@
<?php
declare(strict_types=1);
return [
'title' => 'الأتمتة',
'default_name' => 'أتمتة جديدة',
'actions' => [
'new' => 'أتمتة جديدة',
'edit' => 'تعديل',
'save' => 'حفظ',
'activate' => 'تفعيل',
'pause' => 'إيقاف مؤقت',
'delete' => 'حذف',
'retry' => 'إعادة المحاولة',
'guide' => 'تعرّف على آلية العمل',
],
'tabs' => [
'build' => 'البناء',
'variables' => 'المتغيرات',
'test' => 'اختبار',
],
'nav' => [
'workflow' => 'سير العمل',
'invocations' => 'عمليات التشغيل',
'metrics' => 'المقاييس',
'settings' => 'الإعدادات',
],
'settings' => [
'general' => 'عام',
'general_description' => 'إعادة تسمية هذه الأتمتة.',
'name_label' => 'الاسم',
'name_saved' => 'تمت إعادة تسمية الأتمتة.',
'status_title' => 'الحالة',
'status_description' => 'فعّلها لبدء تشغيلها، أو أوقفها مؤقتًا للتوقف.',
'activated_at' => 'تم التفعيل :date',
'paused_at' => 'تم الإيقاف المؤقت :date',
'created_at' => 'تم الإنشاء :date',
'danger_title' => 'منطقة الخطر',
'danger_description' => 'إجراءات لا يمكن التراجع عنها.',
'delete_title' => 'حذف هذه الأتمتة',
'delete_description' => 'يزيل الأتمتة وسجل تشغيلها نهائيًا.',
],
'status_run' => [
'pending' => 'قيد الانتظار',
'running' => 'قيد التشغيل',
'waiting' => 'في الانتظار',
'completed' => 'مكتمل',
'failed' => 'فشل',
'cancelled' => 'مُلغى',
],
'node_type' => [
'trigger' => 'مُشغّل',
'generate' => 'إنشاء محتوى',
'delay' => 'تأخير',
'condition' => 'شرط',
'publish' => 'نشر',
'webhook' => 'Webhook',
'end' => 'إنهاء',
'fetch_rss' => 'جلب RSS',
'http_request' => 'طلب HTTP',
],
'invocations' => [
'empty' => 'لا توجد عمليات تشغيل بعد.',
'refresh' => 'تحديث',
'search_placeholder' => 'البحث عبر معرّف التشغيل…',
'copied' => 'تم نسخ معرّف التشغيل.',
'loading' => 'جارٍ تحميل الخطوات…',
'no_steps' => 'لم يتم تسجيل أي خطوات.',
'load_error' => 'تعذر تحميل الخطوات.',
'steps' => '{0}لا خطوات|{1}خطوة واحدة|{2}خطوتان|[3,10]:count خطوات|[11,*]:count خطوة',
'filter' => [
'all' => 'جميع الحالات',
],
'columns' => [
'timestamp' => 'الطابع الزمني',
'run' => 'التشغيل',
'status' => 'الحالة',
'message' => 'آخر رسالة',
'duration' => 'المدة',
],
'summary' => [
'completed' => 'اكتمل سير العمل',
'failed' => 'فشل سير العمل',
'running' => 'سير العمل قيد التشغيل',
'cancelled' => 'تم إلغاء سير العمل',
'pending' => 'سير العمل قيد الانتظار',
],
],
'metrics' => [
'overview' => 'نظرة عامة',
'runs_over_time' => 'عمليات التشغيل عبر الزمن',
'posts_by_platform' => 'المنشورات حسب المنصة',
'no_posts' => 'لم يتم نشر أي منشورات في هذه الفترة.',
'cards' => [
'runs' => 'إجمالي عمليات التشغيل',
'completed' => 'مكتملة',
'failed' => 'فاشلة',
'in_progress' => 'قيد التنفيذ',
'success_rate' => 'معدل النجاح',
'avg_duration' => 'متوسط المدة',
'posts_created' => 'المنشورات المُنشأة',
],
'legend' => [
'started' => 'بدأت',
'completed' => 'اكتملت',
'failed' => 'فشلت',
],
],
'categories' => [
'sources' => 'المصادر',
'content' => 'المحتوى',
'flow' => 'التدفق',
'output' => 'الإخراج',
],
'variables' => [
'title' => 'متغيرات سير العمل',
'hint' => 'قيم قابلة لإعادة الاستخدام يُشار إليها في أي مكان عبر {{ variables.KEY }}. تُخزَّن مشفّرة.',
'empty' => 'لا توجد متغيرات بعد.',
'key' => 'المفتاح',
'value' => 'القيمة',
'key_placeholder' => 'API_KEY',
'value_placeholder' => 'القيمة',
'add' => 'متغير جديد',
],
'expr' => [
'trigger_event' => 'اسم حدث المُشغّل',
'trigger_fired_at' => 'وقت إطلاق المُشغّل',
'trigger_post_id' => 'معرّف المنشور المُشغِّل',
'trigger_post_content' => 'محتوى المنشور المُشغِّل',
'trigger_post_status' => 'حالة المنشور المُشغِّل',
'trigger_post_scheduled_at' => 'وقت جدولة المنشور',
'trigger_post_published_at' => 'وقت نشر المنشور',
'fetched_title' => 'عنوان العنصر المجلوب',
'fetched_link' => 'رابط العنصر المجلوب',
'fetched_date' => 'تاريخ نشر العنصر المجلوب',
'fetched_content' => 'المحتوى الكامل للعنصر المجلوب',
'fetched_description' => 'ملخص العنصر المجلوب',
'fetched_author' => 'كاتب العنصر المجلوب',
'fetched_image' => 'رابط صورة العنصر المجلوب',
'fetched_categories' => 'فئات العنصر المجلوب',
'fetched_enclosure' => 'وسائط العنصر المجلوب (صوت/فيديو/ملف)',
'fetched_pubdate' => 'تاريخ نشر العنصر المجلوب',
'fetched_http' => 'عنصر HTTP المجلوب (أضِف حقلًا)',
'generated_content' => 'محتوى المنشور المُنشأ بالذكاء الاصطناعي',
'generated_post_url' => 'رابط المنشور المُنشأ بالذكاء الاصطناعي',
'variable' => 'متغير سير العمل',
'now' => 'التاريخ والوقت الحالي',
],
'test' => [
'description' => 'يشغّل الأتمتة من البداية إلى النهاية باستخدام حمولة مُشغِّل مُصطنعة. مفيد للتحقق من كل عقدة دون انتظار الجدول أو الخلاصة الحقيقية.',
'starting' => 'جارٍ بدء تشغيل الاختبار…',
'in_progress' => 'قيد التنفيذ',
'completed' => 'مكتمل',
'failed' => 'فشل',
'waiting' => 'في الانتظار',
'close' => 'إغلاق',
'no_node_runs' => 'في انتظار بدء العقدة الأولى…',
'node_input' => 'المدخلات',
'node_output' => 'المخرجات',
'node_error' => 'خطأ',
'no_new_items' => 'لا توجد عناصر جديدة — لم يُشغَّل أي شيء لاحق.',
'error_starting' => 'تعذر بدء تشغيل الاختبار.',
'with_real_data' => 'ببيانات حقيقية',
'run' => 'تشغيل الاختبار',
'idle_hint' => 'اضغط على "تشغيل الاختبار" لتنفيذ الأتمتة من البداية إلى النهاية.',
'real_data_hint' => 'سيقوم هذا الاختبار بنشر المنشورات، وتقديم علامات الاستطلاع، وإطلاق تأثيرات جانبية خارجية.',
'dry_badge' => 'تشغيل تجريبي',
],
'status' => [
'draft' => 'مسودة',
'active' => 'نشط',
'paused' => 'متوقف مؤقتًا',
],
'index' => [
'empty_title' => 'لا توجد عمليات أتمتة بعد',
'empty_description' => 'أنشئ أول أتمتة لك لبدء النشر تلقائيًا.',
'columns' => [
'name' => 'الاسم',
'status' => 'الحالة',
'created' => 'تاريخ الإنشاء',
],
],
'form' => [
'activate_error_fallback' => 'تعذر تفعيل الأتمتة.',
'pause_error_fallback' => 'تعذر إيقاف الأتمتة مؤقتًا.',
'save_error_fallback' => 'تعذر حفظ الأتمتة.',
'save_success' => 'تم حفظ الأتمتة.',
'empty_canvas_title' => 'ابدأ ببناء أتمتتك',
'empty_canvas_description' => 'اسحب عقدة من اللوحة الجانبية للبدء.',
'name_placeholder' => 'أتمتة بلا عنوان',
],
'nodes' => [
'trigger' => 'مُشغّل',
'generate' => 'إنشاء',
'delay' => 'تأخير',
'condition' => 'شرط',
'publish' => 'نشر',
'webhook' => 'Webhook',
'end' => 'إنهاء',
'end_summary' => 'يوقف الأتمتة هنا',
'fetch_rss' => 'جلب RSS',
'http_request' => 'طلب HTTP',
'handles' => [
'items' => 'يحتوي على عناصر',
'no_items' => 'لا عناصر',
],
],
'config' => [
'select_placeholder' => 'اختر…',
'invalid_json' => 'هذا ليس JSON صالحًا بعد.',
'expand_editor' => 'توسيع المحرر',
'minimize_editor' => 'تصغير',
'trigger' => [
'type' => 'نوع المُشغّل',
'types' => [
'schedule' => 'جدولة',
'post_published' => 'عند نشر منشور',
'post_scheduled' => 'عند جدولة منشور',
],
'post_published_hint' => 'يعمل كلما تم نشر أي منشور في مساحة العمل هذه. يصبح المنشور المنشور متاحًا في {{ trigger.post }} للعقد اللاحقة.',
'post_scheduled_hint' => 'يعمل كلما تمت جدولة أي منشور في مساحة العمل هذه. يكون المنشور المجدول متاحًا في {{ trigger.post }}.',
'schedule' => [
'field' => 'فاصل المُشغّل',
'fields' => [
'minutes' => 'دقائق',
'hours' => 'ساعات',
'days' => 'أيام',
'weeks' => 'أسابيع',
'months' => 'أشهر',
],
'minutes_interval' => 'الدقائق بين عمليات التشغيل',
'hours_interval' => 'الساعات بين عمليات التشغيل',
'days_interval' => 'الأيام بين عمليات التشغيل',
'hour' => 'التشغيل عند الساعة',
'minute' => 'التشغيل عند الدقيقة',
'weekdays' => 'التشغيل في أيام الأسبوع',
'day_of_month' => 'يوم من الشهر',
'weekday_names' => [
'sun' => 'أحد',
'mon' => 'اثنين',
'tue' => 'ثلاثاء',
'wed' => 'أربعاء',
'thu' => 'خميس',
'fri' => 'جمعة',
'sat' => 'سبت',
],
'summary' => [
'every_n_minutes' => '{1}يعمل كل دقيقة|{2}يعمل كل دقيقتين|[3,10]يعمل كل :count دقائق|[11,*]يعمل كل :count دقيقة',
'every_n_hours' => '{1}يعمل كل ساعة عند الدقيقة :minute|{2}يعمل كل ساعتين عند الدقيقة :minute|[3,10]يعمل كل :count ساعات عند الدقيقة :minute|[11,*]يعمل كل :count ساعة عند الدقيقة :minute',
'every_n_days' => '{1}يعمل كل يوم عند :time|{2}يعمل كل يومين عند :time|[3,10]يعمل كل :count أيام عند :time|[11,*]يعمل كل :count يوم عند :time',
'weekly' => 'يعمل كل :days عند :time',
'monthly' => 'يعمل في اليوم :day من كل شهر عند :time',
],
],
],
'generate' => [
'social_accounts' => 'الحسابات الاجتماعية',
'social_accounts_empty' => 'لا توجد حسابات اجتماعية متصلة. اربط واحدًا أولًا.',
'target_slide_count' => 'الشرائح المراد إنشاؤها',
'prompt_template' => 'قالب الموجّه',
'prompt_template_hint' => 'اكتب {{ لإدراج بيانات من الخطوات السابقة.',
'image_count' => 'الصور المراد إنشاؤها',
'image_count_hint' => '0 = منشور نصي فقط (بلا صورة). 1 = صورة واحدة. 2 أو أكثر = عرض دائري.',
'use_brand_voice' => 'استخدام صوت العلامة التجارية',
'use_brand_voice_hint' => 'طبّق وصف علامتك التجارية وصوتها. أوقفه للتنسيق الأمين لمصادر الجهات الخارجية (الأخبار، RSS).',
'use_brand_visuals' => 'استخدام العناصر المرئية للعلامة التجارية',
'use_brand_visuals_hint' => 'وجّه صور الذكاء الاصطناعي بألوان علامتك التجارية وهويتها. أوقفه للصور المحايدة المدفوعة بموضوع المنشور فقط.',
'style' => 'النمط',
'account_summary' => '{1}حساب واحد · :format|{2}حسابان · :format|[3,10]:count حسابات · :format|[11,*]:count حساب · :format',
'formats' => [
'single' => 'مفرد',
'carousel' => 'عرض دائري',
],
],
'delay' => [
'duration' => 'المدة',
'unit' => 'الوحدة',
'units' => [
'minutes' => 'دقائق',
'hours' => 'ساعات',
'days' => 'أيام',
],
],
'condition' => [
'field' => 'الحقل',
'operator' => 'العامل',
'operators' => [
'contains' => 'يحتوي على',
'not_contains' => 'لا يحتوي على',
'equals' => 'يساوي',
'not_equals' => 'لا يساوي',
'matches' => 'يطابق (تعبير نمطي)',
'greater_than' => 'أكبر من',
'less_than' => 'أصغر من',
],
'value' => 'القيمة',
],
'publish' => [
'mode' => 'الوضع',
'modes' => [
'now' => 'نشر الآن',
'scheduled' => 'جدولة',
'draft' => 'حفظ كمسودة',
],
'scheduled_offset' => 'الإزاحة عن المُشغّل (بالدقائق)',
'offset_summary' => ':mode · +:offset د',
],
'webhook' => [
'url' => 'الرابط',
'method' => 'الطريقة',
'payload_template' => 'قالب الحمولة (JSON)',
],
'end' => [
'reason' => 'السبب (اختياري)',
'reason_placeholder' => 'مثال: تمت تصفيته بواسطة شرط',
],
'fetch_rss' => [
'feed_url' => 'رابط الخلاصة',
'feed_url_hint' => 'في التشغيل الأول، تُضبط العلامة على "الآن" حتى لا تُغرِق العناصر التاريخية العقد اللاحقة. تشاهد عمليات التشغيل اللاحقة فقط العناصر الأحدث من الاستطلاع السابق.',
'inspect' => 'فحص الخلاصة',
'inspecting' => 'جارٍ الفحص…',
'inspect_hint' => 'اجلب عينة لاكتشاف الحقول المتاحة للاستخدام في العقد اللاحقة.',
'inspect_error' => 'تعذرت قراءة هذه الخلاصة. تحقق من الرابط وحاول مرة أخرى.',
'discovered_fields' => 'الحقول المتاحة',
'discovered_empty' => 'لم يتم العثور على حقول في أحدث عنصر.',
],
'http_request' => [
'url' => 'الرابط',
'method' => 'الطريقة',
'auth_type' => 'المصادقة',
'auth' => [
'none' => 'بلا (عام)',
'bearer' => 'رمز Bearer',
'basic' => 'مصادقة أساسية',
'api_key' => 'ترويسة مفتاح API',
],
'bearer_token' => 'رمز Bearer',
'basic_username' => 'اسم المستخدم',
'basic_password' => 'كلمة المرور',
'api_key_header' => 'اسم الترويسة',
'api_key_value' => 'مفتاح API',
'body_template' => 'قالب النص (JSON)',
'headers' => 'الترويسات',
'header_name' => 'اسم الترويسة',
'header_value' => 'القيمة',
'add_header' => 'إضافة ترويسة',
'polling_section' => 'القائمة وإزالة التكرار (اختياري)',
'polling_hint' => 'عندما تكون الاستجابة قائمة، يشغّل كل عنصر سير العمل بشكل منفصل. يشغّل الكائن الواحد مرة واحدة.',
'items_path' => 'مسار العناصر',
'items_path_hint' => 'اتركه فارغًا إذا كانت الاستجابة مصفوفة بالفعل. استخدم مسارًا منقّطًا (مثل data.items) لمصفوفة متداخلة، أو * لكائن مفهرس بالمعرّف.',
'item_key_path' => 'مسار مفتاح العنصر',
'item_key_path_hint' => 'مسار JSON لمعرّف فريد (مثل id). تُتخطى العناصر التي سبقت رؤيتها، لذا تظل الخلاصة بلا تواريخ تُمرّر الإدخالات الجديدة فقط.',
'item_date_path' => 'مسار تاريخ العنصر',
'item_date_path_hint' => 'مسار JSON للطابع الزمني للعنصر (مثل published_at). يُفضَّل على مسار المفتاح عند توفره. يسجّل الاستطلاع الأول الأساس ولا يمرّر شيئًا، لذا لا تُغرِق الخلاصة الموجودة في اليوم الأول.',
],
],
'delete' => [
'title' => 'حذف الأتمتة',
'description' => 'هل أنت متأكد من رغبتك في حذف هذه الأتمتة؟ ستتم إزالة جميع عمليات التشغيل وعناصر التشغيل أيضًا. لا يمكن التراجع عن هذا الإجراء.',
'confirm' => 'حذف',
'cancel' => 'إلغاء',
],
'flash' => [
'deleted' => 'تم حذف الأتمتة بنجاح!',
],
'errors' => [
'no_active_social_accounts' => 'لا توجد حسابات اجتماعية نشطة مُهيّأة لهذه الأتمتة.',
'must_have_one_trigger' => 'يجب أن تحتوي الأتمتة على عقدة مُشغّل واحدة بالضبط.',
'trigger_must_be_connected' => 'يجب أن تكون عقدة المُشغّل متصلة بعقدة واحدة على الأقل.',
'graph_contains_cycle' => 'يحتوي مخطط الأتمتة على حلقة.',
'only_failed_can_retry' => 'يمكن إعادة محاولة عمليات التشغيل الفاشلة فقط.',
'no_generated_post' => 'لم يتم العثور على منشور مُنشأ في التشغيل.',
'webhook_server_error' => 'خطأ في خادم Webhook.',
'webhook_request_failed' => 'تعذر إكمال طلب Webhook.',
'webhook_missing_url' => 'عقدة Webhook تفتقد إلى رابط.',
'webhook_invalid_payload_json' => 'قالب الحمولة ليس JSON صالحًا.',
'url_not_allowed' => 'رابط الطلب يشير إلى عنوان خاص أو غير قابل للوصول وتم حظره.',
'node_no_longer_exists' => 'العقدة :node_id لم تعد موجودة في الأتمتة.',
'no_trigger_connection' => 'لا توجد عقدة متصلة بعقدة المُشغّل.',
'fetch_rss_missing_url' => 'عقدة جلب RSS تفتقد إلى رابط خلاصة.',
'fetch_rss_request_failed' => 'فشل طلب خلاصة RSS.',
'fetch_rss_malformed' => 'خلاصة RSS مشوّهة.',
'http_missing_url' => 'عقدة طلب HTTP تفتقد إلى رابط.',
'http_request_exception' => 'أطلق طلب HTTP استثناءً.',
'http_request_failed' => 'فشل طلب HTTP.',
'http_items_path_not_array' => 'لم يُفضِ مسار العناصر إلى قائمة.',
],
];

76
lang/ar/billing.php Normal file
View file

@ -0,0 +1,76 @@
<?php
return [
'title' => 'الفوترة',
'past_due_notice' => [
'title' => 'دفعة متأخرة',
'description' => 'حدّث طريقة الدفع للحفاظ على اشتراكك نشطًا.',
'cta' => 'تحديث الدفع',
],
'annual_banner' => [
'title' => 'احصل على شهرين مجانًا',
'description' => 'انتقل إلى الفوترة السنوية وادفع أقل كل شهر — الخطة نفسها، لا شيء آخر يتغير.',
'cta' => 'الترقية إلى السنوية',
],
'subscribe' => [
'billed_monthly' => 'فوترة شهرية',
'billed_yearly' => 'فوترة سنوية',
'prices' => [
'workspace' => ['monthly' => '$12', 'yearly_per_month' => '$10', 'yearly' => '$120'],
],
],
'plan' => [
'title' => 'الخطة',
'description' => 'إدارة خطة اشتراكك.',
'label' => 'الخطة',
'workspaces' => '{1}مساحة عمل واحدة|{2}مساحتا عمل|[3,10]:count مساحات عمل|[11,*]:count مساحة عمل',
'per_workspace' => 'لكل مساحة عمل',
'price' => 'السعر',
'month' => 'شهر',
'trial' => 'تجريبي',
'active' => 'نشط',
'past_due' => 'متأخر',
'cancelling' => 'قيد الإلغاء',
'trial_ends' => 'تنتهي الفترة التجريبية',
],
'subscription' => [
'title' => 'الاشتراك',
'description' => 'إدارة طريقة الدفع وتفاصيل الفوترة والاشتراك.',
'payment_method' => 'طريقة الدفع',
'no_payment_method' => 'لا توجد طريقة دفع مسجّلة بعد.',
'expires_on' => 'تنتهي في :month/:year',
'manage_label' => 'الاشتراك',
'manage_stripe' => 'الإدارة عبر Stripe',
],
'invoices' => [
'title' => 'الفواتير',
'description' => 'نزّل فواتيرك السابقة.',
'empty' => 'لم يتم العثور على فواتير',
'paid' => 'مدفوعة',
],
'flash' => [
'plan_changed' => 'أنت الآن على خطة :plan.',
'switched_to_yearly' => 'أنت الآن على الفوترة السنوية.',
'cannot_manage' => 'يمكن لمالك الحساب فقط إدارة الفوترة.',
'credits_exhausted' => 'نفد رصيد الذكاء الاصطناعي — تم استخدام مخصصك الشهري البالغ :limit. رقِّ خطتك أو انتظر حتى الشهر المقبل.',
'subscription_required' => 'يلزم وجود اشتراك نشط لاستخدام ميزات الذكاء الاصطناعي.',
],
'processing' => [
'page_title' => 'جارٍ المعالجة...',
'title' => 'جارٍ معالجة اشتراكك',
'description' => 'يرجى الانتظار بينما نُعِدّ حسابك. لن يستغرق هذا سوى لحظة.',
'success_title' => 'كل شيء جاهز!',
'success_description' => 'اشتراكك نشط. جارٍ إعادة توجيهك إلى مساحات عملك...',
'cancelled_title' => 'تم إلغاء الدفع',
'cancelled_description' => 'تم إلغاء عملية الدفع. لم تُجرَ أي رسوم.',
'retry' => 'إعادة المحاولة',
],
];

39
lang/ar/brands.php Normal file
View file

@ -0,0 +1,39 @@
<?php
return [
'new_brand' => 'علامة تجارية جديدة',
'no_brands_yet' => 'لا توجد علامات تجارية بعد',
'no_brands_description' => 'أنشئ علامات تجارية لتنظيم حساباتك الاجتماعية حسب العميل أو المشروع',
'accounts_count' => ':count حساب',
'create' => [
'title' => 'إنشاء علامة تجارية',
'description' => 'امنح علامتك التجارية اسمًا لتجميع الحسابات الاجتماعية',
'name' => 'اسم العلامة التجارية',
'name_placeholder' => 'مثال: Acme Corp، شخصي',
'submit' => 'إنشاء علامة تجارية',
'submitting' => 'جارٍ الإنشاء...',
],
'edit' => [
'title' => 'تعديل العلامة التجارية',
'description' => 'تحديث اسم هذه العلامة التجارية',
'name' => 'اسم العلامة التجارية',
'name_placeholder' => 'مثال: Acme Corp، شخصي',
'submit' => 'حفظ التغييرات',
'submitting' => 'جارٍ الحفظ...',
],
'delete' => [
'title' => 'حذف العلامة التجارية',
'description' => 'هل أنت متأكد من رغبتك في حذف هذه العلامة التجارية؟ سيتم إلغاء تعيين الحسابات الاجتماعية دون حذفها.',
'confirm' => 'حذف',
'cancel' => 'إلغاء',
],
'flash' => [
'created' => 'تم إنشاء العلامة التجارية بنجاح!',
'updated' => 'تم تحديث العلامة التجارية بنجاح!',
'deleted' => 'تم حذف العلامة التجارية بنجاح!',
],
];

12
lang/ar/calendar.php Normal file
View file

@ -0,0 +1,12 @@
<?php
return [
'title' => 'التقويم',
'today' => 'اليوم',
'day' => 'يوم',
'week' => 'أسبوع',
'month' => 'شهر',
'new_post' => 'منشور جديد',
'no_content' => 'لا يوجد محتوى',
'more' => '+:count المزيد',
];

18
lang/ar/comments.php Normal file
View file

@ -0,0 +1,18 @@
<?php
return [
'placeholder' => 'اكتب تعليقًا...',
'reply_placeholder' => 'اكتب ردًا...',
'reply' => 'رد',
'edit' => 'تعديل',
'delete' => 'حذف',
'edited' => 'تم التعديل',
'save' => 'حفظ',
'cancel' => 'إلغاء',
'send' => 'إرسال',
'replying_to' => 'رد على :name',
'empty' => 'لا توجد تعليقات بعد. ابدأ المحادثة.',
'load_more' => 'تحميل التعليقات الأقدم',
'today' => 'اليوم',
'yesterday' => 'أمس',
];

67
lang/ar/common.php Normal file
View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
return [
'back' => 'رجوع',
'beta' => 'تجريبي',
'confirm_modal' => [
'cannot_be_undone' => 'لا يمكن التراجع عن هذا الإجراء.',
'type' => 'اكتب',
'to_confirm' => 'للتأكيد.',
'copy_to_clipboard' => 'نسخ إلى الحافظة',
'delete_keyword' => 'حذف',
],
'photo_upload' => [
'upload' => 'رفع',
'uploading' => 'جارٍ الرفع...',
'remove' => 'إزالة الصورة',
'hint' => 'موصى به: صورة مربعة، بحد أقصى 2 ميغابايت.',
'crop_title' => 'قص الصورة',
'crop_description' => 'حدّد المنطقة التي تريد الاحتفاظ بها.',
'crop_hint' => 'اسحب للتحريك، أو زاوية لتغيير الحجم.',
'crop_save' => 'حفظ',
'crop_cancel' => 'إلغاء',
'crop_error' => 'تعذّر تحميل هذه الصورة. جرّب ملفًا آخر.',
],
'timezone' => [
'select' => 'اختر المنطقة الزمنية',
'search' => 'البحث عن منطقة زمنية...',
'empty' => 'لم يتم العثور على منطقة زمنية',
],
'date_picker' => [
'select' => 'اختر التاريخ',
],
'date_range_picker' => [
'placeholder' => 'اختر نطاقًا زمنيًا',
'today' => 'اليوم',
'yesterday' => 'أمس',
'last_7_days' => 'آخر 7 أيام',
'last_30_days' => 'آخر 30 يومًا',
'last_3_months' => 'آخر 3 أشهر',
'last_6_months' => 'آخر 6 أشهر',
'last_12_months' => 'آخر 12 شهرًا',
'this_month' => 'هذا الشهر',
'last_month' => 'الشهر الماضي',
'year_to_date' => 'منذ بداية العام',
'last_year' => 'العام الماضي',
],
'cancel' => 'إلغاء',
'clear' => 'مسح',
'close' => 'إغلاق',
'loading_more' => 'جارٍ تحميل المزيد...',
'actions' => [
'copy' => 'نسخ',
'copied' => 'تم النسخ',
'copy_failed' => 'فشل النسخ إلى الحافظة',
],
];

54
lang/ar/labels.php Normal file
View file

@ -0,0 +1,54 @@
<?php
return [
'title' => 'التسميات',
'description' => 'أنشئ تسميات لتنظيم منشوراتك وتصنيفها',
'search' => 'البحث في التسميات...',
'new_label' => 'تسمية جديدة',
'no_labels_yet' => 'لا توجد تسميات بعد',
'no_search_results' => 'لا توجد تسميات مطابقة لبحثك',
'try_different_search' => 'جرّب كلمة مختلفة أو امسح البحث.',
'create_first_label' => 'أنشئ أول تسمية لك',
'table' => [
'name' => 'الاسم',
'created_at' => 'تاريخ الإنشاء',
],
'actions' => [
'edit' => 'تعديل التسمية',
'delete' => 'حذف التسمية',
],
'create' => [
'title' => 'إنشاء تسمية',
'description' => 'امنح تسميتك اسمًا واختر لونًا',
'name' => 'الاسم',
'name_placeholder' => 'أدخل اسم التسمية...',
'color' => 'اللون',
'submit' => 'إنشاء تسمية',
'submitting' => 'جارٍ الإنشاء...',
],
'edit' => [
'title' => 'تعديل التسمية',
'description' => 'تحديث اسم ولون هذه التسمية',
'name' => 'الاسم',
'name_placeholder' => 'أدخل اسم التسمية...',
'color' => 'اللون',
'submit' => 'حفظ التغييرات',
'submitting' => 'جارٍ الحفظ...',
],
'delete' => [
'title' => 'حذف التسمية',
'description' => 'هل أنت متأكد من رغبتك في حذف هذه التسمية؟ لا يمكن التراجع عن هذا الإجراء.',
'confirm' => 'حذف',
'cancel' => 'إلغاء',
],
'flash' => [
'created' => 'تم إنشاء التسمية بنجاح!',
'updated' => 'تم تحديث التسمية بنجاح!',
'deleted' => 'تم حذف التسمية بنجاح!',
],
];

22
lang/ar/mail.php Normal file
View file

@ -0,0 +1,22 @@
<?php
return [
'mentioned' => [
'subject' => 'أشار إليك :name على TryPost',
'title' => 'أشار إليك :name',
'intro' => 'أشار إليك :name في تعليق على منشور.',
'cta' => 'عرض التعليق',
],
'workspace_connections_disconnected' => [
'subject' => '{1} حساب واحد يحتاج إلى إعادة الربط في :workspace|{2} حسابان يحتاجان إلى إعادة الربط في :workspace|[3,10] :count حسابات تحتاج إلى إعادة الربط في :workspace|[11,*] :count حسابًا يحتاج إلى إعادة الربط في :workspace',
'title' => 'حسابات تحتاج إلى إعادة الربط',
'intro' => 'تم فصل الحسابات الاجتماعية التالية في مساحة العمل <strong>:workspace</strong> وتحتاج إلى إعادة الربط:',
'reasons_title' => 'قد يكون هذا قد حدث بسبب:',
'reason_expired' => 'انتهاء صلاحية رموز الوصول',
'reason_revoked' => 'قيامك بإلغاء وصول TryPost على المنصة',
'reason_changed' => 'قيام المنصة بتغيير متطلبات المصادقة الخاصة بها',
'reconnect_cta' => 'يرجى إعادة ربط هذه الحسابات لمواصلة جدولة المنشورات ونشرها.',
'button' => 'إعادة ربط الحسابات',
],
];

18
lang/ar/notifications.php Normal file
View file

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
return [
'post_ready' => [
'title' => 'منشورك جاهز',
'body' => 'أنهى الذكاء الاصطناعي عمله للتو. انقر للمراجعة والنشر.',
],
'account_disconnected' => [
'title' => 'تم فصل حساب :platform',
'body' => 'يحتاج :account إلى إعادة الربط',
],
'account_token_expired' => [
'title' => 'يحتاج حساب :platform إلى إعادة الربط',
'body' => 'انتهت جلسة :account — يرجى إعادة الربط لمواصلة النشر',
],
];

41
lang/ar/onboarding.php Normal file
View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
return [
'title' => 'مرحبًا بك في TryPost',
'description' => 'أخبرنا بما يصفك أنت أو نشاطك التجاري على أفضل وجه حتى نتمكن من تخصيص تجربتك.',
'continue' => 'متابعة',
'personas' => [
'creator' => 'صانع محتوى',
'freelancer' => 'مستقل',
'developer' => 'مطوّر',
'startup' => 'شركة ناشئة',
'agency' => 'وكالة',
'small_business' => 'نشاط تجاري صغير',
'marketer' => 'مسوّق',
'online_store' => 'متجر إلكتروني',
'other' => 'أخرى',
],
'goals_title' => 'ما هدفك من استخدام TryPost؟',
'goals_description' => 'اختر كل ما يناسبك وسنقوم بإعداد TryPost من أجلك.',
'goals' => [
'save_time' => 'توفير الوقت بالنشر في كل مكان دفعة واحدة',
'ai_content' => 'إنشاء منشورات أسرع بالذكاء الاصطناعي',
'plan_calendar' => 'التخطيط لمنشوراتي على التقويم',
'stay_on_brand' => 'الحفاظ على اتساق كل منشور مع العلامة التجارية',
'grow_audience' => 'تنمية جمهوري وزيادة التفاعل',
'drive_sales' => 'الحصول على المزيد من الزيارات والمبيعات',
'manage_clients' => 'إدارة عدة علامات تجارية أو عملاء',
'team_collaboration' => 'العمل مع فريقي',
'automate_api' => 'أتمتة النشر عبر الواجهة البرمجية أو MCP أو الكود',
'track_performance' => 'معرفة أداء منشوراتي',
'just_exploring' => 'مجرد استكشاف في الوقت الحالي',
'other' => 'شيء آخر',
],
'connect' => [
'title' => 'اربط شبكتك الأولى',
'description' => 'اربط حسابًا اجتماعيًا واحدًا على الأقل لبدء الجدولة. يمكنك إضافة المزيد في أي وقت.',
'must_connect' => 'اربط شبكة واحدة على الأقل للمتابعة.',
],
];

19
lang/ar/pagination.php Normal file
View file

@ -0,0 +1,19 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; السابق',
'next' => 'التالي &raquo;',
];

22
lang/ar/passwords.php Normal file
View file

@ -0,0 +1,22 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| outcome such as failure due to an invalid password / reset token.
|
*/
'reset' => 'تمت إعادة تعيين كلمة المرور الخاصة بك.',
'sent' => 'لقد أرسلنا رابط إعادة تعيين كلمة المرور إلى بريدك الإلكتروني.',
'throttled' => 'يرجى الانتظار قبل المحاولة مرة أخرى.',
'token' => 'رمز إعادة تعيين كلمة المرور هذا غير صالح.',
'user' => 'لا يمكننا العثور على مستخدم بهذا البريد الإلكتروني.',
];

671
lang/ar/posts.php Normal file
View file

@ -0,0 +1,671 @@
<?php
return [
'title' => 'المنشورات',
'search' => 'البحث في المنشورات...',
'all_posts' => 'جميع المنشورات',
'new_post' => 'منشور جديد',
'no_posts' => 'لم يتم العثور على منشورات',
'no_search_results' => 'لا توجد منشورات مطابقة لبحثك',
'try_different_search' => 'جرّب كلمة مختلفة أو امسح البحث.',
'start_creating' => 'ابدأ بإنشاء أول منشور لك.',
'filter_by_label' => 'التصفية حسب التسمية',
'label_search_placeholder' => 'البحث في التسميات...',
'no_labels' => 'لم يتم العثور على تسميات.',
'clear_label_filter' => 'مسح تصفية التسميات',
'table' => [
'post' => 'المنشور',
'status' => 'الحالة',
'content' => 'المحتوى',
'platforms' => 'المنصات',
'labels' => 'التسميات',
'scheduled_at' => 'التاريخ',
'actions' => '',
],
'manage_posts' => 'إدارة جميع منشوراتك',
'delete_confirm' => 'هل أنت متأكد من رغبتك في حذف هذا المنشور؟',
'by' => 'بواسطة',
'actions' => [
'view' => 'عرض المنشور',
'delete' => 'حذف',
'duplicate' => 'تكرار',
'copy_id' => 'نسخ المعرّف',
'copied' => 'تم نسخ المعرّف إلى الحافظة',
],
'form' => [
'post_type' => 'نوع المنشور',
'board' => 'اللوحة',
'select_board' => 'اختر لوحة',
'search_board' => 'البحث عن لوحة...',
'no_board_found' => 'لم يتم العثور على لوحة',
'media' => 'الوسائط',
'min' => 'الحد الأدنى',
'uploading' => 'جارٍ الرفع...',
'drop_to_upload' => 'أفلِت للرفع',
'drag_and_drop' => 'اسحب وأفلِت أو انقر للرفع',
'photos_and_videos' => 'الصور ومقاطع الفيديو',
'photos_only' => 'الصور فقط',
'videos_only' => 'مقاطع الفيديو فقط',
'drag_to_reorder' => 'اسحب لإعادة الترتيب',
'caption' => 'التسمية التوضيحية',
'write_caption' => 'اكتب التسمية التوضيحية...',
'content_exceeds_platform' => ':platform: أطول بمقدار :over حرفًا (الحد الأقصى :limit).',
'tiktok' => [
'settings' => 'إعدادات TikTok',
'variant_label' => 'نوع المنشور',
'variant' => [
'video' => 'فيديو',
'photo' => 'عرض صور دائري',
],
'posting_to' => 'النشر إلى',
'privacy_level' => 'من يمكنه رؤية هذا الفيديو؟',
'privacy_placeholder' => 'اختر من يمكنه مشاهدة هذا المنشور',
'privacy' => [
'public' => 'عام للجميع',
'friends' => 'الأصدقاء المتابَعون بشكل متبادل',
'followers' => 'المتابِعون',
'private' => 'أنا فقط',
'private_disabled_branded' => 'لا يمكن ضبط ظهور المحتوى ذي العلامة التجارية على خاص.',
],
'privacy_hint' => 'تعتمد الخيارات المتاحة على إعدادات حسابك على TikTok.',
'auto_add_music' => 'إضافة موسيقى تلقائيًا',
'auto_add_music_hint' => 'تتوفر هذه الميزة للصور فقط. ستضيف موسيقى افتراضية يمكنك تغييرها لاحقًا.',
'yes' => 'نعم',
'no' => 'لا',
'allow_users' => 'السماح للمستخدمين بـ:',
'comments' => 'التعليق',
'duet' => 'الديو (Duet)',
'stitch' => 'الدمج (Stitch)',
'is_aigc' => 'فيديو مُنشأ بالذكاء الاصطناعي',
'disclose' => 'الإفصاح عن محتوى الفيديو',
'disclose_hint' => 'فعّله للإفصاح عن أن هذا الفيديو يروّج لسلع أو خدمات مقابل شيء ذي قيمة. قد يروّج الفيديو لك أو لطرف ثالث أو كليهما.',
'promotional_organic_title' => 'ستُصنَّف صورتك/فيديوك على أنها "محتوى ترويجي".',
'promotional_paid_title' => 'ستُصنَّف صورتك/فيديوك على أنها "شراكة مدفوعة".',
'promotional_description' => 'لا يمكن تغيير هذا بمجرد نشر الفيديو.',
'compliance_incomplete' => 'يجب أن تحدد ما إذا كان محتواك يروّج لك أو لطرف ثالث أو كليهما.',
'privacy_required' => 'مستوى الخصوصية على TikTok مطلوب عند النشر.',
'branded_cleared_private' => 'تم مسح الخصوصية لأن المحتوى ذا العلامة التجارية لا يمكن أن يكون خاصًا.',
'interaction_disabled_by_creator' => 'مُعطَّل في إعدادات حسابك على TikTok',
'max_duration_exceeded' => 'مدة الفيديو :duration ث لكن هذا الحساب يمكنه نشر مقاطع فيديو حتى :max ث فقط.',
'processing_hint' => 'بعد النشر، قد يستغرق معالجة المحتوى وظهوره على ملفك الشخصي في TikTok بضع دقائق.',
'brand_organic' => 'علامتك التجارية',
'brand_organic_hint' => 'أنت تروّج لنفسك أو لعلامتك التجارية الخاصة. سيُصنَّف هذا الفيديو على أنه محتوى عضوي للعلامة التجارية.',
'brand_content' => 'محتوى ذو علامة تجارية',
'brand_content_hint' => 'أنت تروّج لعلامة تجارية أخرى أو لطرف ثالث. سيُصنَّف هذا الفيديو على أنه محتوى ذو علامة تجارية.',
'compliance' => [
'agree' => 'بالنشر، فإنك توافق على',
'music_usage' => 'تأكيد استخدام الموسيقى',
'and' => 'و',
'branded_policy' => 'سياسة المحتوى ذي العلامة التجارية',
],
],
'instagram' => [
'settings' => 'إعدادات Instagram',
'posting_to' => 'النشر إلى',
'variant_label' => 'نوع المنشور',
'variant' => [
'feed' => 'منشور',
'reel' => 'ريل',
'story' => 'قصة',
],
'aspect_label' => 'نسبة العرض إلى الارتفاع',
'aspect' => [
'square' => 'مربع (1:1)',
'portrait' => 'عمودي (4:5)',
'landscape' => 'أفقي (16:9)',
'original' => 'الأصلي',
],
],
'facebook' => [
'settings' => 'إعدادات Facebook',
'posting_to' => 'النشر إلى',
'variant_label' => 'نوع المنشور',
'variant' => [
'post' => 'منشور',
'reel' => 'ريل',
'story' => 'قصة',
],
'aspect_label' => 'نسبة العرض إلى الارتفاع',
'aspect' => [
'square' => 'مربع (1:1)',
'portrait' => 'عمودي (4:5)',
'landscape' => 'أفقي (16:9)',
'original' => 'الأصلي',
],
],
'linkedin' => [
'settings' => 'إعدادات LinkedIn',
'settings_page' => 'إعدادات صفحة LinkedIn',
'posting_to' => 'النشر إلى',
'document_title' => 'عنوان المستند',
'document_title_placeholder' => 'يظهر على منشور مستند PDF الخاص بك',
],
'pinterest' => [
'settings' => 'إعدادات Pinterest',
'posting_to' => 'النشر إلى',
'variant_label' => 'نوع الدبوس',
'variant' => [
'pin' => 'دبوس',
'video_pin' => 'دبوس فيديو',
'carousel' => 'عرض دائري',
],
'board' => 'اللوحة',
'select_board' => 'اختر لوحة',
'no_boards' => 'لم يتم العثور على لوحات Pinterest. أنشئ واحدة في حسابك على Pinterest أولًا.',
'search_board' => 'البحث في اللوحات...',
'no_board_found' => 'لا توجد لوحة مطابقة لبحثك.',
'board_required' => 'اختر لوحة Pinterest لنشر هذا المنشور.',
],
'discord' => [
'settings' => 'إعدادات Discord',
'posting_to' => 'النشر إلى',
'channel' => 'القناة',
'select_channel' => 'اختر قناة',
'loading_channels' => 'جارٍ تحميل القنوات…',
'search_channel' => 'البحث في القنوات…',
'no_channels' => 'لم يتم العثور على قنوات.',
'channel_required' => 'اختر قناة Discord لنشر هذا المنشور.',
'mentions' => 'الإشارات',
'search_mention' => 'أشِر إلى دور أو عضو…',
'embeds' => 'التضمينات',
'embed' => 'تضمين',
'add_embed' => 'إضافة تضمين',
'embed_title' => 'عنوان التضمين',
'embed_description' => 'وصف التضمين',
'embed_url' => 'رابط التضمين',
'embed_image' => 'رابط الصورة',
'embed_color' => 'اللون',
],
'warnings' => [
'no_variant' => 'اختر نوع منشور للمتابعة.',
'requires_media' => 'يتطلب هذا النوع من المنشورات صورة أو فيديو واحدًا على الأقل.',
'max_files_exceeded' => 'يقبل هذا النوع من المنشورات حتى :max ملف وسائط (لديك :current).',
'min_files_required' => 'يتطلب هذا النوع من المنشورات :min ملف وسائط على الأقل (لديك :current).',
'no_video_allowed' => 'لا يقبل هذا النوع من المنشورات مقاطع الفيديو.',
'no_image_allowed' => 'يقبل هذا النوع من المنشورات مقاطع الفيديو فقط.',
'no_document_allowed' => 'لا يقبل هذا النوع من المنشورات مستندات PDF.',
'no_mixed_media' => 'لا يمكن الجمع بين الصور والفيديو في نفس المنشور.',
'document_not_alone' => 'يجب نشر ملف PDF بمفرده، دون صور أو مقاطع فيديو أخرى.',
'gif_not_allowed' => 'لا تقبل هذه المنصة صور GIF. أزِل صورة GIF أو اختر شبكة مختلفة.',
'image_too_large' => 'تتجاوز الصورة حد :max لهذا النوع من المنشورات (حجم صورتك :current).',
'video_too_large' => 'يتجاوز الفيديو حد :max لهذا النوع من المنشورات (حجم فيديوك :current).',
'document_too_large' => 'يتجاوز ملف PDF حد :max لهذا النوع من المنشورات (حجم ملفك :current).',
'video_too_long' => 'مدة الفيديو :current، لكن هذا النوع من المنشورات يسمح حتى :max.',
'aspect_ratio_too_narrow' => 'نسبة العرض إلى الارتفاع :current طويلة جدًا لهذا النوع من المنشورات (الحد الأدنى :min).',
'aspect_ratio_too_wide' => 'نسبة العرض إلى الارتفاع :current عريضة جدًا لهذا النوع من المنشورات (الحد الأقصى :max).',
],
],
'status' => [
'pending' => 'قيد الانتظار',
'draft' => 'مسودة',
'scheduled' => 'مجدول',
'publishing' => 'قيد النشر',
'retrying' => 'إعادة المحاولة',
'published' => 'منشور',
'partially_published' => 'منشور جزئيًا',
'failed' => 'فشل',
],
'descriptions' => [
'draft' => 'منشورات تنتظر الجدولة',
'scheduled' => 'منشورات مجدولة للنشر',
'published' => 'منشورات تم نشرها بالفعل',
],
'ai' => [
'generate' => [
'button_tooltip' => 'الإنشاء بالذكاء الاصطناعي',
'title' => 'إنشاء منشور بالذكاء الاصطناعي',
'description' => 'صِف موضوع المنشور. سيستخدم الذكاء الاصطناعي سياق علامتك التجارية لكتابته.',
'prompt_label' => 'ما موضوع هذا المنشور؟',
'prompt_placeholder' => 'مثال: الإعلان عن ميزتنا الجديدة لإنشاء الصور للعروض الدائرية',
'preview_label' => 'معاينة',
'start' => 'إنشاء',
'apply' => 'استخدام هذا المحتوى',
'retry' => 'إعادة المحاولة',
'cancel' => 'إلغاء',
],
'review' => [
'button_tooltip' => 'المراجعة بالذكاء الاصطناعي',
'title' => 'مراجعة المنشور بالذكاء الاصطناعي',
'description' => 'يفحص الذكاء الاصطناعي القواعد والإملاء والوضوح. طبّق الاقتراحات التي توافق عليها.',
'loading' => 'جارٍ مراجعة نصك...',
'no_issues' => 'لم يتم العثور على مشكلات. يبدو جيدًا.',
'original' => 'الأصل',
'suggestion' => 'اقتراح',
'apply' => 'تطبيق',
'apply_all' => 'تطبيق الكل',
'applied' => 'تم التطبيق',
'cancel' => 'إلغاء',
],
'image_regenerate' => [
'button' => 'تعديل',
'title' => 'تعديل صورة الذكاء الاصطناعي',
'description' => 'صِف التصحيح. تحل الصورة الجديدة محل الحالية وتحتفظ بموضعها في العرض الدائري.',
'instruction_label' => 'التعليمات',
'instruction_placeholder' => 'مثال: صحّح الخطأ المطبعي في العنوان واجعل الخلفية أفتح.',
'processing' => 'جارٍ إعادة إنشاء الصورة... قد يستغرق هذا بضع ثوانٍ.',
'submit' => 'إعادة إنشاء الصورة',
'cancel' => 'إلغاء',
'success' => 'تم تحديث الصورة. حلّت النسخة الجديدة محل السابقة في منشورك.',
'fallback_title' => 'تحسين نص هذه الصورة',
'errors' => [
'required' => 'التعليمات مطلوبة.',
'start_failed' => 'فشل بدء إعادة الإنشاء.',
'unavailable' => 'تعذر إعادة إنشاء هذه الصورة الآن.',
'timeout' => 'تستغرق إعادة الإنشاء وقتًا أطول من المتوقع. حاول مرة أخرى بعد لحظة.',
'media_not_found' => 'لم يتم العثور على عنصر الوسائط.',
'not_ai_media' => 'يمكن إعادة إنشاء الوسائط المُنشأة بالذكاء الاصطناعي فقط.',
],
],
'templates' => [
'image_card' => [
'name' => 'منشور صورة',
'description' => 'صورة بالذكاء الاصطناعي مع عنوان وتسمية توضيحية.',
],
'carousel' => [
'name' => 'عرض دائري',
'description' => 'عرض دائري متعدد الشرائح مع تسمية توضيحية.',
],
'tweet_card' => [
'name' => 'بطاقة تغريدة',
'description' => 'منشورك بتنسيق منشور X/Twitter.',
],
'tweet_card_image' => [
'name' => 'بطاقة تغريدة مع صورة',
'description' => 'منشورك كبطاقة X/Twitter فوق صورة ضبابية.',
],
],
],
'show' => [
'title' => 'تفاصيل المنشور',
'edit' => 'تعديل',
'back' => 'رجوع',
'no_content' => 'لا توجد تسمية توضيحية',
'platforms' => 'المنصات',
'no_platforms' => 'لم يتم اختيار أي منصات.',
'view_on_platform' => 'العرض على المنصة',
'published_on' => 'نُشر في :date',
'scheduled_for' => 'مجدول لـ :date',
'draft' => 'مسودة',
'status_pending' => 'قيد الانتظار',
'metrics' => 'المقاييس',
'metrics_loading' => 'جارٍ تحميل المقاييس…',
'metrics_unavailable' => 'المقاييس غير متاحة لهذه المنصة بعد.',
'metrics_empty' => 'لم تُرجَع أي مقاييس.',
],
'edit' => [
'title' => 'تعديل المنشور',
'view_title' => 'عرض المنشور',
'labels' => 'التسميات',
'no_labels' => 'لم يتم إنشاء تسميات بعد',
'schedule' => 'جدولة',
'pick_time' => 'اختر الوقت',
'pick_time_past' => 'اختر تاريخًا ووقتًا مستقبليًا.',
'post_now' => 'انشر الآن',
'time' => 'الوقت',
'cancel' => 'إلغاء',
'delete' => 'حذف',
'schedule_for' => 'جدولة لـ',
'schedule_date' => 'تاريخ الجدولة',
'unschedule' => 'إلغاء الجدولة',
'saving' => 'جارٍ الحفظ...',
'saved' => 'تم الحفظ',
'draft' => 'مسودة',
'media' => 'الوسائط',
'add_media' => 'إضافة وسائط',
'caption' => 'التسمية التوضيحية',
'caption_placeholder' => 'اكتب التسمية التوضيحية...',
'compose_title' => 'إنشاء منشور',
'compose_subtitle' => 'اكتب رسالتك وأضِف الوسائط',
'preview_empty' => [
'title' => 'لم يتم اختيار منصة',
'description' => 'اختر منصة للنشر لرؤية المعاينة.',
],
'drop_zone_title' => 'إضافة وسائط',
'drop_zone_subtitle' => 'اسحب الملفات وأفلتها أو انقر للتصفح',
'add' => 'إضافة',
'publish_to' => 'النشر إلى',
'organize' => 'تنظيم',
'signatures' => 'التوقيعات',
'view_on_platform' => 'العرض على المنصة',
'platform_status' => 'حالة المنصة',
'compliance_incomplete' => 'بعض إعدادات المنصة غير مكتملة أو غير متوافقة مع الوسائط المرفقة.',
'compliance' => [
'requires_content_or_media' => 'أضِف نصًا أو وسائط للنشر.',
'requires_media' => 'أضِف صورة أو فيديو للنشر هنا.',
'too_many_files' => 'مسموح بـ :max ملف فقط لهذا التنسيق.',
'too_few_files' => 'أضِف :min ملف على الأقل لهذا التنسيق.',
'no_videos' => 'يُسمح بالصور فقط لهذا التنسيق.',
'no_images' => 'يُسمح بمقاطع الفيديو فقط لهذا التنسيق.',
'no_mixed_media' => 'لا يمكن الجمع بين الصور ومقاطع الفيديو في نفس المنشور.',
'no_gifs' => 'صور GIF غير مدعومة هنا.',
'no_documents' => 'مستندات PDF غير مدعومة في هذا التنسيق.',
'document_not_alone' => 'يجب نشر ملف PDF بمفرده، دون صور أو مقاطع فيديو أخرى.',
'video_too_large' => 'يتجاوز الفيديو حد الحجم لهذه المنصة.',
'video_too_long' => 'يجب أن تكون مدة الفيديو أقل من :seconds ثانية لهذا التنسيق.',
'image_too_large' => 'تتجاوز الصورة حد الحجم لهذه المنصة.',
'document_too_large' => 'يتجاوز ملف PDF حد الحجم لهذه المنصة.',
'aspect_ratio_invalid' => 'نسبة العرض إلى الارتفاع غير مدعومة في هذا التنسيق.',
'no_content_type' => 'اختر نوع محتوى لهذه المنصة.',
'requires_text' => 'أضِف نصًا — يتطلب هذا التنسيق عنوانًا.',
],
'publishing' => 'جارٍ النشر...',
'publishing_overlay_title' => 'جارٍ نشر منشورك',
'publishing_overlay_subtitle' => 'قد يستغرق هذا بضع لحظات. يمكنك مغادرة هذه الصفحة بأمان.',
'scheduled_overlay_title' => 'هذا المنشور مجدول',
'scheduled_overlay_subtitle' => 'مجدول لـ :date. ألغِ جدولته أولًا لإجراء تغييرات.',
'unschedule_cta' => 'ألغِ الجدولة للتعديل',
'tabs' => [
'preview' => 'معاينة',
'channels' => 'القنوات',
'comments' => 'التعليقات',
'comments_empty' => 'لا توجد تعليقات بعد.',
],
'media_picker' => [
'title' => 'اختر من المعرض',
'search' => 'البحث في الوسائط...',
'empty' => 'لا توجد وسائط في معرضك بعد',
'cancel' => 'إلغاء',
'add' => 'إضافة',
'add_count' => 'إضافة :count',
],
'emoji_picker' => [
'search' => 'البحث عن رمز تعبيري',
'empty' => 'لم يتم العثور على رموز تعبيرية',
'recent' => 'المستخدمة كثيرًا',
'smileys' => 'الوجوه والمشاعر',
'people' => 'الأشخاص والجسم',
'nature' => 'الحيوانات والطبيعة',
'food' => 'الطعام والشراب',
'activities' => 'الأنشطة',
'travel' => 'السفر والأماكن',
'objects' => 'الأشياء',
'symbols' => 'الرموز',
'flags' => 'الأعلام',
],
'status' => [
'pending' => 'قيد الانتظار',
'scheduled' => 'مجدول',
'published' => 'منشور',
'publishing' => 'جارٍ النشر...',
'retrying' => 'جارٍ إعادة المحاولة...',
'failed' => 'فشل',
],
'delete_modal' => [
'title' => 'حذف المنشور',
'description' => 'هل أنت متأكد من رغبتك في حذف هذا المنشور؟ لا يمكن التراجع عن هذا الإجراء.',
'action' => 'حذف',
'cancel' => 'إلغاء',
],
'sync_enable' => [
'title' => 'تفعيل المزامنة؟',
'description' => 'ستشترك جميع المنصات في نفس المحتوى. سيتم استبدال أي تعديلات مخصصة أُجريت على منصات فردية بالمحتوى الحالي.',
'cancel' => 'إلغاء',
'action' => 'تفعيل المزامنة',
],
'sync_disable' => [
'title' => 'تعطيل المزامنة؟',
'description' => 'ستحتفظ كل منصة بمحتواها الحالي، لكن التعديلات المستقبلية ستُطبَّق فقط على المنصة التي تعدّلها.',
'customize_note' => 'ستتمكن من تخصيص المحتوى لكل منصة على حدة.',
'cancel' => 'إلغاء',
'action' => 'تعطيل المزامنة',
],
'platforms_dialog' => [
'title' => 'اختيار المنصات',
'description' => 'اختر المنصات التي تريد نشر هذا المنشور عليها.',
],
'signatures_modal' => [
'search' => 'البحث في التوقيعات...',
'no_results' => 'لم يتم العثور على توقيعات.',
],
'validation' => [
'select_board' => 'اختر لوحة',
'images_not_supported' => 'الصور غير مدعومة',
'videos_not_supported' => 'مقاطع الفيديو غير مدعومة',
'max_images' => 'الحد الأقصى :count صور',
'requires_media' => 'يتطلب وسائط',
'requires_content' => 'المحتوى النصي مطلوب',
'exceeded' => 'تجاوز :count',
'does_not_support_images' => 'لا يدعم :platform الصور',
'supports_up_to_images' => 'يدعم :platform حتى :count صور',
'does_not_support_videos' => 'لا يدعم :platform مقاطع الفيديو',
],
],
'content_types' => [
'instagram_feed' => [
'label' => 'منشور',
'description' => 'يظهر في خلاصتك وملفك الشخصي',
],
'instagram_reel' => [
'label' => 'ريل',
'description' => 'فيديو قصير حتى 90 ثانية',
],
'instagram_story' => [
'label' => 'قصة',
'description' => 'يختفي بعد 24 ساعة',
],
'linkedin_post' => [
'label' => 'منشور',
'description' => 'منشور قياسي — صورة واحدة أو متعددة أو فيديو أو PDF',
],
'linkedin_page_post' => [
'label' => 'منشور',
'description' => 'منشور قياسي — صورة واحدة أو متعددة أو فيديو أو PDF',
],
'facebook_post' => [
'label' => 'منشور',
'description' => 'منشور قياسي على صفحتك',
],
'facebook_reel' => [
'label' => 'ريل',
'description' => 'فيديو قصير حتى 90 ثانية',
],
'facebook_story' => [
'label' => 'قصة',
'description' => 'قصة فيديو عمودية، حتى 60 ثانية',
],
'tiktok_video' => [
'label' => 'فيديو',
'description' => 'محتوى فيديو قصير',
],
'tiktok_photo' => [
'label' => 'عرض صور دائري',
'description' => 'حتى 35 صورة كعرض دائري قابل للتمرير',
],
'youtube_short' => [
'label' => 'مقطع قصير',
'description' => 'فيديو عمودي حتى 60 ثانية',
],
'x_post' => [
'label' => 'منشور',
'description' => 'تغريدة بنص ووسائط',
],
'threads_post' => [
'label' => 'منشور',
'description' => 'منشور نصي مع وسائط اختيارية',
],
'pinterest_pin' => [
'label' => 'دبوس',
'description' => 'دبوس صورة قياسي',
],
'pinterest_video_pin' => [
'label' => 'دبوس فيديو',
'description' => 'دبوس فيديو (4 ث - 15 د)',
],
'pinterest_carousel' => [
'label' => 'عرض دائري',
'description' => 'عرض دائري متعدد الصور (2-5 صور)',
],
'bluesky_post' => [
'label' => 'منشور',
'description' => 'منشور نصي مع صور اختيارية',
],
'mastodon_post' => [
'label' => 'منشور',
'description' => 'منشور نصي مع وسائط اختيارية',
],
'telegram_post' => [
'label' => 'منشور',
'description' => 'منشور نصي مع وسائط اختيارية',
],
'discord_message' => [
'label' => 'رسالة',
'description' => 'رسالة إلى قناة Discord مع وسائط وتضمينات اختيارية',
],
],
'platforms' => [
'linkedin' => 'LinkedIn',
'linkedin-page' => 'LinkedIn Page',
'x' => 'X',
'tiktok' => 'TikTok',
'youtube' => 'YouTube Shorts',
'facebook' => 'Facebook Page',
'instagram' => 'Instagram',
'threads' => 'Threads',
'pinterest' => 'Pinterest',
'bluesky' => 'Bluesky',
'mastodon' => 'Mastodon',
],
'flash' => [
'scheduled' => 'تمت جدولة المنشور بنجاح!',
'deleted' => 'تم حذف المنشور بنجاح!',
'duplicated' => 'تم تكرار المنشور كمسودة.',
'cannot_edit_finalized' => 'تمت معالجة هذا المنشور بالفعل ولا يمكن إعادة نشره. كرّره للمحاولة مرة أخرى.',
'cannot_delete_published' => 'لا يمكن حذف المنشورات المنشورة.',
'connect_first' => 'اربط شبكة اجتماعية واحدة على الأقل قبل إنشاء منشور.',
],
'errors' => [
'account_disconnected' => 'الحساب الاجتماعي مفصول',
'account_inactive' => 'الحساب الاجتماعي مُعطَّل',
'account_token_expired' => 'انتهت جلسة الحساب الاجتماعي — يرجى إعادة الربط',
],
'delete' => [
'title' => 'حذف المنشور؟',
'description' => 'لا يمكن التراجع عن هذا الإجراء. ستتم إزالة المنشور وجميع وسائطه نهائيًا.',
'confirm' => 'نعم، احذف',
'cancel' => 'إلغاء',
],
'create' => [
'title' => 'إنشاء منشور جديد',
'description' => 'اختر كيف تريد البدء.',
'scratch_title' => 'البدء من الصفر',
'scratch_description' => 'افتح منشورًا فارغًا واكتب كل شيء بنفسك.',
'ai_title' => 'الإنشاء بالذكاء الاصطناعي',
'ai_description' => 'صِف ما تريده وينشئ الذكاء الاصطناعي المحتوى من أجلك.',
'ai_configure_description' => 'اختر تنسيقًا وصِف المنشور الذي تريد إنشاءه.',
'ai_pick_template_description' => 'اختر نمطًا لمنشورك المُنشأ بالذكاء الاصطناعي.',
'template_title' => 'استخدام قالب',
'template_description' => 'اختر من قوالبنا المنسّقة وخصّصها.',
'coming_soon' => 'قريبًا',
'preview' => [
'image_title' => 'عنوان الصورة',
'image_body' => 'نص الصورة',
],
'steps' => [
'template_picker_title' => 'اختر نمطًا',
'format_title' => 'اختر تنسيقًا',
'format_description' => 'اختر نوع المنشور الذي تريد إنشاءه.',
'account_title' => 'اختر حسابًا',
'account_description' => 'اختر الحساب الاجتماعي للنشر إليه.',
'media_title' => 'خيارات الوسائط',
'media_carousel' => 'كم عدد الشرائح؟',
'media_optional' => 'تضمين صور؟',
'media_optional_label' => 'كم عدد الصور؟',
'media_none' => 'بلا',
'media_count_label' => 'عدد الصور',
'prompt_title' => 'صِف منشورك',
'prompt_label' => 'ما موضوع هذا المنشور؟',
'prompt_placeholder' => 'مثال: الإعلان عن ميزة العرض الدائري الجديدة لدينا على Instagram',
'preview_error' => 'حدث خطأ ما. يرجى المحاولة مرة أخرى.',
'loading_page_title' => 'جارٍ إنشاء منشورك',
'loading_eta' => 'الوقت المقدّر: حوالي :minutes.',
'loading_eta_minute_one' => 'دقيقة واحدة',
'loading_eta_minute_other' => ':count دقيقة',
'loading_leave_title' => 'يمكنك متابعة عملك.',
'loading_leave_body' => 'سنُعلمك عندما يصبح المنشور جاهزًا.',
'loading_leave_cta' => 'الذهاب إلى التقويم',
'loading_create_another_cta' => 'إنشاء منشور آخر',
'loading_tip_credits' => 'تستخدم كل صورة بالذكاء الاصطناعي حوالي 15 من الرصيد.',
'loading_tip_edit' => 'ستتمكن من تعديل كل شيء بمجرد أن يصبح المنشور جاهزًا.',
'loading_tip_draft' => 'تصل المنشورات المُنشأة إلى مسوداتك.',
'loading_tip_brand' => 'عدّل إعدادات علامتك التجارية للتأثير في المنشورات المستقبلية.',
'loading_tip_carousel' => 'تقدّم العروض الدائرية شريحة واحدة لكل صورة مرفوعة.',
'loading_tip_quality' => 'تم ضبط جودة الصورة لتحقيق توازن بين السرعة والتكلفة.',
'create' => 'إنشاء منشور',
'back' => 'رجوع',
'next' => 'متابعة',
'cancel' => 'إلغاء',
'discard' => 'تجاهل',
'retry' => 'إعادة المحاولة',
'no_platforms' => 'لا توجد حسابات متصلة',
'connect_first' => 'اربط حسابًا اجتماعيًا واحدًا على الأقل لاستخدام الإنشاء بالذكاء الاصطناعي.',
'no_account_for_template' => 'اربط حسابًا متوافقًا لاستخدام هذا القالب.',
'format' => [
'instagram_feed' => 'منشور خلاصة Instagram',
'instagram_carousel' => 'عرض Instagram الدائري',
'linkedin_post' => 'منشور LinkedIn',
'linkedin_page_post' => 'منشور صفحة LinkedIn',
'x_post' => 'منشور X',
'bluesky_post' => 'منشور Bluesky',
'threads_post' => 'منشور Threads',
'mastodon_post' => 'منشور Mastodon',
'telegram_post' => 'منشور Telegram',
'discord_message' => 'رسالة Discord',
'facebook_post' => 'منشور Facebook',
'pinterest_pin' => 'دبوس Pinterest',
'instagram_story' => 'قصة Instagram',
'facebook_story' => 'قصة Facebook',
],
],
],
'templates' => [
'browser_title' => 'اختر قالبًا',
'browser_description' => 'ابدأ من قالب منسّق وكيّفه.',
'search_placeholder' => 'البحث في القوالب…',
'no_search_results' => 'لا توجد قوالب مطابقة لبحثك',
'try_different_search' => 'جرّب كلمة مختلفة أو امسح البحث.',
'slides_count' => '{count} شرائح|{count} شريحة|{count} شريحتان|{count} شرائح|{count} شريحة|{count} شريحة',
'all_platforms' => 'جميع المنصات',
'platform_search_placeholder' => 'البحث عن منصة…',
'no_platform_match' => 'لا توجد منصة مطابقة.',
'use_this' => 'استخدام هذا القالب',
'no_templates' => 'لا توجد قوالب متاحة.',
'applying' => 'جارٍ تطبيق القالب…',
'category' => [
'product_launch' => 'إطلاق منتج',
'promotion' => 'ترويج',
'educational' => 'تعليمي',
'behind_the_scenes' => 'خلف الكواليس',
'testimonial' => 'شهادة',
'industry_tip' => 'نصيحة في المجال',
'event' => 'فعالية',
'engagement' => 'تفاعل',
],
],
];

363
lang/ar/settings.php Normal file
View file

@ -0,0 +1,363 @@
<?php
return [
'title' => 'الإعدادات',
'description' => 'إدارة ملفك الشخصي وإعدادات حسابك',
'hub' => [
'title' => 'الإعدادات',
'description' => 'اختر ما تريد إدارته.',
'profile' => [
'title' => 'الملف الشخصي',
'description' => 'حدّث معلوماتك الشخصية وكلمة المرور وتفضيلات الإشعارات.',
],
'workspace' => [
'title' => 'مساحة العمل',
'description' => 'اضبط مساحة عملك وعلامتك التجارية والأعضاء ومفاتيح API.',
],
'account' => [
'title' => 'الحساب',
'description' => 'إدارة معلومات حسابك واستخدامك والفوترة.',
],
],
'nav' => [
'profile' => 'الملف الشخصي',
'authentication' => 'المصادقة',
'workspace' => 'مساحة العمل',
'members' => 'الأعضاء',
'notifications' => 'الإشعارات',
'billing' => 'الفوترة',
],
'notifications' => [
'title' => 'تفضيلات الإشعارات',
'heading' => 'إشعارات البريد الإلكتروني',
'description' => 'اختر إشعارات البريد الإلكتروني التي تريد استلامها',
'post_published' => 'تم نشر المنشور',
'post_published_description' => 'استلم بريدًا إلكترونيًا عند نشر منشورك بنجاح',
'post_failed' => 'فشل نشر المنشور',
'post_failed_description' => 'استلم بريدًا إلكترونيًا عند فشل نشر منشورك',
'account_disconnected' => 'تم فصل الحساب',
'account_disconnected_description' => 'استلم بريدًا إلكترونيًا عند فصل حساب اجتماعي',
'save' => 'حفظ التفضيلات',
],
'profile' => [
'title' => 'إعدادات الملف الشخصي',
'photo_heading' => 'الصورة الشخصية',
'photo_description' => 'ارفع صورة شخصية',
'heading' => 'معلومات الملف الشخصي',
'description' => 'حدّث اسمك وبريدك الإلكتروني',
'avatar' => 'الصورة الرمزية',
'name' => 'الاسم',
'name_placeholder' => 'الاسم الكامل',
'email' => 'البريد الإلكتروني',
'email_placeholder' => 'البريد الإلكتروني',
'email_unverified' => 'لم يتم تأكيد بريدك الإلكتروني.',
'resend_verification' => 'انقر هنا لإعادة إرسال بريد التأكيد.',
'verification_sent' => 'تم إرسال رابط تأكيد جديد إلى بريدك الإلكتروني.',
'save' => 'حفظ',
],
'authentication' => [
'title' => 'المصادقة',
'page_title' => 'إعدادات المصادقة',
'sessions' => [
'title' => 'الجلسات النشطة',
'description' => 'إذا لاحظت أي شيء مريب، سجّل الخروج من الأجهزة الأخرى.',
'unknown_browser' => 'متصفح غير معروف',
'unknown_ip' => 'عنوان IP غير معروف',
'on' => 'على',
'active_now' => 'نشط الآن',
'log_out_others' => 'تسجيل الخروج من الأجهزة الأخرى',
'modal_title' => 'تسجيل الخروج من الأجهزة الأخرى',
'modal_description_password' => 'أدخل كلمة المرور الحالية لتأكيد رغبتك في تسجيل الخروج من جلسات المتصفح الأخرى.',
'modal_description_email' => 'اكتب بريدك الإلكتروني لتأكيد رغبتك في تسجيل الخروج من جلسات المتصفح الأخرى.',
'password_placeholder' => 'كلمة المرور الحالية',
'email_placeholder' => 'بريد حسابك الإلكتروني',
'cancel' => 'إلغاء',
'submit' => 'تسجيل الخروج من الأجهزة الأخرى',
'email_mismatch' => 'البريد الإلكتروني لا يطابق حسابك.',
'flash_logged_out' => 'تم تسجيل خروجك من الأجهزة الأخرى.',
],
'password' => [
'update_title' => 'تحديث كلمة المرور',
'set_title' => 'تعيين كلمة مرور',
'update_description' => 'تأكد من أن حسابك يستخدم كلمة مرور طويلة وعشوائية للحفاظ على أمانه.',
'set_description' => 'أضِف كلمة مرور لتتمكن من تسجيل الدخول دون مزوّد متصل.',
'current_password' => 'كلمة المرور الحالية',
'new_password' => 'كلمة المرور الجديدة',
'confirm_password' => 'تأكيد كلمة المرور',
'save' => 'حفظ كلمة المرور',
'set' => 'تعيين كلمة المرور',
],
'providers' => [
'title' => 'الحسابات المتصلة',
'description' => 'سجّل الدخول بشكل أسرع عبر هؤلاء المزوّدين المتصلين.',
'connected' => 'متصل',
'not_connected' => 'غير متصل',
'connect' => 'ربط',
'disconnect' => 'فصل',
'flash_disconnected' => 'تم فصل :provider بنجاح.',
'flash_connected' => 'تم ربط :provider بنجاح.',
'flash_already_linked' => 'حساب :provider هذا مرتبط بالفعل بمستخدم آخر.',
'flash_cannot_disconnect' => 'لا يمكنك فصل طريقة تسجيل الدخول الوحيدة لديك. عيّن كلمة مرور أو اربط مزوّدًا آخر أولًا.',
],
],
'delete_account' => [
'heading' => 'حذف الحساب',
'description' => 'احذف حسابك وجميع موارده',
'warning' => 'تحذير',
'warning_message' => 'يرجى المتابعة بحذر، لا يمكن التراجع عن هذا الإجراء.',
'button' => 'حذف الحساب',
'modal_title' => 'هل أنت متأكد من رغبتك في حذف حسابك؟',
'modal_description_password' => 'بمجرد حذف حسابك، ستُحذف جميع موارده وبياناته نهائيًا أيضًا. يرجى إدخال كلمة المرور للتأكيد.',
'modal_description_email' => 'بمجرد حذف حسابك، ستُحذف جميع موارده وبياناته نهائيًا أيضًا. يرجى كتابة بريدك الإلكتروني :email للتأكيد.',
'password' => 'كلمة المرور',
'password_placeholder' => 'كلمة المرور',
'email_placeholder' => 'بريد حسابك الإلكتروني',
'email_mismatch' => 'البريد الإلكتروني لا يطابق حسابك.',
'cancel' => 'إلغاء',
'confirm' => 'حذف الحساب',
],
'workspace' => [
'tabs' => [
'workspace' => 'مساحة العمل',
'brand' => 'العلامة التجارية',
'users' => 'الأعضاء',
'api_keys' => 'مفاتيح API',
],
'title' => 'إعدادات مساحة العمل',
'logo_heading' => 'شعار مساحة العمل',
'logo_description' => 'ارفع شعارًا لمساحة عملك',
'heading' => 'اسم مساحة العمل',
'description' => 'حدّث اسم مساحة عملك',
'members_heading' => 'الأعضاء',
'members_description' => 'إدارة أعضاء مساحة العمل والدعوات',
'name' => 'الاسم',
'name_placeholder' => 'مساحة عملي',
'save' => 'حفظ',
],
'brand' => [
'title' => 'العلامة التجارية',
'description' => 'اضبط هوية علامتك التجارية للمحتوى المُنشأ بالذكاء الاصطناعي.',
'name' => 'اسم مساحة العمل',
'name_placeholder' => 'علامتي التجارية',
'website' => 'الموقع الإلكتروني',
'website_placeholder' => 'https://yourbrand.com',
'brand_description' => 'الوصف',
'brand_description_placeholder' => 'أخبرنا عن علامتك التجارية، وما تفعله، ومن هو جمهورك...',
'voice' => 'صوت العلامة التجارية',
'voice_description' => 'اختر السمات التي تحدد أسلوب محتواك.',
'voice_group' => [
'pov' => 'وجهة النظر',
'formality' => 'الرسمية',
'energy' => 'الحيوية',
'humor' => 'الفكاهة',
'attitude' => 'الموقف',
'warmth' => 'الدفء',
'confidence' => 'الثقة',
'style' => 'الأسلوب',
],
'voice_trait' => [
'first_person' => 'ضمير المتكلم',
'second_person' => 'ضمير المخاطب (أنت)',
'third_person' => 'ضمير الغائب',
'formal' => 'رسمي',
'balanced' => 'متوازن',
'casual' => 'غير رسمي',
'calm' => 'هادئ',
'moderate' => 'معتدل',
'enthusiastic' => 'متحمس',
'vibrant' => 'نابض بالحيوية',
'serious' => 'جاد',
'dry' => 'ساخر / خفيّ',
'witty' => 'ذكي',
'playful' => 'مرح',
'respectful' => 'محترم',
'even_handed' => 'محايد ومنصف',
'bold' => 'جريء',
'provocative' => 'مثير للجدل',
'neutral' => 'محايد',
'friendly' => 'ودود',
'empathetic' => 'متعاطف',
'humble' => 'متواضع',
'confident' => 'واثق',
'assertive' => 'حازم',
'direct' => 'مباشر',
'concise' => 'موجز',
'transparent' => 'شفاف',
'no_hype' => 'بلا مبالغة',
'practical' => 'عملي',
'data_driven' => 'مبني على البيانات',
'storytelling' => 'سرد القصص',
'inspirational' => 'ملهم',
'educational' => 'تعليمي',
'technical' => 'تقني',
'minimalist' => 'رموز تعبيرية قليلة',
],
'brand_color' => 'لون العلامة التجارية',
'background_color' => 'لون الخلفية',
'text_color' => 'لون النص',
'font' => 'الخط',
'image_style' => 'نمط الصور',
'image_style_description' => 'النمط المرئي المطبَّق عند إنشاء صور الشرائح والأغلفة لمنشورات الذكاء الاصطناعي.',
'image_style_cinematic' => 'سينمائي',
'image_style_illustration' => 'رسم توضيحي',
'image_style_isometric_3d' => 'متساوي القياس',
'image_style_cartoon' => 'كرتوني',
'image_style_typographic' => 'طباعي',
'image_style_infographic' => 'إنفوغرافيك',
'image_style_minimalist' => 'بسيط',
'image_style_mockup' => 'نموذج أوّلي',
'content_language' => 'لغة المحتوى',
'content_language_description' => 'اللغة المستخدمة في التسميات التوضيحية والوسوم المُنشأة بالذكاء الاصطناعي وأي نص داخل الصور أو مقاطع الفيديو المُنشأة.',
'font_placeholder' => 'اختر خطًا…',
'font_search' => 'ابحث عن خط…',
'font_empty' => 'لا توجد خطوط مطابقة.',
'language_placeholder' => 'اختر لغة…',
'language_search' => 'ابحث عن لغة…',
'language_empty' => 'لم يتم العثور على لغة.',
],
'members' => [
'title' => 'الأعضاء',
'heading' => 'أعضاء الفريق',
'description' => 'إدارة الأعضاء والدعوات لمساحة العمل هذه',
'cancel' => 'إلغاء',
'remove' => 'إزالة',
'make_role' => 'تعيين كـ:role',
'invite' => [
'title' => 'دعوة عضو',
'description' => 'أرسل دعوة عبر البريد الإلكتروني لإضافة متعاونين',
'email' => 'البريد الإلكتروني',
'email_placeholder' => 'collaborator@email.com',
'role' => 'الدور',
'role_placeholder' => 'اختر دورًا',
'submit' => 'إرسال الدعوة',
],
'pending' => [
'title' => 'الدعوات المعلقة',
'description' => 'دعوات في انتظار القبول',
'empty' => 'لا توجد دعوات معلقة',
],
'list' => [
'title' => 'الأعضاء',
'description' => 'الأشخاص الذين لديهم وصول إلى مساحة العمل هذه',
'empty' => 'لا يوجد أعضاء غير المالك',
],
'remove_modal' => [
'title' => 'إزالة عضو',
'description' => 'هل أنت متأكد من رغبتك في إزالة هذا العضو من مساحة العمل؟ سيفقد الوصول إلى جميع موارد مساحة العمل.',
'action' => 'إزالة العضو',
],
'cancel_invite_modal' => [
'title' => 'إلغاء الدعوة',
'description' => 'هل أنت متأكد من رغبتك في إلغاء هذه الدعوة؟',
'action' => 'إلغاء الدعوة',
],
'roles' => [
'owner' => 'المالك',
'admin' => 'مشرف',
'member' => 'عضو',
'viewer' => 'مشاهد',
],
'flash' => [
'invite_sent' => 'تم إرسال الدعوة بنجاح!',
'invite_deleted' => 'تم حذف الدعوة.',
'member_removed' => 'تمت إزالة العضو بنجاح.',
'role_updated' => 'تم تحديث دور العضو.',
'wrong_email' => 'هذه الدعوة مخصصة لبريد إلكتروني مختلف.',
'already_member' => 'أنت عضو بالفعل في مساحة العمل هذه.',
'invite_accepted' => 'مرحبًا! أنت الآن عضو في مساحة العمل.',
'invite_declined' => 'تم رفض الدعوة.',
],
],
'account' => [
'tabs' => [
'account' => 'الحساب',
'usage' => 'الاستخدام',
'billing' => 'الفوترة',
],
'title' => 'إعدادات الحساب',
'description' => 'إدارة اسم حسابك والبريد الإلكتروني للفوترة',
'name' => 'اسم الحساب',
'name_placeholder' => 'شركتي',
'billing_email' => 'البريد الإلكتروني للفوترة',
'billing_email_placeholder' => 'billing@company.com',
'billing_email_hint' => 'سيُستخدم هذا البريد الإلكتروني للفواتير ومراسلات الفوترة من Stripe.',
'submit' => 'حفظ',
],
'flash' => [
'account_updated' => 'تم تحديث الحساب بنجاح!',
'profile_updated' => 'تم تحديث الملف الشخصي بنجاح!',
'password_updated' => 'تم تحديث كلمة المرور بنجاح!',
'workspace_updated' => 'تم تحديث الإعدادات بنجاح!',
'photo_updated' => 'تم تحديث الصورة بنجاح!',
'photo_deleted' => 'تمت إزالة الصورة بنجاح!',
'logo_updated' => 'تم رفع الشعار بنجاح!',
'logo_deleted' => 'تمت إزالة الشعار بنجاح!',
'notifications_updated' => 'تم تحديث تفضيلات الإشعارات!',
],
'api_keys' => [
'title' => 'مفاتيح API',
'page_title' => 'مفاتيح API',
'heading' => 'مفاتيح API',
'description' => 'إدارة مفاتيح API للوصول البرمجي إلى مساحة عملك.',
'create' => 'إنشاء مفتاح API',
'copy' => 'نسخ',
'new_token_message' => 'تم إنشاء مفتاح API الجديد. انسخه الآن — لن تتمكن من رؤيته مرة أخرى.',
'table' => [
'name' => 'الاسم',
'key' => 'المفتاح',
'status' => 'الحالة',
'expires' => 'ينتهي في',
'last_used' => 'آخر استخدام',
'never' => 'أبدًا',
],
'actions' => [
'copy_id' => 'نسخ معرّف مفتاح API',
'copy_id_success' => 'تم نسخ معرّف مفتاح API إلى الحافظة',
'delete' => 'حذف',
],
'empty' => [
'title' => 'لا توجد مفاتيح API بعد',
'description' => 'أنشئ مفتاح API للوصول إلى مساحة عملك برمجيًا.',
],
'delete_modal' => [
'title' => 'حذف مفتاح API',
'description' => 'هل أنت متأكد من رغبتك في حذف مفتاح API هذا؟ ستفقد أي تطبيقات تستخدم هذا المفتاح الوصول فورًا.',
'action' => 'حذف مفتاح API',
],
'create_dialog' => [
'title' => 'إنشاء مفتاح API',
'description' => 'أنشئ مفتاح API جديدًا للوصول البرمجي إلى مساحة عملك.',
'name' => 'الاسم',
'name_placeholder' => 'مثال: مفتاح API للإنتاج',
'expires' => 'تاريخ الانتهاء (اختياري)',
'expires_placeholder' => 'بلا انتهاء',
'submit' => 'إنشاء',
'cancel' => 'إلغاء',
],
'flash' => [
'created' => 'تم إنشاء مفتاح API بنجاح!',
'deleted' => 'تم حذف مفتاح API بنجاح!',
],
],
];

61
lang/ar/sidebar.php Normal file
View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
return [
'workspaces' => 'مساحات العمل',
'select_workspace' => 'اختر مساحة العمل',
'create_workspace' => 'إنشاء مساحة عمل',
'create_post' => 'إنشاء منشور',
'profile' => 'الملف الشخصي',
'log_out' => 'تسجيل الخروج',
'workspace' => 'مساحة العمل: :name',
'workspace_select' => 'مساحة العمل: اختر',
'theme' => 'المظهر: :name',
'theme_light' => 'فاتح',
'theme_dark' => 'داكن',
'theme_system' => 'النظام',
'language' => 'اللغة: :name',
'language_select' => 'اللغة: اختر',
'groups' => [
'posts' => 'المنشورات',
'workspace' => 'مساحة العمل',
'others' => 'أخرى',
],
'analytics' => 'التحليلات',
'automations' => 'الأتمتة',
'settings' => 'الإعدادات',
'posts' => [
'calendar' => 'التقويم',
'all' => 'الكل',
'scheduled' => 'المجدولة',
'posted' => 'المنشورة',
'drafts' => 'المسودات',
],
'workspace' => [
'connections' => 'الاتصالات',
'signatures' => 'التوقيعات',
'labels' => 'التسميات',
'assets' => 'الوسائط',
'api_keys' => 'مفاتيح API',
],
'notifications' => 'الإشعارات',
'mark_all_read' => 'تعليم الكل كمقروء',
'mark_as_read' => 'تعليم كمقروء',
'archive_all' => 'أرشفة الكل',
'no_notifications' => 'لا توجد إشعارات',
'support' => [
'docs' => 'التوثيق',
'referral' => 'اربح عمولة إحالة 30%',
'stay_updated' => 'ابقَ على اطلاع',
],
];

59
lang/ar/signatures.php Normal file
View file

@ -0,0 +1,59 @@
<?php
return [
'title' => 'التوقيعات',
'description' => 'أنشئ توقيعات قابلة لإعادة الاستخدام لإضافتها بسرعة إلى منشوراتك',
'search' => 'البحث في التوقيعات...',
'new' => 'توقيع جديد',
'empty_title' => 'لا توجد توقيعات بعد',
'empty_description' => 'أنشئ توقيعات لإضافة الوسوم أو الروابط أو أي نص قابل لإعادة الاستخدام إلى منشوراتك بسرعة',
'no_search_results' => 'لا توجد توقيعات مطابقة لبحثك',
'try_different_search' => 'جرّب كلمة مختلفة أو امسح البحث.',
'table' => [
'name' => 'الاسم',
'content' => 'المحتوى',
'created_at' => 'تاريخ الإنشاء',
],
'actions' => [
'edit' => 'تعديل التوقيع',
'delete' => 'حذف التوقيع',
],
'create' => [
'title' => 'إنشاء توقيع',
'description' => 'امنح توقيعك اسمًا والمحتوى الذي تريد إضافته (وسوم، روابط، نص مخصص — أي شيء تعيد استخدامه).',
'name' => 'الاسم',
'name_placeholder' => 'مثال: التسويق، السفر، توقيع العلامة التجارية',
'content' => 'المحتوى',
'content_placeholder' => "#marketing #socialmedia\nاعرف المزيد: https://yourbrand.com",
'content_hint' => 'وسوم، روابط، مقدمات مخصصة، توقيعات — أي شيء تضيفه إلى المنشورات.',
'submit' => 'إنشاء توقيع',
'submitting' => 'جارٍ الإنشاء...',
],
'edit' => [
'title' => 'تعديل التوقيع',
'description' => 'تحديث اسم ومحتوى هذا التوقيع.',
'name' => 'الاسم',
'name_placeholder' => 'مثال: التسويق، السفر، توقيع العلامة التجارية',
'content' => 'المحتوى',
'content_placeholder' => "#marketing #socialmedia\nاعرف المزيد: https://yourbrand.com",
'content_hint' => 'وسوم، روابط، مقدمات مخصصة، توقيعات — أي شيء تضيفه إلى المنشورات.',
'submit' => 'حفظ التغييرات',
'submitting' => 'جارٍ الحفظ...',
],
'delete' => [
'title' => 'حذف التوقيع',
'description' => 'هل أنت متأكد من رغبتك في حذف هذا التوقيع؟ لا يمكن التراجع عن هذا الإجراء.',
'confirm' => 'حذف',
'cancel' => 'إلغاء',
],
'flash' => [
'created' => 'تم إنشاء التوقيع.',
'updated' => 'تم تحديث التوقيع.',
'deleted' => 'تم حذف التوقيع.',
],
];

15
lang/ar/usage.php Normal file
View file

@ -0,0 +1,15 @@
<?php
return [
'title' => 'الاستخدام',
'section_account' => 'الحساب',
'section_account_description' => 'الحصص والحدود الخاصة بخطتك.',
'section_ai' => 'رصيد الذكاء الاصطناعي',
'section_ai_description' => 'يُخصم الرصيد عند استخدام ميزات الذكاء الاصطناعي. يتم تجديده في اليوم الأول من كل شهر.',
'workspaces' => 'مساحات العمل',
'social_accounts' => 'الحسابات الاجتماعية',
'members' => 'الأعضاء',
'credits' => 'الرصيد',
];

200
lang/ar/validation.php Normal file
View file

@ -0,0 +1,200 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'يجب قبول حقل :attribute.',
'accepted_if' => 'يجب قبول حقل :attribute عندما يكون :other مساويًا لـ :value.',
'active_url' => 'يجب أن يكون حقل :attribute رابطًا صالحًا.',
'after' => 'يجب أن يكون حقل :attribute تاريخًا لاحقًا لـ :date.',
'after_or_equal' => 'يجب أن يكون حقل :attribute تاريخًا لاحقًا لـ :date أو مساويًا له.',
'alpha' => 'يجب أن يحتوي حقل :attribute على أحرف فقط.',
'alpha_dash' => 'يجب أن يحتوي حقل :attribute على أحرف وأرقام وشرطات وشرطات سفلية فقط.',
'alpha_num' => 'يجب أن يحتوي حقل :attribute على أحرف وأرقام فقط.',
'any_of' => 'حقل :attribute غير صالح.',
'array' => 'يجب أن يكون حقل :attribute مصفوفة.',
'ascii' => 'يجب أن يحتوي حقل :attribute على أحرف ورموز أحادية البايت فقط.',
'before' => 'يجب أن يكون حقل :attribute تاريخًا سابقًا لـ :date.',
'before_or_equal' => 'يجب أن يكون حقل :attribute تاريخًا سابقًا لـ :date أو مساويًا له.',
'between' => [
'array' => 'يجب أن يحتوي حقل :attribute على عدد عناصر بين :min و:max.',
'file' => 'يجب أن يكون حجم حقل :attribute بين :min و:max كيلوبايت.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute بين :min و:max.',
'string' => 'يجب أن يكون طول حقل :attribute بين :min و:max حرفًا.',
],
'boolean' => 'يجب أن تكون قيمة حقل :attribute صحيحة أو خاطئة.',
'can' => 'يحتوي حقل :attribute على قيمة غير مصرّح بها.',
'confirmed' => 'تأكيد حقل :attribute غير مطابق.',
'contains' => 'حقل :attribute يفتقد إلى قيمة مطلوبة.',
'current_password' => 'كلمة المرور غير صحيحة.',
'date' => 'يجب أن يكون حقل :attribute تاريخًا صالحًا.',
'date_equals' => 'يجب أن يكون حقل :attribute تاريخًا مساويًا لـ :date.',
'date_format' => 'يجب أن يطابق حقل :attribute التنسيق :format.',
'decimal' => 'يجب أن يحتوي حقل :attribute على :decimal منزلة عشرية.',
'declined' => 'يجب رفض حقل :attribute.',
'declined_if' => 'يجب رفض حقل :attribute عندما يكون :other مساويًا لـ :value.',
'different' => 'يجب أن يختلف حقل :attribute عن :other.',
'digits' => 'يجب أن يتكوّن حقل :attribute من :digits رقمًا.',
'digits_between' => 'يجب أن يتكوّن حقل :attribute من عدد أرقام بين :min و:max.',
'dimensions' => 'أبعاد صورة حقل :attribute غير صالحة.',
'distinct' => 'يحتوي حقل :attribute على قيمة مكرّرة.',
'doesnt_contain' => 'يجب ألا يحتوي حقل :attribute على أي مما يلي: :values.',
'doesnt_end_with' => 'يجب ألا ينتهي حقل :attribute بأي مما يلي: :values.',
'doesnt_start_with' => 'يجب ألا يبدأ حقل :attribute بأي مما يلي: :values.',
'email' => 'يجب أن يكون حقل :attribute بريدًا إلكترونيًا صالحًا.',
'encoding' => 'يجب أن يكون ترميز حقل :attribute بصيغة :encoding.',
'ends_with' => 'يجب أن ينتهي حقل :attribute بأحد ما يلي: :values.',
'enum' => 'قيمة :attribute المحدّدة غير صالحة.',
'exists' => 'قيمة :attribute المحدّدة غير صالحة.',
'extensions' => 'يجب أن يحمل حقل :attribute أحد الامتدادات التالية: :values.',
'file' => 'يجب أن يكون حقل :attribute ملفًا.',
'filled' => 'يجب أن يحتوي حقل :attribute على قيمة.',
'gt' => [
'array' => 'يجب أن يحتوي حقل :attribute على أكثر من :value عنصرًا.',
'file' => 'يجب أن يكون حجم حقل :attribute أكبر من :value كيلوبايت.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute أكبر من :value.',
'string' => 'يجب أن يكون طول حقل :attribute أكبر من :value حرفًا.',
],
'gte' => [
'array' => 'يجب أن يحتوي حقل :attribute على :value عنصرًا أو أكثر.',
'file' => 'يجب أن يكون حجم حقل :attribute أكبر من :value كيلوبايت أو مساويًا له.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute أكبر من :value أو مساوية له.',
'string' => 'يجب أن يكون طول حقل :attribute أكبر من :value حرفًا أو مساويًا له.',
],
'hex_color' => 'يجب أن يكون حقل :attribute لونًا سداسيًا صالحًا.',
'image' => 'يجب أن يكون حقل :attribute صورة.',
'in' => 'قيمة :attribute المحدّدة غير صالحة.',
'in_array' => 'يجب أن يكون حقل :attribute موجودًا في :other.',
'in_array_keys' => 'يجب أن يحتوي حقل :attribute على واحد على الأقل من المفاتيح التالية: :values.',
'integer' => 'يجب أن يكون حقل :attribute عددًا صحيحًا.',
'ip' => 'يجب أن يكون حقل :attribute عنوان IP صالحًا.',
'ipv4' => 'يجب أن يكون حقل :attribute عنوان IPv4 صالحًا.',
'ipv6' => 'يجب أن يكون حقل :attribute عنوان IPv6 صالحًا.',
'json' => 'يجب أن يكون حقل :attribute نص JSON صالحًا.',
'list' => 'يجب أن يكون حقل :attribute قائمة.',
'lowercase' => 'يجب أن يكون حقل :attribute بأحرف صغيرة.',
'lt' => [
'array' => 'يجب أن يحتوي حقل :attribute على أقل من :value عنصرًا.',
'file' => 'يجب أن يكون حجم حقل :attribute أقل من :value كيلوبايت.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute أقل من :value.',
'string' => 'يجب أن يكون طول حقل :attribute أقل من :value حرفًا.',
],
'lte' => [
'array' => 'يجب ألا يحتوي حقل :attribute على أكثر من :value عنصرًا.',
'file' => 'يجب أن يكون حجم حقل :attribute أقل من :value كيلوبايت أو مساويًا له.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute أقل من :value أو مساوية له.',
'string' => 'يجب أن يكون طول حقل :attribute أقل من :value حرفًا أو مساويًا له.',
],
'mac_address' => 'يجب أن يكون حقل :attribute عنوان MAC صالحًا.',
'max' => [
'array' => 'يجب ألا يحتوي حقل :attribute على أكثر من :max عنصرًا.',
'file' => 'يجب ألا يزيد حجم حقل :attribute عن :max كيلوبايت.',
'numeric' => 'يجب ألا تزيد قيمة حقل :attribute عن :max.',
'string' => 'يجب ألا يزيد طول حقل :attribute عن :max حرفًا.',
],
'max_digits' => 'يجب ألا يحتوي حقل :attribute على أكثر من :max رقمًا.',
'mimes' => 'يجب أن يكون حقل :attribute ملفًا من نوع: :values.',
'mimetypes' => 'يجب أن يكون حقل :attribute ملفًا من نوع: :values.',
'min' => [
'array' => 'يجب أن يحتوي حقل :attribute على :min عنصرًا على الأقل.',
'file' => 'يجب أن يكون حجم حقل :attribute :min كيلوبايت على الأقل.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute :min على الأقل.',
'string' => 'يجب أن يكون طول حقل :attribute :min حرفًا على الأقل.',
],
'min_digits' => 'يجب أن يحتوي حقل :attribute على :min رقمًا على الأقل.',
'missing' => 'يجب أن يكون حقل :attribute غير موجود.',
'missing_if' => 'يجب أن يكون حقل :attribute غير موجود عندما يكون :other مساويًا لـ :value.',
'missing_unless' => 'يجب أن يكون حقل :attribute غير موجود ما لم يكن :other مساويًا لـ :value.',
'missing_with' => 'يجب أن يكون حقل :attribute غير موجود عند وجود :values.',
'missing_with_all' => 'يجب أن يكون حقل :attribute غير موجود عند وجود :values.',
'multiple_of' => 'يجب أن تكون قيمة حقل :attribute من مضاعفات :value.',
'not_in' => 'قيمة :attribute المحدّدة غير صالحة.',
'not_regex' => 'صيغة حقل :attribute غير صالحة.',
'numeric' => 'يجب أن يكون حقل :attribute رقمًا.',
'password' => [
'letters' => 'يجب أن يحتوي حقل :attribute على حرف واحد على الأقل.',
'mixed' => 'يجب أن يحتوي حقل :attribute على حرف كبير وحرف صغير على الأقل.',
'numbers' => 'يجب أن يحتوي حقل :attribute على رقم واحد على الأقل.',
'symbols' => 'يجب أن يحتوي حقل :attribute على رمز واحد على الأقل.',
'uncompromised' => 'ظهر حقل :attribute المُدخل في تسريب بيانات. يرجى اختيار :attribute مختلف.',
],
'present' => 'يجب أن يكون حقل :attribute موجودًا.',
'present_if' => 'يجب أن يكون حقل :attribute موجودًا عندما يكون :other مساويًا لـ :value.',
'present_unless' => 'يجب أن يكون حقل :attribute موجودًا ما لم يكن :other مساويًا لـ :value.',
'present_with' => 'يجب أن يكون حقل :attribute موجودًا عند وجود :values.',
'present_with_all' => 'يجب أن يكون حقل :attribute موجودًا عند وجود :values.',
'prohibited' => 'حقل :attribute محظور.',
'prohibited_if' => 'حقل :attribute محظور عندما يكون :other مساويًا لـ :value.',
'prohibited_if_accepted' => 'حقل :attribute محظور عند قبول :other.',
'prohibited_if_declined' => 'حقل :attribute محظور عند رفض :other.',
'prohibited_unless' => 'حقل :attribute محظور ما لم يكن :other ضمن :values.',
'prohibits' => 'يمنع حقل :attribute وجود :other.',
'regex' => 'صيغة حقل :attribute غير صالحة.',
'required' => 'حقل :attribute مطلوب.',
'required_array_keys' => 'يجب أن يحتوي حقل :attribute على إدخالات لـ: :values.',
'required_if' => 'حقل :attribute مطلوب عندما يكون :other مساويًا لـ :value.',
'required_if_accepted' => 'حقل :attribute مطلوب عند قبول :other.',
'required_if_declined' => 'حقل :attribute مطلوب عند رفض :other.',
'required_unless' => 'حقل :attribute مطلوب ما لم يكن :other ضمن :values.',
'required_with' => 'حقل :attribute مطلوب عند وجود :values.',
'required_with_all' => 'حقل :attribute مطلوب عند وجود :values.',
'required_without' => 'حقل :attribute مطلوب عند عدم وجود :values.',
'required_without_all' => 'حقل :attribute مطلوب عند عدم وجود أي من :values.',
'same' => 'يجب أن يطابق حقل :attribute قيمة :other.',
'size' => [
'array' => 'يجب أن يحتوي حقل :attribute على :size عنصرًا.',
'file' => 'يجب أن يكون حجم حقل :attribute :size كيلوبايت.',
'numeric' => 'يجب أن تكون قيمة حقل :attribute :size.',
'string' => 'يجب أن يكون طول حقل :attribute :size حرفًا.',
],
'starts_with' => 'يجب أن يبدأ حقل :attribute بأحد ما يلي: :values.',
'string' => 'يجب أن يكون حقل :attribute نصًا.',
'timezone' => 'يجب أن يكون حقل :attribute منطقة زمنية صالحة.',
'unique' => 'قيمة :attribute مُستخدمة بالفعل.',
'uploaded' => 'فشل رفع :attribute.',
'uppercase' => 'يجب أن يكون حقل :attribute بأحرف كبيرة.',
'url' => 'يجب أن يكون حقل :attribute رابطًا صالحًا.',
'ulid' => 'يجب أن يكون حقل :attribute معرّف ULID صالحًا.',
'uuid' => 'يجب أن يكون حقل :attribute معرّف UUID صالحًا.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];

50
lang/ar/workspaces.php Normal file
View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
return [
'title' => 'مساحات العمل',
'select_title' => 'مساحات العمل الخاصة بك',
'select_description' => 'اختر مساحة عمل للمتابعة',
'current' => 'الحالية',
'connections' => ':count اتصال',
'posts' => ':count منشور',
'create' => [
'page_title' => 'أنشئ مساحة عملك',
'title' => 'إعداد مساحة عملك',
'description' => 'أخبرنا قليلًا عنك أو عن مشروعك. سنستخدم ذلك لتخصيص المنشورات المُنشأة بالذكاء الاصطناعي لتتناسب مع أسلوبك.',
'website' => 'الموقع الإلكتروني',
'website_placeholder' => 'https://yourbrand.com',
'autofill' => 'تعبئة تلقائية من الموقع',
'autofill_missing_url' => 'أدخل رابطًا أولًا.',
'autofill_success' => 'تم تحميل معلومات العلامة التجارية.',
'autofill_error' => 'تعذرت التعبئة التلقائية. يمكنك ملء الحقول يدويًا.',
'autofill_errors' => [
'unreachable' => 'تعذر الوصول إلى ذلك الموقع (:reason).',
'http_status' => 'أعاد الموقع حالة غير متوقعة (:status).',
'invalid_scheme' => 'يتم دعم روابط http وhttps فقط.',
'missing_host' => 'الرابط يفتقد إلى المضيف.',
'unresolvable_host' => 'تعذر التعرف على المضيف (:host).',
'private_network' => 'الروابط التي تشير إلى الشبكات الخاصة غير مسموح بها.',
],
'logo_captured' => 'تم التقاط الشعار من موقعك الإلكتروني.',
'name' => 'اسم مساحة العمل',
'name_placeholder' => 'مثال: Acme Inc',
'brand_description' => 'وصف العلامة التجارية',
'brand_description_placeholder' => 'ماذا تفعل علامتك التجارية؟',
'content_language' => 'لغة المحتوى',
'content_language_description' => 'ستُكتب التسميات التوضيحية المُنشأة بالذكاء الاصطناعي بهذه اللغة.',
'brand_color' => 'لون العلامة التجارية',
'background_color' => 'لون الخلفية',
'text_color' => 'لون النص',
'submit' => 'إنشاء مساحة عمل',
'success' => 'تم إنشاء مساحة العمل. اربط حسابًا اجتماعيًا لبدء النشر.',
],
'cannot_delete_last' => 'لا يمكنك حذف مساحة العمل الوحيدة لديك. ألغِ اشتراكك من إعدادات الفوترة لإغلاق حسابك.',
'flash' => [
'deleted' => 'تم حذف مساحة العمل بنجاح.',
],
];

150
lang/de/accounts.php Normal file
View file

@ -0,0 +1,150 @@
<?php
declare(strict_types=1);
return [
'title' => 'Verbindungen',
'page_title' => 'Social-Media-Konten',
'description' => 'Übersicht über alle deine verbundenen Social-Media-Konten',
'connect_cta' => 'Verbinden',
'not_connected' => 'Nicht verbunden',
'connect' => 'Verbinden',
'connection_lost' => 'Verbindung verloren',
'reconnect' => 'Erneut verbinden',
'reconnect_account' => 'Konto erneut verbinden',
'view_profile' => 'Profil ansehen',
'disconnect' => 'Trennen',
'descriptions' => [
'linkedin' => 'Verbinde dein LinkedIn-Profil oder deine Unternehmensseite',
'linkedin-page' => 'Verbinde eine LinkedIn-Unternehmensseite',
'x' => 'Verbinde dein X-Konto (Twitter)',
'tiktok' => 'Verbinde dein TikTok-Konto',
'youtube' => 'Verbinde einen YouTube-Kanal',
'facebook' => 'Verbinde eine Facebook-Seite',
'instagram' => 'Verbinde ein professionelles Instagram-Konto',
'instagram-facebook' => 'Verbinde Instagram über eine Facebook-Seite',
'threads' => 'Verbinde dein Threads-Konto',
'pinterest' => 'Verbinde dein Pinterest-Konto',
'bluesky' => 'Verbinde dein Bluesky-Konto',
'mastodon' => 'Verbinde dein Mastodon-Konto',
'telegram' => 'Verbinde einen Telegram-Kanal oder eine Telegram-Gruppe',
'discord' => 'Verbinde einen Discord-Server',
],
'disconnect_modal' => [
'title' => 'Konto trennen',
'description' => 'Möchtest du dieses Konto wirklich trennen? Du kannst es jederzeit wieder verbinden.',
'confirm' => 'Trennen',
'cancel' => 'Abbrechen',
],
'bluesky' => [
'title' => 'Bluesky verbinden',
'description' => 'Gib deine Zugangsdaten ein, um dich zu verbinden',
'email' => 'E-Mail',
'email_placeholder' => 'yourhandle.bsky.social',
'app_password' => 'App-Passwort',
'app_password_placeholder' => 'xxxx-xxxx-xxxx-xxxx',
'app_password_hint' => 'Verwende aus Sicherheitsgründen ein <strong>App-Passwort</strong>. Erstelle eines unter <a href="https://bsky.app/settings/app-passwords" target="_blank" class="underline">bsky.app/settings</a>.',
'submit' => 'Bluesky verbinden',
'submitting' => 'Verbindung wird hergestellt...',
],
'mastodon' => [
'title' => 'Mastodon verbinden',
'description' => 'Gib deine Mastodon-Instanz ein',
'instance_url' => 'Instanz-URL',
'instance_placeholder' => 'https://mastodon.social',
'instance_hint' => 'Gib die URL deiner Mastodon-Instanz ein (z. B. mastodon.social, techhub.social)',
'submit' => 'Mit Mastodon fortfahren',
'submitting' => 'Verbindung wird hergestellt...',
],
'telegram' => [
'title' => 'Telegram verbinden',
'description' => 'Einen Kanal oder eine Gruppe verknüpfen',
'step_admin' => 'Füge :bot als Administrator zu deinem Telegram-Kanal oder deiner Telegram-Gruppe hinzu.',
'step_command' => 'Poste diesen Befehl im Kanal oder in der Gruppe:',
'waiting' => 'Warten auf die Verbindung des Kanals…',
'connected' => 'Kanal verbunden!',
'connected_toast' => 'Telegram-Kanal erfolgreich verbunden!',
'copied_toast' => 'Befehl in die Zwischenablage kopiert',
'copy_tooltip' => 'Befehl kopieren',
'expired' => 'Dieser Code ist abgelaufen. Erstelle einen neuen, um es erneut zu versuchen.',
'new_code' => 'Neuen Code erstellen',
'retry' => 'Erneut versuchen',
'error_generic' => 'Die Verbindung konnte nicht gestartet werden. Bitte versuche es erneut.',
'network_taken' => 'Dieser Workspace hat bereits einen verbundenen Telegram-Kanal. Trenne ihn zuerst.',
],
'facebook' => [
'title' => 'Facebook-Seite auswählen',
'description' => 'Wähle die Seite aus, die du verbinden möchtest',
'no_pages' => 'Keine Seiten gefunden',
'no_pages_description' => 'Du bist kein Administrator einer Facebook-Seite.',
'page_label' => 'Facebook-Seite',
'view' => 'Ansehen',
'choose' => 'Auswählen',
],
'instagram_facebook' => [
'title' => 'Instagram-Konto auswählen',
'description' => 'Wähle das Instagram-Konto aus, das du verbinden möchtest',
'no_pages' => 'Keine Instagram-Konten gefunden',
'no_pages_description' => 'Es wurden keine Facebook-Seiten mit verknüpften Instagram-Business-Konten gefunden.',
'view' => 'Ansehen',
'choose' => 'Auswählen',
],
'linkedin' => [
'title' => 'LinkedIn-Seite auswählen',
'description' => 'Wähle die Seite aus, die du verbinden möchtest',
'no_pages' => 'Keine Seiten gefunden',
'no_pages_description' => 'Du bist kein Administrator einer LinkedIn-Seite.',
'page_label' => 'LinkedIn-Seite',
'select_title' => 'Wo möchtest du posten?',
'select_subtitle' => 'Poste als du selbst oder wähle eine Unternehmensseite, die du verwaltest.',
'person_tag' => 'Person',
'organization_tag' => 'Organisation',
'view' => 'Ansehen',
'choose' => 'Auswählen',
],
'flash' => [
'disconnected' => 'Konto erfolgreich getrennt!',
'connected' => 'Konto erfolgreich verbunden!',
'session_expired' => 'Sitzung abgelaufen. Bitte versuche es erneut.',
'workspace_not_found' => 'Workspace nicht gefunden.',
'activated' => 'Konto aktiviert!',
'deactivated' => 'Konto deaktiviert!',
'already_connected' => 'Diese Plattform ist bereits verbunden.',
'no_youtube_channels' => 'Keine YouTube-Kanäle gefunden. Bitte erstelle zuerst einen Kanal.',
],
'popup_callback' => [
'title_success' => 'Verbunden',
'title_error' => 'Fehler',
'closing' => 'Dieses Fenster wird automatisch geschlossen...',
'manual_close' => 'Du kannst dieses Fenster schließen.',
'popup_blocked' => 'Das Verbindungsfenster konnte nicht geöffnet werden. Bitte erlaube Pop-ups und versuche es erneut.',
'connected' => 'Konto verbunden!',
'reconnected' => 'Konto erneut verbunden!',
'error_connecting' => 'Fehler beim Verbinden des Kontos. Bitte versuche es erneut.',
'network_taken' => 'Dieser Workspace hat bereits ein Konto für dieses Netzwerk. Trenne es zuerst.',
'error_connecting_page' => 'Fehler beim Verbinden der Seite. Bitte versuche es erneut.',
'error_connecting_channel' => 'Fehler beim Verbinden des Kanals. Bitte versuche es erneut.',
'session_expired' => 'Sitzung abgelaufen. Bitte versuche es erneut.',
'workspace_not_found' => 'Workspace nicht gefunden.',
'invalid_state' => 'Ungültiger Status. Bitte versuche es erneut.',
'failed_to_authenticate' => 'Authentifizierung fehlgeschlagen.',
'failed_to_get_profile' => 'Profil konnte nicht abgerufen werden.',
'page_not_found' => 'Seite nicht gefunden.',
'channel_not_found' => 'Kanal nicht gefunden.',
'no_facebook_pages' => 'Keine Facebook-Seiten gefunden. Du musst Administrator mindestens einer Seite sein.',
'no_facebook_instagram_pages' => 'Keine Facebook-Seiten mit verknüpften Instagram-Konten gefunden.',
'no_youtube_channels' => 'Keine YouTube-Kanäle gefunden. Bitte erstelle zuerst einen Kanal.',
'not_linkedin_admin' => 'Du bist kein Administrator einer LinkedIn-Seite.',
],
];

57
lang/de/analytics.php Normal file
View file

@ -0,0 +1,57 @@
<?php
declare(strict_types=1);
return [
'no_accounts' => 'Keine verbundenen Konten mit Analysedaten.',
'no_accounts_match' => 'Keine passenden Konten.',
'search_account' => 'Konto suchen…',
'select_account' => 'Wähle ein Konto, um die Analysedaten anzuzeigen.',
'no_data' => 'Keine Analysedaten verfügbar.',
'metrics' => [
'avg_view_duration' => 'Durchschn. Wiedergabedauer (s)',
'avg_view_percentage' => 'Durchschn. Wiedergabeanteil',
'bookmarks' => 'Lesezeichen',
'clicks' => 'Klicks',
'comments' => 'Kommentare',
'custom_reaction' => 'Benutzerdefiniert',
'engagement' => 'Engagement',
'favourites' => 'Favoriten',
'followers' => 'Follower',
'following' => 'Abonniert',
'impressions' => 'Impressionen',
'interactions' => 'Interaktionen',
'likes' => 'Likes',
'members' => 'Mitglieder',
'minutes_watched' => 'Angesehene Minuten',
'organic_followers' => 'Organische Follower',
'outbound_clicks' => 'Ausgehende Klicks',
'page_followers' => 'Seiten-Follower',
'page_reach' => 'Seiten-Reichweite',
'page_views' => 'Seitenaufrufe',
'paid_followers' => 'Bezahlte Follower',
'pin_click_rate' => 'Pin-Klickrate',
'pin_clicks' => 'Pin-Klicks',
'posts_engagement' => 'Beitrags-Engagement',
'posts_reach' => 'Beitrags-Reichweite',
'quotes' => 'Zitate',
'reach' => 'Reichweite',
'reblogs' => 'Reblogs',
'recent_comments' => 'Neueste Kommentare',
'recent_likes' => 'Neueste Likes',
'recent_shares' => 'Neueste Shares',
'replies' => 'Antworten',
'reposts' => 'Reposts',
'retweets' => 'Retweets',
'saves' => 'Gespeichert',
'shares' => 'Shares',
'subscribers' => 'Abonnenten',
'subscribers_gained' => 'Gewonnene Abonnenten',
'subscribers_lost' => 'Verlorene Abonnenten',
'total_likes' => 'Likes gesamt',
'video_views' => 'Videoaufrufe',
'videos' => 'Videos',
'views' => 'Aufrufe',
],
];

54
lang/de/assets.php Normal file
View file

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
return [
'title' => 'Assets',
'tabs' => [
'my_uploads' => 'Meine Uploads',
'stock_photos' => 'Stockfotos',
'gifs' => 'GIFs',
],
'upload' => [
'drag_drop' => 'Dateien hierher ziehen und ablegen oder zum Auswählen klicken',
'formats' => 'JPEG, PNG, GIF, WebP, MP4, PDF',
'uploading' => 'Wird hochgeladen...',
'failed' => ':file konnte nicht hochgeladen werden. Bitte versuche es erneut.',
],
'empty' => [
'title' => 'Noch keine Assets',
'description' => 'Lade Bilder und Videos hoch, um deine Medienbibliothek aufzubauen.',
],
'save_to_assets' => 'In Assets speichern',
'saved' => 'In deinen Assets gespeichert!',
'create_post' => 'Beitrag erstellen',
'add_to_post' => 'Zum Beitrag hinzufügen',
'search_placeholder' => 'Medien suchen...',
'delete' => [
'title' => 'Asset löschen',
'description' => 'Möchtest du dieses Asset wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.',
'confirm' => 'Löschen',
'cancel' => 'Abbrechen',
],
'unsplash' => [
'search_placeholder' => 'Kostenlose Fotos suchen...',
'no_results' => 'Keine Fotos gefunden',
'no_results_description' => 'Versuche einen anderen Suchbegriff.',
'trending' => 'Beliebt auf Unsplash',
'start_searching' => 'Suche nach kostenlosen Stockfotos von Unsplash',
],
'giphy' => [
'trending' => 'Beliebt auf Giphy',
'search_placeholder' => 'GIFs suchen...',
'no_results' => 'Keine GIFs gefunden',
'no_results_description' => 'Versuche einen anderen Suchbegriff.',
'powered_by' => 'Bereitgestellt von GIPHY',
],
];

143
lang/de/auth.php Normal file
View file

@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'Diese Zugangsdaten stimmen nicht mit unseren Aufzeichnungen überein.',
'password' => 'Das angegebene Passwort ist falsch.',
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuche es in :seconds Sekunden erneut.',
'flash' => [
'welcome' => 'Willkommen bei TryPost!',
'welcome_trial' => 'Willkommen bei TryPost! Deine Testphase hat begonnen.',
],
'legal' => 'Indem du fortfährst, stimmst du unseren <a href="https://trypost.it/terms" target="_blank">Nutzungsbedingungen</a> und unserer <a href="https://trypost.it/privacy" target="_blank">Datenschutzerklärung</a> zu.',
'slides' => [
'calendar' => [
'title' => 'Visueller Kalender',
'description' => 'Plane und terminiere deine Inhalte mit einem intuitiven Drag-and-drop-Kalender für alle deine Social-Media-Konten.',
],
'scheduling' => [
'title' => 'Intelligente Planung',
'description' => 'Plane Beiträge für LinkedIn, X, Instagram, TikTok, YouTube und mehr – alles von einem Ort aus.',
],
'media' => [
'title' => 'Rich Media',
'description' => 'Veröffentliche Bilder, Karussells, Storys und Reels. Jede Plattform erhält automatisch das richtige Format.',
],
'video' => [
'title' => 'Video-Veröffentlichung',
'description' => 'Lade Videos einmal hoch und veröffentliche sie auf TikTok, YouTube Shorts, Instagram Reels und Facebook Reels.',
],
'team' => [
'title' => 'Team-Workspaces',
'description' => 'Lade dein Team ein, weise Rollen zu und verwalte mehrere Marken in separaten Workspaces.',
],
'signatures' => [
'title' => 'Signaturen',
'description' => 'Speichere wiederverwendbare Signaturen (Hashtags, Links, Grußformeln) und füge sie mit einem Klick zu Beiträgen hinzu.',
],
],
'or_continue_with' => 'Oder fortfahren mit',
'or_continue_with_email' => 'Oder mit E-Mail fortfahren',
'google_login' => 'Mit Google anmelden',
'google_signup' => 'Mit Google registrieren',
'github_login' => 'Mit GitHub anmelden',
'github_signup' => 'Mit GitHub registrieren',
'github_email_unavailable' => 'Deine E-Mail-Adresse konnte nicht von GitHub abgerufen werden. Mache deine GitHub-E-Mail-Adresse öffentlich oder erteile die Berechtigung für den E-Mail-Zugriff und versuche es dann erneut.',
'signup_success' => [
'page_title' => 'Willkommen',
'title' => 'Dein Konto wird eingerichtet',
'description' => 'Das dauert normalerweise nur wenige Sekunden...',
],
'login' => [
'title' => 'Melde dich bei deinem Konto an',
'description' => 'Gib unten deine E-Mail-Adresse und dein Passwort ein, um dich anzumelden',
'page_title' => 'Anmelden',
'email' => 'E-Mail-Adresse',
'password' => 'Passwort',
'forgot_password' => 'Passwort vergessen?',
'remember_me' => 'Angemeldet bleiben',
'submit' => 'Anmelden',
'no_account' => 'Noch kein Konto?',
'sign_up' => 'Registrieren',
],
'register' => [
'title' => 'Dein gesamter Social-Media-Kalender an einem Ort',
'description' => 'Erstelle dein Konto und beginne, Beiträge für jedes Netzwerk zu planen.',
'page_title' => 'Registrieren',
'signup_with_email' => 'Mit E-Mail registrieren',
'name' => 'Name',
'name_placeholder' => 'Vollständiger Name',
'email' => 'E-Mail-Adresse',
'password' => 'Passwort',
'show_password' => 'Passwort anzeigen',
'hide_password' => 'Passwort verbergen',
'submit' => 'Konto erstellen',
'has_account' => 'Hast du bereits ein Konto?',
'log_in' => 'Anmelden',
],
'forgot_password' => [
'title' => 'Passwort vergessen',
'description' => 'Gib deine E-Mail-Adresse ein, um einen Link zum Zurücksetzen des Passworts zu erhalten',
'page_title' => 'Passwort vergessen',
'email' => 'E-Mail-Adresse',
'submit' => 'Link zum Zurücksetzen des Passworts senden',
'return_to' => 'Oder zurück zur',
'log_in' => 'Anmeldung',
],
'reset_password' => [
'title' => 'Passwort zurücksetzen',
'description' => 'Bitte gib unten dein neues Passwort ein',
'page_title' => 'Passwort zurücksetzen',
'email' => 'E-Mail',
'password' => 'Passwort',
'confirm_password' => 'Passwort bestätigen',
'confirm_placeholder' => 'Passwort bestätigen',
'submit' => 'Passwort zurücksetzen',
],
'verify_email' => [
'title' => 'E-Mail bestätigen',
'description' => 'Bitte bestätige deine E-Mail-Adresse, indem du auf den Link klickst, den wir dir gerade per E-Mail gesendet haben.',
'page_title' => 'E-Mail-Bestätigung',
'link_sent' => 'Ein neuer Bestätigungslink wurde an die E-Mail-Adresse gesendet, die du bei der Registrierung angegeben hast.',
'resend' => 'Bestätigungs-E-Mail erneut senden',
'log_out' => 'Abmelden',
],
'accept_invite' => [
'page_title' => 'Einladung annehmen',
'title' => 'Du wurdest eingeladen!',
'description' => 'Du wurdest eingeladen, dem Workspace :workspace beizutreten.',
'workspace' => 'Workspace',
'your_role' => 'Deine Rolle',
'email' => 'E-Mail',
'accept' => 'Einladung annehmen',
'decline' => 'Einladung ablehnen',
'login_prompt' => 'Melde dich an oder erstelle ein Konto, um diese Einladung anzunehmen.',
'log_in' => 'Anmelden',
'create_account' => 'Konto erstellen',
],
];

411
lang/de/automations.php Normal file
View file

@ -0,0 +1,411 @@
<?php
declare(strict_types=1);
return [
'title' => 'Automatisierungen',
'default_name' => 'Neue Automatisierung',
'actions' => [
'new' => 'Neue Automatisierung',
'edit' => 'Bearbeiten',
'save' => 'Speichern',
'activate' => 'Aktivieren',
'pause' => 'Pausieren',
'delete' => 'Löschen',
'retry' => 'Erneut versuchen',
'guide' => 'So funktioniert es',
],
'tabs' => [
'build' => 'Erstellen',
'variables' => 'Variablen',
'test' => 'Test',
],
'nav' => [
'workflow' => 'Workflow',
'invocations' => 'Ausführungen',
'metrics' => 'Kennzahlen',
'settings' => 'Einstellungen',
],
'settings' => [
'general' => 'Allgemein',
'general_description' => 'Benenne diese Automatisierung um.',
'name_label' => 'Name',
'name_saved' => 'Automatisierung umbenannt.',
'status_title' => 'Status',
'status_description' => 'Aktiviere sie, um sie auszuführen, oder pausiere sie, um sie zu stoppen.',
'activated_at' => 'Aktiviert :date',
'paused_at' => 'Pausiert :date',
'created_at' => 'Erstellt :date',
'danger_title' => 'Gefahrenzone',
'danger_description' => 'Unumkehrbare Aktionen.',
'delete_title' => 'Diese Automatisierung löschen',
'delete_description' => 'Entfernt die Automatisierung und ihren Ausführungsverlauf dauerhaft.',
],
'status_run' => [
'pending' => 'Ausstehend',
'running' => 'Läuft',
'waiting' => 'Wartet',
'completed' => 'Abgeschlossen',
'failed' => 'Fehlgeschlagen',
'cancelled' => 'Abgebrochen',
],
'node_type' => [
'trigger' => 'Trigger',
'generate' => 'Inhalt generieren',
'delay' => 'Verzögerung',
'condition' => 'Bedingung',
'publish' => 'Veröffentlichen',
'webhook' => 'Webhook',
'end' => 'Ende',
'fetch_rss' => 'RSS abrufen',
'http_request' => 'HTTP-Anfrage',
],
'invocations' => [
'empty' => 'Noch keine Ausführungen.',
'refresh' => 'Aktualisieren',
'search_placeholder' => 'Nach Ausführungs-ID suchen…',
'copied' => 'Ausführungs-ID kopiert.',
'loading' => 'Schritte werden geladen…',
'no_steps' => 'Keine Schritte aufgezeichnet.',
'load_error' => 'Schritte konnten nicht geladen werden.',
'steps' => '{0}Keine Schritte|{1}:count Schritt|[2,*]:count Schritte',
'filter' => [
'all' => 'Alle Status',
],
'columns' => [
'timestamp' => 'Zeitstempel',
'run' => 'Ausführung',
'status' => 'Status',
'message' => 'Letzte Meldung',
'duration' => 'Dauer',
],
'summary' => [
'completed' => 'Workflow abgeschlossen',
'failed' => 'Workflow fehlgeschlagen',
'running' => 'Workflow läuft',
'cancelled' => 'Workflow abgebrochen',
'pending' => 'Workflow ausstehend',
],
],
'metrics' => [
'overview' => 'Übersicht',
'runs_over_time' => 'Ausführungen im Zeitverlauf',
'posts_by_platform' => 'Beiträge nach Plattform',
'no_posts' => 'In diesem Zeitraum wurden keine Beiträge veröffentlicht.',
'cards' => [
'runs' => 'Ausführungen gesamt',
'completed' => 'Abgeschlossen',
'failed' => 'Fehlgeschlagen',
'in_progress' => 'In Bearbeitung',
'success_rate' => 'Erfolgsquote',
'avg_duration' => 'Durchschn. Dauer',
'posts_created' => 'Erstellte Beiträge',
],
'legend' => [
'started' => 'Gestartet',
'completed' => 'Abgeschlossen',
'failed' => 'Fehlgeschlagen',
],
],
'categories' => [
'sources' => 'Quellen',
'content' => 'Inhalt',
'flow' => 'Ablauf',
'output' => 'Ausgabe',
],
'variables' => [
'title' => 'Workflow-Variablen',
'hint' => 'Wiederverwendbare Werte, die überall mit {{ variables.KEY }} referenziert werden. Verschlüsselt gespeichert.',
'empty' => 'Noch keine Variablen.',
'key' => 'Schlüssel',
'value' => 'Wert',
'key_placeholder' => 'API_KEY',
'value_placeholder' => 'Wert',
'add' => 'Neue Variable',
],
'expr' => [
'trigger_event' => 'Name des Trigger-Events',
'trigger_fired_at' => 'Wann der Trigger ausgelöst wurde',
'trigger_post_id' => 'ID des auslösenden Beitrags',
'trigger_post_content' => 'Inhalt des auslösenden Beitrags',
'trigger_post_status' => 'Status des auslösenden Beitrags',
'trigger_post_scheduled_at' => 'Wann der Beitrag geplant ist',
'trigger_post_published_at' => 'Wann der Beitrag veröffentlicht wurde',
'fetched_title' => 'Titel des abgerufenen Eintrags',
'fetched_link' => 'Link des abgerufenen Eintrags',
'fetched_date' => 'Veröffentlichungsdatum des abgerufenen Eintrags',
'fetched_content' => 'Vollständiger Inhalt des abgerufenen Eintrags',
'fetched_description' => 'Zusammenfassung des abgerufenen Eintrags',
'fetched_author' => 'Autor des abgerufenen Eintrags',
'fetched_image' => 'Bild-URL des abgerufenen Eintrags',
'fetched_categories' => 'Kategorien des abgerufenen Eintrags',
'fetched_enclosure' => 'Medien des abgerufenen Eintrags (Audio/Video/Datei)',
'fetched_pubdate' => 'Veröffentlichungsdatum des abgerufenen Eintrags',
'fetched_http' => 'Abgerufener HTTP-Eintrag (Feld anhängen)',
'generated_content' => 'KI-generierter Beitragsinhalt',
'generated_post_url' => 'URL des KI-generierten Beitrags',
'variable' => 'Workflow-Variable',
'now' => 'Aktuelles Datum & Uhrzeit',
],
'test' => [
'description' => 'Führt die Automatisierung durchgängig mit einer synthetisierten Trigger-Nutzlast aus. Nützlich, um jeden Node zu validieren, ohne auf den echten Zeitplan oder Feed zu warten.',
'starting' => 'Testlauf wird gestartet…',
'in_progress' => 'In Bearbeitung',
'completed' => 'Abgeschlossen',
'failed' => 'Fehlgeschlagen',
'waiting' => 'Wartet',
'close' => 'Schließen',
'no_node_runs' => 'Warten auf den Start des ersten Nodes…',
'node_input' => 'Eingabe',
'node_output' => 'Ausgabe',
'node_error' => 'Fehler',
'no_new_items' => 'Keine neuen Einträge – nichts Nachgelagertes wurde ausgeführt.',
'error_starting' => 'Der Testlauf konnte nicht gestartet werden.',
'with_real_data' => 'Mit echten Daten',
'run' => 'Test ausführen',
'idle_hint' => 'Klicke auf „Test ausführen", um die Automatisierung durchgängig auszuführen.',
'real_data_hint' => 'Dieser Test veröffentlicht Beiträge, setzt Polling-Markierungen fort und löst externe Seiteneffekte aus.',
'dry_badge' => 'Probelauf',
],
'status' => [
'draft' => 'Entwurf',
'active' => 'Aktiv',
'paused' => 'Pausiert',
],
'index' => [
'empty_title' => 'Noch keine Automatisierungen',
'empty_description' => 'Erstelle deine erste Automatisierung, um auf Autopilot zu veröffentlichen.',
'columns' => [
'name' => 'Name',
'status' => 'Status',
'created' => 'Erstellt',
],
],
'form' => [
'activate_error_fallback' => 'Automatisierung konnte nicht aktiviert werden.',
'pause_error_fallback' => 'Automatisierung konnte nicht pausiert werden.',
'save_error_fallback' => 'Automatisierung konnte nicht gespeichert werden.',
'save_success' => 'Automatisierung gespeichert.',
'empty_canvas_title' => 'Beginne mit dem Aufbau deiner Automatisierung',
'empty_canvas_description' => 'Ziehe einen Node aus dem linken Bereich, um zu starten.',
'name_placeholder' => 'Unbenannte Automatisierung',
],
'nodes' => [
'trigger' => 'Trigger',
'generate' => 'Generieren',
'delay' => 'Verzögerung',
'condition' => 'Bedingung',
'publish' => 'Veröffentlichen',
'webhook' => 'Webhook',
'end' => 'Ende',
'end_summary' => 'Stoppt die Automatisierung hier',
'fetch_rss' => 'RSS abrufen',
'http_request' => 'HTTP-Anfrage',
'handles' => [
'items' => 'hat Einträge',
'no_items' => 'keine Einträge',
],
],
'config' => [
'select_placeholder' => 'Auswählen…',
'invalid_json' => 'Das ist noch kein gültiges JSON.',
'expand_editor' => 'Editor vergrößern',
'minimize_editor' => 'Verkleinern',
'trigger' => [
'type' => 'Trigger-Typ',
'types' => [
'schedule' => 'Zeitplan',
'post_published' => 'Wenn ein Beitrag veröffentlicht wird',
'post_scheduled' => 'Wenn ein Beitrag geplant wird',
],
'post_published_hint' => 'Läuft, wann immer ein Beitrag in diesem Workspace veröffentlicht wird. Der veröffentlichte Beitrag steht unter {{ trigger.post }} für nachgelagerte Nodes zur Verfügung.',
'post_scheduled_hint' => 'Läuft, wann immer ein Beitrag in diesem Workspace geplant wird. Der geplante Beitrag steht unter {{ trigger.post }} zur Verfügung.',
'schedule' => [
'field' => 'Trigger-Intervall',
'fields' => [
'minutes' => 'Minuten',
'hours' => 'Stunden',
'days' => 'Tage',
'weeks' => 'Wochen',
'months' => 'Monate',
],
'minutes_interval' => 'Minuten zwischen den Triggern',
'hours_interval' => 'Stunden zwischen den Triggern',
'days_interval' => 'Tage zwischen den Triggern',
'hour' => 'Auslösen zur Stunde',
'minute' => 'Auslösen zur Minute',
'weekdays' => 'An Wochentagen auslösen',
'day_of_month' => 'Tag des Monats',
'weekday_names' => [
'sun' => 'So',
'mon' => 'Mo',
'tue' => 'Di',
'wed' => 'Mi',
'thu' => 'Do',
'fri' => 'Fr',
'sat' => 'Sa',
],
'summary' => [
'every_n_minutes' => 'Läuft jede Minute|Läuft alle :count Minuten',
'every_n_hours' => 'Läuft jede Stunde zur Minute :minute|Läuft alle :count Stunden zur Minute :minute',
'every_n_days' => 'Läuft täglich um :time|Läuft alle :count Tage um :time',
'weekly' => 'Läuft :days um :time',
'monthly' => 'Läuft an Tag :day jedes Monats um :time',
],
],
],
'generate' => [
'social_accounts' => 'Social-Media-Konten',
'social_accounts_empty' => 'Keine verbundenen Social-Media-Konten. Verbinde zuerst eines.',
'target_slide_count' => 'Zu generierende Slides',
'prompt_template' => 'Prompt-Vorlage',
'prompt_template_hint' => 'Tippe {{, um Daten aus vorherigen Schritten einzufügen.',
'image_count' => 'Zu generierende Bilder',
'image_count_hint' => '0 = reiner Textbeitrag (kein Bild). 1 = einzelnes Bild. 2+ = Karussell.',
'use_brand_voice' => 'Markenton verwenden',
'use_brand_voice_hint' => 'Wende deine Markenbeschreibung und deinen Markenton an. Deaktiviere dies für die originalgetreue Kuratierung von Drittquellen (News, RSS).',
'use_brand_visuals' => 'Marken-Visuals verwenden',
'use_brand_visuals_hint' => 'Steuere KI-Bilder mit deinen Markenfarben und deiner Markenidentität. Deaktiviere dies für neutrale Bilder, die nur vom Beitragsthema bestimmt werden.',
'style' => 'Stil',
'account_summary' => ':count Konto · :format|:count Konten · :format',
'formats' => [
'single' => 'Einzeln',
'carousel' => 'Karussell',
],
],
'delay' => [
'duration' => 'Dauer',
'unit' => 'Einheit',
'units' => [
'minutes' => 'Minuten',
'hours' => 'Stunden',
'days' => 'Tage',
],
],
'condition' => [
'field' => 'Feld',
'operator' => 'Operator',
'operators' => [
'contains' => 'enthält',
'not_contains' => 'enthält nicht',
'equals' => 'ist gleich',
'not_equals' => 'ist ungleich',
'matches' => 'entspricht (Regex)',
'greater_than' => 'größer als',
'less_than' => 'kleiner als',
],
'value' => 'Wert',
],
'publish' => [
'mode' => 'Modus',
'modes' => [
'now' => 'Jetzt veröffentlichen',
'scheduled' => 'Planen',
'draft' => 'Als Entwurf speichern',
],
'scheduled_offset' => 'Versatz zum Trigger (Minuten)',
'offset_summary' => ':mode · +:offset Min.',
],
'webhook' => [
'url' => 'URL',
'method' => 'Methode',
'payload_template' => 'Payload-Vorlage (JSON)',
],
'end' => [
'reason' => 'Grund (optional)',
'reason_placeholder' => 'z. B. Durch Bedingung herausgefiltert',
],
'fetch_rss' => [
'feed_url' => 'Feed-URL',
'feed_url_hint' => 'Beim ersten Durchlauf wird die Markierung auf "now" gesetzt, damit historische Einträge die nachgelagerten Nodes nicht überfluten. Nachfolgende Durchläufe sehen nur Einträge, die neuer sind als die vorherige Abfrage.',
'inspect' => 'Feed prüfen',
'inspecting' => 'Wird geprüft…',
'inspect_hint' => 'Rufe ein Beispiel ab, um die verfügbaren Felder für nachgelagerte Nodes zu ermitteln.',
'inspect_error' => 'Dieser Feed konnte nicht gelesen werden. Prüfe die URL und versuche es erneut.',
'discovered_fields' => 'Verfügbare Felder',
'discovered_empty' => 'Keine Felder im neuesten Eintrag gefunden.',
],
'http_request' => [
'url' => 'URL',
'method' => 'Methode',
'auth_type' => 'Authentifizierung',
'auth' => [
'none' => 'Keine (öffentlich)',
'bearer' => 'Bearer-Token',
'basic' => 'Basic Auth',
'api_key' => 'API-Key-Header',
],
'bearer_token' => 'Bearer-Token',
'basic_username' => 'Benutzername',
'basic_password' => 'Passwort',
'api_key_header' => 'Header-Name',
'api_key_value' => 'API-Key',
'body_template' => 'Body-Vorlage (JSON)',
'headers' => 'Header',
'header_name' => 'Header-Name',
'header_value' => 'Wert',
'add_header' => 'Header hinzufügen',
'polling_section' => 'Liste & Deduplizierung (optional)',
'polling_hint' => 'Wenn die Antwort eine Liste ist, durchläuft jeder Eintrag den Workflow separat. Ein einzelnes Objekt wird einmal ausgeführt.',
'items_path' => 'Pfad zu den Einträgen',
'items_path_hint' => 'Leer lassen, wenn die Antwort bereits ein Array ist. Verwende einen Punkt-Pfad (z. B. data.items) für ein verschachteltes Array oder * für ein nach ID indiziertes Objekt.',
'item_key_path' => 'Pfad zum Eintragsschlüssel',
'item_key_path_hint' => 'JSON-Pfad zu einer eindeutigen ID (z. B. id). Bereits gesehene Einträge werden übersprungen, sodass ein Feed ohne Datumsangaben trotzdem nur neue Einträge weiterleitet.',
'item_date_path' => 'Pfad zum Eintragsdatum',
'item_date_path_hint' => 'JSON-Pfad zum Zeitstempel des Eintrags (z. B. published_at). Wird, sofern verfügbar, dem Schlüssel-Pfad vorgezogen. Die erste Abfrage erfasst den Ausgangswert und leitet nichts weiter, sodass ein bestehender Feed am ersten Tag niemals überflutet.',
],
],
'delete' => [
'title' => 'Automatisierung löschen',
'description' => 'Möchtest du diese Automatisierung wirklich löschen? Alle Ausführungen und Trigger-Einträge werden ebenfalls entfernt. Diese Aktion kann nicht rückgängig gemacht werden.',
'confirm' => 'Löschen',
'cancel' => 'Abbrechen',
],
'flash' => [
'deleted' => 'Automatisierung erfolgreich gelöscht!',
],
'errors' => [
'no_active_social_accounts' => 'Für diese Automatisierung sind keine aktiven Social-Media-Konten konfiguriert.',
'must_have_one_trigger' => 'Eine Automatisierung muss genau einen Trigger-Node haben.',
'trigger_must_be_connected' => 'Der Trigger-Node muss mit mindestens einem Node verbunden sein.',
'graph_contains_cycle' => 'Der Automatisierungsgraph enthält einen Zyklus.',
'only_failed_can_retry' => 'Nur fehlgeschlagene Ausführungen können wiederholt werden.',
'no_generated_post' => 'Bei der Ausführung wurde kein generierter Beitrag gefunden.',
'webhook_server_error' => 'Webhook-Serverfehler.',
'webhook_request_failed' => 'Die Webhook-Anfrage konnte nicht abgeschlossen werden.',
'webhook_missing_url' => 'Dem Webhook-Node fehlt eine URL.',
'webhook_invalid_payload_json' => 'Die Payload-Vorlage ist kein gültiges JSON.',
'url_not_allowed' => 'Die Anfrage-URL verweist auf eine private oder nicht erreichbare Adresse und wurde blockiert.',
'node_no_longer_exists' => 'Node :node_id existiert in der Automatisierung nicht mehr.',
'no_trigger_connection' => 'Kein Node mit dem Trigger-Node verbunden.',
'fetch_rss_missing_url' => 'Dem Node „RSS abrufen" fehlt eine Feed-URL.',
'fetch_rss_request_failed' => 'Die Anfrage an den RSS-Feed ist fehlgeschlagen.',
'fetch_rss_malformed' => 'Der RSS-Feed ist fehlerhaft.',
'http_missing_url' => 'Dem HTTP-Anfrage-Node fehlt eine URL.',
'http_request_exception' => 'Die HTTP-Anfrage hat eine Ausnahme ausgelöst.',
'http_request_failed' => 'Die HTTP-Anfrage ist fehlgeschlagen.',
'http_items_path_not_array' => 'Der Pfad zu den Einträgen ergab keine Liste.',
],
];

78
lang/de/billing.php Normal file
View file

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
return [
'title' => 'Abrechnung',
'past_due_notice' => [
'title' => 'Zahlung überfällig',
'description' => 'Aktualisiere deine Zahlungsmethode, um dein Abonnement aktiv zu halten.',
'cta' => 'Zahlung aktualisieren',
],
'annual_banner' => [
'title' => '2 Monate gratis erhalten',
'description' => 'Wechsle zur jährlichen Abrechnung und zahle jeden Monat weniger – gleicher Tarif, sonst ändert sich nichts.',
'cta' => 'Auf jährlich upgraden',
],
'subscribe' => [
'billed_monthly' => 'Monatlich abgerechnet',
'billed_yearly' => 'Jährlich abgerechnet',
'prices' => [
'workspace' => ['monthly' => '$12', 'yearly_per_month' => '$10', 'yearly' => '$120'],
],
],
'plan' => [
'title' => 'Tarif',
'description' => 'Verwalte deinen Abonnement-Tarif.',
'label' => 'Tarif',
'workspaces' => '{1}:count Workspace|[2,*]:count Workspaces',
'per_workspace' => 'pro Workspace',
'price' => 'Preis',
'month' => 'Monat',
'trial' => 'Testphase',
'active' => 'Aktiv',
'past_due' => 'Überfällig',
'cancelling' => 'Wird gekündigt',
'trial_ends' => 'Testphase endet',
],
'subscription' => [
'title' => 'Abonnement',
'description' => 'Verwalte deine Zahlungsmethode, Rechnungsdaten und dein Abonnement.',
'payment_method' => 'Zahlungsmethode',
'no_payment_method' => 'Noch keine Zahlungsmethode hinterlegt.',
'expires_on' => 'Läuft ab :month/:year',
'manage_label' => 'Abonnement',
'manage_stripe' => 'Bei Stripe verwalten',
],
'invoices' => [
'title' => 'Rechnungen',
'description' => 'Lade deine bisherigen Rechnungen herunter.',
'empty' => 'Keine Rechnungen gefunden',
'paid' => 'Bezahlt',
],
'flash' => [
'plan_changed' => 'Du nutzt jetzt den Tarif :plan.',
'switched_to_yearly' => 'Du nutzt jetzt die jährliche Abrechnung.',
'cannot_manage' => 'Nur der Kontoinhaber kann die Abrechnung verwalten.',
'credits_exhausted' => 'Keine KI-Credits mehr – dein monatliches Kontingent von :limit ist aufgebraucht. Führe ein Upgrade durch oder warte bis zum nächsten Monat.',
'subscription_required' => 'Für die Nutzung der KI-Funktionen ist ein aktives Abonnement erforderlich.',
],
'processing' => [
'page_title' => 'Wird verarbeitet...',
'title' => 'Dein Abonnement wird verarbeitet',
'description' => 'Bitte warte, während wir dein Konto einrichten. Das dauert nur einen Moment.',
'success_title' => 'Alles bereit!',
'success_description' => 'Dein Abonnement ist aktiv. Du wirst zu deinen Workspaces weitergeleitet...',
'cancelled_title' => 'Bezahlvorgang abgebrochen',
'cancelled_description' => 'Dein Bezahlvorgang wurde abgebrochen. Es wurden keine Kosten berechnet.',
'retry' => 'Erneut versuchen',
],
];

41
lang/de/brands.php Normal file
View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
return [
'new_brand' => 'Neue Marke',
'no_brands_yet' => 'Noch keine Marken',
'no_brands_description' => 'Erstelle Marken, um deine Social-Media-Konten nach Kunde oder Projekt zu organisieren',
'accounts_count' => ':count Konten',
'create' => [
'title' => 'Marke erstellen',
'description' => 'Gib deiner Marke einen Namen, um Social-Media-Konten zu gruppieren',
'name' => 'Markenname',
'name_placeholder' => 'z. B. Acme Corp, Privat',
'submit' => 'Marke erstellen',
'submitting' => 'Wird erstellt...',
],
'edit' => [
'title' => 'Marke bearbeiten',
'description' => 'Aktualisiere den Namen dieser Marke',
'name' => 'Markenname',
'name_placeholder' => 'z. B. Acme Corp, Privat',
'submit' => 'Änderungen speichern',
'submitting' => 'Wird gespeichert...',
],
'delete' => [
'title' => 'Marke löschen',
'description' => 'Möchtest du diese Marke wirklich löschen? Die Zuordnung der Social-Media-Konten wird aufgehoben, sie werden aber nicht gelöscht.',
'confirm' => 'Löschen',
'cancel' => 'Abbrechen',
],
'flash' => [
'created' => 'Marke erfolgreich erstellt!',
'updated' => 'Marke erfolgreich aktualisiert!',
'deleted' => 'Marke erfolgreich gelöscht!',
],
];

14
lang/de/calendar.php Normal file
View file

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
return [
'title' => 'Kalender',
'today' => 'Heute',
'day' => 'Tag',
'week' => 'Woche',
'month' => 'Monat',
'new_post' => 'Neuer Beitrag',
'no_content' => 'Kein Inhalt',
'more' => '+:count weitere',
];

20
lang/de/comments.php Normal file
View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
return [
'placeholder' => 'Schreibe einen Kommentar...',
'reply_placeholder' => 'Schreibe eine Antwort...',
'reply' => 'Antworten',
'edit' => 'Bearbeiten',
'delete' => 'Löschen',
'edited' => 'bearbeitet',
'save' => 'Speichern',
'cancel' => 'Abbrechen',
'send' => 'Senden',
'replying_to' => 'Antwort an :name',
'empty' => 'Noch keine Kommentare. Starte die Unterhaltung.',
'load_more' => 'Ältere Kommentare laden',
'today' => 'Heute',
'yesterday' => 'Gestern',
];

67
lang/de/common.php Normal file
View file

@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
return [
'back' => 'Zurück',
'beta' => 'Beta',
'confirm_modal' => [
'cannot_be_undone' => 'Dies kann nicht rückgängig gemacht werden.',
'type' => 'Gib',
'to_confirm' => 'zur Bestätigung ein.',
'copy_to_clipboard' => 'In die Zwischenablage kopieren',
'delete_keyword' => 'löschen',
],
'photo_upload' => [
'upload' => 'Hochladen',
'uploading' => 'Wird hochgeladen...',
'remove' => 'Foto entfernen',
'hint' => 'Empfohlen: quadratisches Bild, max. 2 MB.',
'crop_title' => 'Bild zuschneiden',
'crop_description' => 'Wählen Sie den Bereich aus, den Sie behalten möchten.',
'crop_hint' => 'Zum Verschieben ziehen oder an einer Ecke die Größe ändern.',
'crop_save' => 'Speichern',
'crop_cancel' => 'Abbrechen',
'crop_error' => 'Dieses Bild konnte nicht geladen werden. Versuchen Sie eine andere Datei.',
],
'timezone' => [
'select' => 'Zeitzone auswählen',
'search' => 'Zeitzone suchen...',
'empty' => 'Keine Zeitzone gefunden',
],
'date_picker' => [
'select' => 'Datum auswählen',
],
'date_range_picker' => [
'placeholder' => 'Zeitraum wählen',
'today' => 'Heute',
'yesterday' => 'Gestern',
'last_7_days' => 'Letzte 7 Tage',
'last_30_days' => 'Letzte 30 Tage',
'last_3_months' => 'Letzte 3 Monate',
'last_6_months' => 'Letzte 6 Monate',
'last_12_months' => 'Letzte 12 Monate',
'this_month' => 'Dieser Monat',
'last_month' => 'Letzter Monat',
'year_to_date' => 'Seit Jahresbeginn',
'last_year' => 'Letztes Jahr',
],
'cancel' => 'Abbrechen',
'clear' => 'Zurücksetzen',
'close' => 'Schließen',
'loading_more' => 'Weitere werden geladen...',
'actions' => [
'copy' => 'Kopieren',
'copied' => 'Kopiert',
'copy_failed' => 'Kopieren in die Zwischenablage fehlgeschlagen',
],
];

56
lang/de/labels.php Normal file
View file

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
return [
'title' => 'Labels',
'description' => 'Erstelle Labels, um deine Beiträge zu organisieren und zu kategorisieren',
'search' => 'Labels suchen...',
'new_label' => 'Neues Label',
'no_labels_yet' => 'Noch keine Labels',
'no_search_results' => 'Keine Labels passen zu deiner Suche',
'try_different_search' => 'Versuche ein anderes Stichwort oder setze die Suche zurück.',
'create_first_label' => 'Erstelle dein erstes Label',
'table' => [
'name' => 'Name',
'created_at' => 'Erstellt',
],
'actions' => [
'edit' => 'Label bearbeiten',
'delete' => 'Label löschen',
],
'create' => [
'title' => 'Label erstellen',
'description' => 'Gib deinem Label einen Namen und wähle eine Farbe',
'name' => 'Name',
'name_placeholder' => 'Label-Namen eingeben...',
'color' => 'Farbe',
'submit' => 'Label erstellen',
'submitting' => 'Wird erstellt...',
],
'edit' => [
'title' => 'Label bearbeiten',
'description' => 'Aktualisiere Name und Farbe für dieses Label',
'name' => 'Name',
'name_placeholder' => 'Label-Namen eingeben...',
'color' => 'Farbe',
'submit' => 'Änderungen speichern',
'submitting' => 'Wird gespeichert...',
],
'delete' => [
'title' => 'Label löschen',
'description' => 'Möchtest du dieses Label wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.',
'confirm' => 'Löschen',
'cancel' => 'Abbrechen',
],
'flash' => [
'created' => 'Label erfolgreich erstellt!',
'updated' => 'Label erfolgreich aktualisiert!',
'deleted' => 'Label erfolgreich gelöscht!',
],
];

24
lang/de/mail.php Normal file
View file

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
return [
'mentioned' => [
'subject' => ':name hat dich auf TryPost erwähnt',
'title' => ':name hat dich erwähnt',
'intro' => ':name hat dich in einem Beitragskommentar erwähnt.',
'cta' => 'Kommentar ansehen',
],
'workspace_connections_disconnected' => [
'subject' => '{1} :count Konto muss in :workspace erneut verbunden werden|[2,*] :count Konten müssen in :workspace erneut verbunden werden',
'title' => 'Konten müssen erneut verbunden werden',
'intro' => 'Die folgenden Social-Media-Konten in deinem Workspace <strong>:workspace</strong> wurden getrennt und müssen erneut verbunden werden:',
'reasons_title' => 'Das kann folgende Gründe haben:',
'reason_expired' => 'Zugriffstokens sind abgelaufen',
'reason_revoked' => 'Du hast den Zugriff von TryPost auf der Plattform widerrufen',
'reason_changed' => 'Die Plattform hat ihre Authentifizierungsanforderungen geändert',
'reconnect_cta' => 'Bitte verbinde diese Konten erneut, um weiterhin Beiträge zu planen und zu veröffentlichen.',
'button' => 'Konten erneut verbinden',
],
];

18
lang/de/notifications.php Normal file
View file

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
return [
'post_ready' => [
'title' => 'Dein Beitrag ist fertig',
'body' => 'Die KI ist gerade fertig geworden. Tippe, um ihn zu prüfen und zu veröffentlichen.',
],
'account_disconnected' => [
'title' => ':platform-Konto getrennt',
'body' => ':account muss erneut verbunden werden',
],
'account_token_expired' => [
'title' => ':platform-Konto muss erneut verbunden werden',
'body' => 'Sitzung von :account abgelaufen – bitte verbinde es erneut, um weiter zu posten',
],
];

41
lang/de/onboarding.php Normal file
View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
return [
'title' => 'Willkommen bei TryPost',
'description' => 'Sag uns, was dich oder dein Unternehmen am besten beschreibt, damit wir dein Erlebnis anpassen können.',
'continue' => 'Weiter',
'personas' => [
'creator' => 'Content Creator',
'freelancer' => 'Freelancer',
'developer' => 'Entwickler',
'startup' => 'Startup',
'agency' => 'Agentur',
'small_business' => 'Kleinunternehmen',
'marketer' => 'Marketer',
'online_store' => 'Onlineshop',
'other' => 'Sonstiges',
],
'goals_title' => 'Was ist dein Ziel mit TryPost?',
'goals_description' => 'Wähle alles aus, was passt, und wir richten TryPost für dich ein.',
'goals' => [
'save_time' => 'Zeit sparen, indem ich überall gleichzeitig poste',
'ai_content' => 'Beiträge schneller mit KI erstellen',
'plan_calendar' => 'Meine Beiträge in einem Kalender planen',
'stay_on_brand' => 'Jeden Beitrag markenkonform halten',
'grow_audience' => 'Meine Reichweite und mein Engagement steigern',
'drive_sales' => 'Mehr Traffic und Verkäufe erzielen',
'manage_clients' => 'Mehrere Marken oder Kunden verwalten',
'team_collaboration' => 'Mit meinem Team arbeiten',
'automate_api' => 'Das Posten per API, MCP oder Code automatisieren',
'track_performance' => 'Sehen, wie meine Beiträge performen',
'just_exploring' => 'Ich schaue mich vorerst nur um',
'other' => 'Etwas anderes',
],
'connect' => [
'title' => 'Verbinde dein erstes Netzwerk',
'description' => 'Verknüpfe mindestens ein Social-Media-Konto, um mit der Planung zu beginnen. Du kannst jederzeit weitere hinzufügen.',
'must_connect' => 'Verbinde mindestens ein Netzwerk, um fortzufahren.',
],
];

21
lang/de/pagination.php Normal file
View file

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Zurück',
'next' => 'Weiter &raquo;',
];

24
lang/de/passwords.php Normal file
View file

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| outcome such as failure due to an invalid password / reset token.
|
*/
'reset' => 'Dein Passwort wurde zurückgesetzt.',
'sent' => 'Wir haben dir den Link zum Zurücksetzen deines Passworts per E-Mail gesendet.',
'throttled' => 'Bitte warte, bevor du es erneut versuchst.',
'token' => 'Dieser Token zum Zurücksetzen des Passworts ist ungültig.',
'user' => 'Wir können keinen Benutzer mit dieser E-Mail-Adresse finden.',
];

673
lang/de/posts.php Normal file
View file

@ -0,0 +1,673 @@
<?php
declare(strict_types=1);
return [
'title' => 'Beiträge',
'search' => 'Beiträge suchen...',
'all_posts' => 'Alle Beiträge',
'new_post' => 'Neuer Beitrag',
'no_posts' => 'Keine Beiträge gefunden',
'no_search_results' => 'Keine Beiträge passen zu deiner Suche',
'try_different_search' => 'Versuche ein anderes Stichwort oder setze die Suche zurück.',
'start_creating' => 'Beginne, indem du deinen ersten Beitrag erstellst.',
'filter_by_label' => 'Nach Label filtern',
'label_search_placeholder' => 'Labels suchen...',
'no_labels' => 'Keine Labels gefunden.',
'clear_label_filter' => 'Label-Filter zurücksetzen',
'table' => [
'post' => 'Beitrag',
'status' => 'Status',
'content' => 'Inhalt',
'platforms' => 'Plattformen',
'labels' => 'Labels',
'scheduled_at' => 'Datum',
'actions' => '',
],
'manage_posts' => 'Verwalte all deine Beiträge',
'delete_confirm' => 'Möchtest du diesen Beitrag wirklich löschen?',
'by' => 'von',
'actions' => [
'view' => 'Beitrag ansehen',
'delete' => 'Löschen',
'duplicate' => 'Duplizieren',
'copy_id' => 'ID kopieren',
'copied' => 'ID in die Zwischenablage kopiert',
],
'form' => [
'post_type' => 'Beitragstyp',
'board' => 'Pinnwand',
'select_board' => 'Pinnwand auswählen',
'search_board' => 'Pinnwand suchen...',
'no_board_found' => 'Keine Pinnwand gefunden',
'media' => 'Medien',
'min' => 'Min.',
'uploading' => 'Wird hochgeladen...',
'drop_to_upload' => 'Zum Hochladen ablegen',
'drag_and_drop' => 'Ziehen & ablegen oder zum Hochladen klicken',
'photos_and_videos' => 'Fotos und Videos',
'photos_only' => 'Nur Fotos',
'videos_only' => 'Nur Videos',
'drag_to_reorder' => 'Zum Neuordnen ziehen',
'caption' => 'Bildunterschrift',
'write_caption' => 'Schreibe deine Bildunterschrift...',
'content_exceeds_platform' => ':platform: um :over Zeichen zu lang (max. :limit).',
'tiktok' => [
'settings' => 'TikTok-Einstellungen',
'variant_label' => 'Beitragstyp',
'variant' => [
'video' => 'Video',
'photo' => 'Foto-Karussell',
],
'posting_to' => 'Veröffentlichen auf',
'privacy_level' => 'Wer kann dieses Video sehen?',
'privacy_placeholder' => 'Wähle, wer diesen Beitrag sehen kann',
'privacy' => [
'public' => 'Öffentlich für alle',
'friends' => 'Freunde, denen du gegenseitig folgst',
'followers' => 'Follower',
'private' => 'Nur ich',
'private_disabled_branded' => 'Die Sichtbarkeit von Branded Content kann nicht auf privat gesetzt werden.',
],
'privacy_hint' => 'Die verfügbaren Optionen hängen von deinen TikTok-Kontoeinstellungen ab.',
'auto_add_music' => 'Musik automatisch hinzufügen',
'auto_add_music_hint' => 'Diese Funktion ist nur für Fotos verfügbar. Sie fügt eine Standardmusik hinzu, die du später ändern kannst.',
'yes' => 'Ja',
'no' => 'Nein',
'allow_users' => 'Nutzern erlauben:',
'comments' => 'Kommentieren',
'duet' => 'Duett',
'stitch' => 'Stitch',
'is_aigc' => 'Mit KI erstelltes Video',
'disclose' => 'Videoinhalt offenlegen',
'disclose_hint' => 'Aktivieren, um offenzulegen, dass dieses Video Waren oder Dienstleistungen gegen einen Gegenwert bewirbt. Dein Video kann dich selbst, einen Dritten oder beide bewerben.',
'promotional_organic_title' => 'Dein Foto/Video wird als „Werbeinhalt" gekennzeichnet.',
'promotional_paid_title' => 'Dein Foto/Video wird als „Bezahlte Partnerschaft" gekennzeichnet.',
'promotional_description' => 'Dies kann nach der Veröffentlichung deines Videos nicht mehr geändert werden.',
'compliance_incomplete' => 'Du musst angeben, ob dein Inhalt dich selbst, einen Dritten oder beide bewirbt.',
'privacy_required' => 'Bei der Veröffentlichung ist die TikTok-Datenschutzstufe erforderlich.',
'branded_cleared_private' => 'Die Privatsphäre wurde zurückgesetzt, da Branded Content nicht privat sein kann.',
'interaction_disabled_by_creator' => 'In deinen TikTok-Kontoeinstellungen deaktiviert',
'max_duration_exceeded' => 'Das Video ist :duration s lang, aber dieses Konto kann nur Videos mit bis zu :max s veröffentlichen.',
'processing_hint' => 'Nach der Veröffentlichung kann es einige Minuten dauern, bis der Inhalt verarbeitet ist und in deinem TikTok-Profil erscheint.',
'brand_organic' => 'Deine Marke',
'brand_organic_hint' => 'Du bewirbst dich selbst oder deine eigene Marke. Dieses Video wird als Brand Organic klassifiziert.',
'brand_content' => 'Branded Content',
'brand_content_hint' => 'Du bewirbst eine andere Marke oder einen Dritten. Dieses Video wird als Branded Content klassifiziert.',
'compliance' => [
'agree' => 'Mit dem Veröffentlichen akzeptierst du TikToks',
'music_usage' => 'Bestätigung zur Musiknutzung',
'and' => 'und',
'branded_policy' => 'Richtlinie für Branded Content',
],
],
'instagram' => [
'settings' => 'Instagram-Einstellungen',
'posting_to' => 'Veröffentlichen auf',
'variant_label' => 'Beitragstyp',
'variant' => [
'feed' => 'Feed-Beitrag',
'reel' => 'Reel',
'story' => 'Story',
],
'aspect_label' => 'Seitenverhältnis',
'aspect' => [
'square' => 'Quadratisch (1:1)',
'portrait' => 'Hochformat (4:5)',
'landscape' => 'Querformat (16:9)',
'original' => 'Original',
],
],
'facebook' => [
'settings' => 'Facebook-Einstellungen',
'posting_to' => 'Veröffentlichen auf',
'variant_label' => 'Beitragstyp',
'variant' => [
'post' => 'Beitrag',
'reel' => 'Reel',
'story' => 'Story',
],
'aspect_label' => 'Seitenverhältnis',
'aspect' => [
'square' => 'Quadratisch (1:1)',
'portrait' => 'Hochformat (4:5)',
'landscape' => 'Querformat (16:9)',
'original' => 'Original',
],
],
'linkedin' => [
'settings' => 'LinkedIn-Einstellungen',
'settings_page' => 'LinkedIn-Seiteneinstellungen',
'posting_to' => 'Veröffentlichen auf',
'document_title' => 'Dokumenttitel',
'document_title_placeholder' => 'Wird bei deinem PDF-Dokument-Beitrag angezeigt',
],
'pinterest' => [
'settings' => 'Pinterest-Einstellungen',
'posting_to' => 'Veröffentlichen auf',
'variant_label' => 'Pin-Typ',
'variant' => [
'pin' => 'Pin',
'video_pin' => 'Video-Pin',
'carousel' => 'Karussell',
],
'board' => 'Pinnwand',
'select_board' => 'Pinnwand auswählen',
'no_boards' => 'Keine Pinterest-Pinnwände gefunden. Erstelle zuerst eine in deinem Pinterest-Konto.',
'search_board' => 'Pinnwände suchen...',
'no_board_found' => 'Keine Pinnwand passt zu deiner Suche.',
'board_required' => 'Wähle eine Pinterest-Pinnwand, um diesen Beitrag zu veröffentlichen.',
],
'discord' => [
'settings' => 'Discord-Einstellungen',
'posting_to' => 'Veröffentlichen auf',
'channel' => 'Kanal',
'select_channel' => 'Kanal auswählen',
'loading_channels' => 'Kanäle werden geladen…',
'search_channel' => 'Kanäle suchen…',
'no_channels' => 'Keine Kanäle gefunden.',
'channel_required' => 'Wähle einen Discord-Kanal, um diesen Beitrag zu veröffentlichen.',
'mentions' => 'Erwähnungen',
'search_mention' => 'Eine Rolle oder ein Mitglied erwähnen…',
'embeds' => 'Embeds',
'embed' => 'Embed',
'add_embed' => 'Embed hinzufügen',
'embed_title' => 'Embed-Titel',
'embed_description' => 'Embed-Beschreibung',
'embed_url' => 'Embed-URL',
'embed_image' => 'Bild-URL',
'embed_color' => 'Farbe',
],
'warnings' => [
'no_variant' => 'Wähle einen Beitragstyp, um fortzufahren.',
'requires_media' => 'Dieser Beitragstyp erfordert mindestens ein Bild oder Video.',
'max_files_exceeded' => 'Dieser Beitragstyp akzeptiert bis zu :max Mediendateien (du hast :current).',
'min_files_required' => 'Dieser Beitragstyp erfordert mindestens :min Mediendateien (du hast :current).',
'no_video_allowed' => 'Dieser Beitragstyp akzeptiert keine Videos.',
'no_image_allowed' => 'Dieser Beitragstyp akzeptiert nur Videos.',
'no_document_allowed' => 'Dieser Beitragstyp akzeptiert keine PDF-Dokumente.',
'no_mixed_media' => 'Bilder und ein Video können nicht im selben Beitrag kombiniert werden.',
'document_not_alone' => 'Ein PDF muss einzeln veröffentlicht werden, ohne andere Bilder oder Videos.',
'gif_not_allowed' => 'Diese Plattform akzeptiert keine GIFs. Entferne das GIF oder wähle ein anderes Netzwerk.',
'image_too_large' => 'Das Bild überschreitet das Limit von :max für diesen Beitragstyp (deins hat :current).',
'video_too_large' => 'Das Video überschreitet das Limit von :max für diesen Beitragstyp (deins hat :current).',
'document_too_large' => 'Das PDF überschreitet das Limit von :max für diesen Beitragstyp (deins hat :current).',
'video_too_long' => 'Das Video ist :current lang, aber dieser Beitragstyp erlaubt bis zu :max.',
'aspect_ratio_too_narrow' => 'Das Seitenverhältnis :current ist zu hoch für diesen Beitragstyp (min. :min).',
'aspect_ratio_too_wide' => 'Das Seitenverhältnis :current ist zu breit für diesen Beitragstyp (max. :max).',
],
],
'status' => [
'pending' => 'Ausstehend',
'draft' => 'Entwurf',
'scheduled' => 'Geplant',
'publishing' => 'Wird veröffentlicht',
'retrying' => 'Erneuter Versuch',
'published' => 'Veröffentlicht',
'partially_published' => 'Teilweise veröffentlicht',
'failed' => 'Fehlgeschlagen',
],
'descriptions' => [
'draft' => 'Beiträge, die auf Planung warten',
'scheduled' => 'Zur Veröffentlichung geplante Beiträge',
'published' => 'Bereits veröffentlichte Beiträge',
],
'ai' => [
'generate' => [
'button_tooltip' => 'Mit KI generieren',
'title' => 'Beitrag mit KI generieren',
'description' => 'Beschreibe, worum es in dem Beitrag gehen soll. Die KI verwendet deinen Markenkontext, um ihn zu schreiben.',
'prompt_label' => 'Worum geht es in diesem Beitrag?',
'prompt_placeholder' => 'z. B. Unser neues Bildgenerierungs-Feature für Karussells ankündigen',
'preview_label' => 'Vorschau',
'start' => 'Generieren',
'apply' => 'Diesen Inhalt verwenden',
'retry' => 'Erneut versuchen',
'cancel' => 'Abbrechen',
],
'review' => [
'button_tooltip' => 'Mit KI prüfen',
'title' => 'Beitrag mit KI prüfen',
'description' => 'Die KI prüft Grammatik, Rechtschreibung und Verständlichkeit. Übernimm die Vorschläge, denen du zustimmst.',
'loading' => 'Dein Text wird geprüft...',
'no_issues' => 'Keine Probleme gefunden. Sieht gut aus.',
'original' => 'Original',
'suggestion' => 'Vorschlag',
'apply' => 'Übernehmen',
'apply_all' => 'Alle übernehmen',
'applied' => 'Übernommen',
'cancel' => 'Abbrechen',
],
'image_regenerate' => [
'button' => 'Anpassen',
'title' => 'KI-Bild anpassen',
'description' => 'Beschreibe die Korrektur. Das neue Bild ersetzt das aktuelle und behält seine Position im Karussell.',
'instruction_label' => 'Anweisung',
'instruction_placeholder' => 'z. B. Korrigiere den Tippfehler in der Überschrift und mache den Hintergrund heller.',
'processing' => 'Bild wird neu generiert... das kann einige Sekunden dauern.',
'submit' => 'Bild neu generieren',
'cancel' => 'Abbrechen',
'success' => 'Bild aktualisiert. Die neue Version hat die vorherige in deinem Beitrag ersetzt.',
'fallback_title' => 'Diesen Bildtext verbessern',
'errors' => [
'required' => 'Eine Anweisung ist erforderlich.',
'start_failed' => 'Neugenerierung konnte nicht gestartet werden.',
'unavailable' => 'Dieses Bild kann derzeit nicht neu generiert werden.',
'timeout' => 'Die Neugenerierung dauert länger als erwartet. Versuche es gleich noch einmal.',
'media_not_found' => 'Medienelement nicht gefunden.',
'not_ai_media' => 'Nur KI-generierte Medien können neu generiert werden.',
],
],
'templates' => [
'image_card' => [
'name' => 'Bildbeitrag',
'description' => 'KI-Bild mit Überschrift und Bildunterschrift.',
],
'carousel' => [
'name' => 'Karussell',
'description' => 'Karussell mit mehreren Slides und einer Bildunterschrift.',
],
'tweet_card' => [
'name' => 'Tweet-Karte',
'description' => 'Dein Beitrag im Stil eines X/Twitter-Beitrags.',
],
'tweet_card_image' => [
'name' => 'Tweet-Karte mit Foto',
'description' => 'Dein Beitrag als X/Twitter-Karte über einem unscharfen Foto.',
],
],
],
'show' => [
'title' => 'Beitragsdetails',
'edit' => 'Bearbeiten',
'back' => 'Zurück',
'no_content' => 'Keine Bildunterschrift',
'platforms' => 'Plattformen',
'no_platforms' => 'Keine Plattformen ausgewählt.',
'view_on_platform' => 'Auf der Plattform ansehen',
'published_on' => 'Veröffentlicht am :date',
'scheduled_for' => 'Geplant für :date',
'draft' => 'Entwurf',
'status_pending' => 'Ausstehend',
'metrics' => 'Kennzahlen',
'metrics_loading' => 'Kennzahlen werden geladen…',
'metrics_unavailable' => 'Kennzahlen für diese Plattform sind noch nicht verfügbar.',
'metrics_empty' => 'Keine Kennzahlen zurückgegeben.',
],
'edit' => [
'title' => 'Beitrag bearbeiten',
'view_title' => 'Beitrag ansehen',
'labels' => 'Labels',
'no_labels' => 'Noch keine Labels erstellt',
'schedule' => 'Planen',
'pick_time' => 'Uhrzeit wählen',
'pick_time_past' => 'Wähle ein zukünftiges Datum und eine zukünftige Uhrzeit.',
'post_now' => 'Jetzt veröffentlichen',
'time' => 'Uhrzeit',
'cancel' => 'Abbrechen',
'delete' => 'Löschen',
'schedule_for' => 'Planen für',
'schedule_date' => 'Datum planen',
'unschedule' => 'Planung aufheben',
'saving' => 'Wird gespeichert...',
'saved' => 'Gespeichert',
'draft' => 'Entwurf',
'media' => 'Medien',
'add_media' => 'Medien hinzufügen',
'caption' => 'Bildunterschrift',
'caption_placeholder' => 'Schreibe deine Bildunterschrift...',
'compose_title' => 'Beitrag erstellen',
'compose_subtitle' => 'Verfasse deine Nachricht und füge Medien hinzu',
'preview_empty' => [
'title' => 'Keine Plattform ausgewählt',
'description' => 'Wähle eine Plattform zum Veröffentlichen, um die Vorschau zu sehen.',
],
'drop_zone_title' => 'Medien hinzufügen',
'drop_zone_subtitle' => 'Dateien ziehen & ablegen oder zum Durchsuchen klicken',
'add' => 'Hinzufügen',
'publish_to' => 'Veröffentlichen auf',
'organize' => 'Organisieren',
'signatures' => 'Signaturen',
'view_on_platform' => 'Auf der Plattform ansehen',
'platform_status' => 'Plattform-Status',
'compliance_incomplete' => 'Einige Plattform-Einstellungen sind unvollständig oder nicht mit den angehängten Medien kompatibel.',
'compliance' => [
'requires_content_or_media' => 'Füge Text oder Medien hinzu, um zu veröffentlichen.',
'requires_media' => 'Füge ein Bild oder Video hinzu, um hier zu veröffentlichen.',
'too_many_files' => 'Für dieses Format sind nur :max Datei(en) erlaubt.',
'too_few_files' => 'Füge mindestens :min Dateien für dieses Format hinzu.',
'no_videos' => 'Für dieses Format sind nur Bilder erlaubt.',
'no_images' => 'Für dieses Format sind nur Videos erlaubt.',
'no_mixed_media' => 'Bilder und Videos können nicht im selben Beitrag kombiniert werden.',
'no_gifs' => 'GIFs werden hier nicht unterstützt.',
'no_documents' => 'PDF-Dokumente werden von diesem Format nicht unterstützt.',
'document_not_alone' => 'Ein PDF muss einzeln veröffentlicht werden, ohne andere Bilder oder Videos.',
'video_too_large' => 'Das Video überschreitet das Größenlimit für diese Plattform.',
'video_too_long' => 'Das Video muss für dieses Format kürzer als :seconds Sekunden sein.',
'image_too_large' => 'Das Bild überschreitet das Größenlimit für diese Plattform.',
'document_too_large' => 'Das PDF überschreitet das Größenlimit für diese Plattform.',
'aspect_ratio_invalid' => 'Das Seitenverhältnis wird von diesem Format nicht unterstützt.',
'no_content_type' => 'Wähle einen Inhaltstyp für diese Plattform.',
'requires_text' => 'Füge Text hinzu – dieses Format benötigt einen Titel.',
],
'publishing' => 'Wird veröffentlicht...',
'publishing_overlay_title' => 'Dein Beitrag wird veröffentlicht',
'publishing_overlay_subtitle' => 'Das kann einen Moment dauern. Du kannst diese Seite bedenkenlos verlassen.',
'scheduled_overlay_title' => 'Dieser Beitrag ist geplant',
'scheduled_overlay_subtitle' => 'Geplant für :date. Hebe die Planung zuerst auf, um Änderungen vorzunehmen.',
'unschedule_cta' => 'Zum Bearbeiten Planung aufheben',
'tabs' => [
'preview' => 'Vorschau',
'channels' => 'Kanäle',
'comments' => 'Kommentare',
'comments_empty' => 'Noch keine Kommentare.',
],
'media_picker' => [
'title' => 'Aus Galerie auswählen',
'search' => 'Medien suchen...',
'empty' => 'Noch keine Medien in deiner Galerie',
'cancel' => 'Abbrechen',
'add' => 'Hinzufügen',
'add_count' => ':count hinzufügen',
],
'emoji_picker' => [
'search' => 'Emoji suchen',
'empty' => 'Keine Emojis gefunden',
'recent' => 'Häufig verwendet',
'smileys' => 'Smileys & Emotionen',
'people' => 'Menschen & Körper',
'nature' => 'Tiere & Natur',
'food' => 'Essen & Trinken',
'activities' => 'Aktivitäten',
'travel' => 'Reisen & Orte',
'objects' => 'Objekte',
'symbols' => 'Symbole',
'flags' => 'Flaggen',
],
'status' => [
'pending' => 'Ausstehend',
'scheduled' => 'Geplant',
'published' => 'Veröffentlicht',
'publishing' => 'Wird veröffentlicht...',
'retrying' => 'Erneuter Versuch...',
'failed' => 'Fehlgeschlagen',
],
'delete_modal' => [
'title' => 'Beitrag löschen',
'description' => 'Möchtest du diesen Beitrag wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.',
'action' => 'Löschen',
'cancel' => 'Abbrechen',
],
'sync_enable' => [
'title' => 'Synchronisierung aktivieren?',
'description' => 'Alle Plattformen teilen denselben Inhalt. Alle individuellen Anpassungen an einzelnen Plattformen werden durch den aktuellen Inhalt ersetzt.',
'cancel' => 'Abbrechen',
'action' => 'Synchronisierung aktivieren',
],
'sync_disable' => [
'title' => 'Synchronisierung deaktivieren?',
'description' => 'Jede Plattform behält ihren aktuellen Inhalt, aber zukünftige Änderungen gelten nur für die Plattform, die du gerade bearbeitest.',
'customize_note' => 'Du kannst den Inhalt für jede Plattform einzeln anpassen.',
'cancel' => 'Abbrechen',
'action' => 'Synchronisierung deaktivieren',
],
'platforms_dialog' => [
'title' => 'Plattformen auswählen',
'description' => 'Wähle, auf welchen Plattformen dieser Beitrag veröffentlicht werden soll.',
],
'signatures_modal' => [
'search' => 'Signaturen suchen...',
'no_results' => 'Keine Signaturen gefunden.',
],
'validation' => [
'select_board' => 'Pinnwand auswählen',
'images_not_supported' => 'Bilder nicht unterstützt',
'videos_not_supported' => 'Videos nicht unterstützt',
'max_images' => 'Max. :count Bilder',
'requires_media' => 'Medien erforderlich',
'requires_content' => 'Textinhalt ist erforderlich',
'exceeded' => ':count überschritten',
'does_not_support_images' => ':platform unterstützt keine Bilder',
'supports_up_to_images' => ':platform unterstützt bis zu :count Bilder',
'does_not_support_videos' => ':platform unterstützt keine Videos',
],
],
'content_types' => [
'instagram_feed' => [
'label' => 'Feed-Beitrag',
'description' => 'Erscheint in deinem Feed und Profil',
],
'instagram_reel' => [
'label' => 'Reel',
'description' => 'Kurzes Video bis zu 90 Sekunden',
],
'instagram_story' => [
'label' => 'Story',
'description' => 'Verschwindet nach 24 Stunden',
],
'linkedin_post' => [
'label' => 'Beitrag',
'description' => 'Standardbeitrag – Einzelbild, mehrere Bilder, Video oder PDF',
],
'linkedin_page_post' => [
'label' => 'Beitrag',
'description' => 'Standardbeitrag – Einzelbild, mehrere Bilder, Video oder PDF',
],
'facebook_post' => [
'label' => 'Beitrag',
'description' => 'Standardbeitrag auf deiner Seite',
],
'facebook_reel' => [
'label' => 'Reel',
'description' => 'Kurzes Video bis zu 90 Sekunden',
],
'facebook_story' => [
'label' => 'Story',
'description' => 'Vertikale Videostory, bis zu 60 Sekunden',
],
'tiktok_video' => [
'label' => 'Video',
'description' => 'Kurzvideo-Inhalt',
],
'tiktok_photo' => [
'label' => 'Foto-Karussell',
'description' => 'Bis zu 35 Fotos als wischbares Karussell',
],
'youtube_short' => [
'label' => 'Short',
'description' => 'Vertikales Video bis zu 60 Sekunden',
],
'x_post' => [
'label' => 'Beitrag',
'description' => 'Tweet mit Text und Medien',
],
'threads_post' => [
'label' => 'Beitrag',
'description' => 'Textbeitrag mit optionalen Medien',
],
'pinterest_pin' => [
'label' => 'Pin',
'description' => 'Standard-Bild-Pin',
],
'pinterest_video_pin' => [
'label' => 'Video-Pin',
'description' => 'Video-Pin (4 Sek. – 15 Min.)',
],
'pinterest_carousel' => [
'label' => 'Karussell',
'description' => 'Karussell mit mehreren Bildern (2–5 Bilder)',
],
'bluesky_post' => [
'label' => 'Beitrag',
'description' => 'Textbeitrag mit optionalen Bildern',
],
'mastodon_post' => [
'label' => 'Beitrag',
'description' => 'Textbeitrag mit optionalen Medien',
],
'telegram_post' => [
'label' => 'Beitrag',
'description' => 'Textbeitrag mit optionalen Medien',
],
'discord_message' => [
'label' => 'Nachricht',
'description' => 'Nachricht an einen Discord-Kanal mit optionalen Medien & Embeds',
],
],
'platforms' => [
'linkedin' => 'LinkedIn',
'linkedin-page' => 'LinkedIn-Seite',
'x' => 'X',
'tiktok' => 'TikTok',
'youtube' => 'YouTube Shorts',
'facebook' => 'Facebook-Seite',
'instagram' => 'Instagram',
'threads' => 'Threads',
'pinterest' => 'Pinterest',
'bluesky' => 'Bluesky',
'mastodon' => 'Mastodon',
],
'flash' => [
'scheduled' => 'Beitrag erfolgreich geplant!',
'deleted' => 'Beitrag erfolgreich gelöscht!',
'duplicated' => 'Beitrag als Entwurf dupliziert.',
'cannot_edit_finalized' => 'Dieser Beitrag wurde bereits verarbeitet und kann nicht erneut veröffentlicht werden. Dupliziere ihn, um es noch einmal zu versuchen.',
'cannot_delete_published' => 'Veröffentlichte Beiträge können nicht gelöscht werden.',
'connect_first' => 'Verbinde mindestens ein soziales Netzwerk, bevor du einen Beitrag erstellst.',
],
'errors' => [
'account_disconnected' => 'Social-Media-Konto ist getrennt',
'account_inactive' => 'Social-Media-Konto ist deaktiviert',
'account_token_expired' => 'Sitzung des Social-Media-Kontos abgelaufen – bitte erneut verbinden',
],
'delete' => [
'title' => 'Beitrag löschen?',
'description' => 'Diese Aktion kann nicht rückgängig gemacht werden. Der Beitrag und alle zugehörigen Medien werden dauerhaft entfernt.',
'confirm' => 'Ja, löschen',
'cancel' => 'Abbrechen',
],
'create' => [
'title' => 'Neuen Beitrag erstellen',
'description' => 'Wähle, wie du beginnen möchtest.',
'scratch_title' => 'Von Grund auf beginnen',
'scratch_description' => 'Öffne einen leeren Beitrag und schreibe alles selbst.',
'ai_title' => 'Mit KI generieren',
'ai_description' => 'Beschreibe, was du möchtest, und die KI generiert den Inhalt für dich.',
'ai_configure_description' => 'Wähle ein Format und beschreibe den Beitrag, den du erstellen möchtest.',
'ai_pick_template_description' => 'Wähle einen Stil für deinen KI-generierten Beitrag.',
'template_title' => 'Vorlage verwenden',
'template_description' => 'Wähle aus unseren kuratierten Vorlagen und passe sie an.',
'coming_soon' => 'Demnächst verfügbar',
'preview' => [
'image_title' => 'Bildtitel',
'image_body' => 'Bildtext',
],
'steps' => [
'template_picker_title' => 'Wähle einen Stil',
'format_title' => 'Wähle ein Format',
'format_description' => 'Wähle die Art des Beitrags, den du erstellen möchtest.',
'account_title' => 'Wähle ein Konto',
'account_description' => 'Wähle das Social-Media-Konto zum Veröffentlichen.',
'media_title' => 'Medienoptionen',
'media_carousel' => 'Wie viele Slides?',
'media_optional' => 'Bilder einbeziehen?',
'media_optional_label' => 'Wie viele Bilder?',
'media_none' => 'Keine',
'media_count_label' => 'Anzahl der Bilder',
'prompt_title' => 'Beschreibe deinen Beitrag',
'prompt_label' => 'Worum geht es in diesem Beitrag?',
'prompt_placeholder' => 'z. B. Unser neues Karussell-Feature für Instagram ankündigen',
'preview_error' => 'Etwas ist schiefgelaufen. Bitte versuche es erneut.',
'loading_page_title' => 'Dein Beitrag wird generiert',
'loading_eta' => 'Geschätzte Zeit: etwa :minutes.',
'loading_eta_minute_one' => '1 Minute',
'loading_eta_minute_other' => ':count Minuten',
'loading_leave_title' => 'Du kannst weiterarbeiten.',
'loading_leave_body' => 'Wir benachrichtigen dich, wenn der Beitrag fertig ist.',
'loading_leave_cta' => 'Zum Kalender',
'loading_create_another_cta' => 'Weiteren Beitrag erstellen',
'loading_tip_credits' => 'Jedes KI-Bild verbraucht etwa 15 Credits.',
'loading_tip_edit' => 'Du kannst alles bearbeiten, sobald der Beitrag fertig ist.',
'loading_tip_draft' => 'Generierte Beiträge landen in deinen Entwürfen.',
'loading_tip_brand' => 'Passe deine Markeneinstellungen an, um zukünftige Beiträge zu beeinflussen.',
'loading_tip_carousel' => 'Karussells liefern pro hochgeladenem Bild ein Slide.',
'loading_tip_quality' => 'Die Bildqualität ist auf ein Gleichgewicht aus Geschwindigkeit und Kosten eingestellt.',
'create' => 'Beitrag erstellen',
'back' => 'Zurück',
'next' => 'Weiter',
'cancel' => 'Abbrechen',
'discard' => 'Verwerfen',
'retry' => 'Erneut versuchen',
'no_platforms' => 'Keine verbundenen Konten',
'connect_first' => 'Verbinde mindestens ein Social-Media-Konto, um die KI-Generierung zu nutzen.',
'no_account_for_template' => 'Verbinde ein kompatibles Konto, um diese Vorlage zu verwenden.',
'format' => [
'instagram_feed' => 'Instagram-Feed-Beitrag',
'instagram_carousel' => 'Instagram-Karussell',
'linkedin_post' => 'LinkedIn-Beitrag',
'linkedin_page_post' => 'LinkedIn-Seiten-Beitrag',
'x_post' => 'X-Beitrag',
'bluesky_post' => 'Bluesky-Beitrag',
'threads_post' => 'Threads-Beitrag',
'mastodon_post' => 'Mastodon-Beitrag',
'telegram_post' => 'Telegram-Beitrag',
'discord_message' => 'Discord-Nachricht',
'facebook_post' => 'Facebook-Beitrag',
'pinterest_pin' => 'Pinterest-Pin',
'instagram_story' => 'Instagram-Story',
'facebook_story' => 'Facebook-Story',
],
],
],
'templates' => [
'browser_title' => 'Wähle eine Vorlage',
'browser_description' => 'Beginne mit einer kuratierten Vorlage und passe sie an.',
'search_placeholder' => 'Vorlagen suchen…',
'no_search_results' => 'Keine Vorlagen passen zu deiner Suche',
'try_different_search' => 'Versuche ein anderes Stichwort oder setze die Suche zurück.',
'slides_count' => '{count} Slide|{count} Slides',
'all_platforms' => 'Alle Plattformen',
'platform_search_placeholder' => 'Plattform suchen…',
'no_platform_match' => 'Keine passende Plattform.',
'use_this' => 'Diese Vorlage verwenden',
'no_templates' => 'Keine Vorlagen verfügbar.',
'applying' => 'Vorlage wird angewendet…',
'category' => [
'product_launch' => 'Produkteinführung',
'promotion' => 'Aktion',
'educational' => 'Lehrreich',
'behind_the_scenes' => 'Hinter den Kulissen',
'testimonial' => 'Kundenstimme',
'industry_tip' => 'Branchentipp',
'event' => 'Event',
'engagement' => 'Engagement',
],
],
];

365
lang/de/settings.php Normal file
View file

@ -0,0 +1,365 @@
<?php
declare(strict_types=1);
return [
'title' => 'Einstellungen',
'description' => 'Verwalte dein Profil und deine Kontoeinstellungen',
'hub' => [
'title' => 'Einstellungen',
'description' => 'Wähle, was du verwalten möchtest.',
'profile' => [
'title' => 'Profil',
'description' => 'Aktualisiere deine persönlichen Daten, dein Passwort und deine Benachrichtigungseinstellungen.',
],
'workspace' => [
'title' => 'Workspace',
'description' => 'Konfiguriere deinen Workspace, deine Marke, deine Mitglieder und deine API-Keys.',
],
'account' => [
'title' => 'Konto',
'description' => 'Verwalte deine Kontoinformationen, deine Nutzung und deine Abrechnung.',
],
],
'nav' => [
'profile' => 'Profil',
'authentication' => 'Authentifizierung',
'workspace' => 'Workspace',
'members' => 'Mitglieder',
'notifications' => 'Benachrichtigungen',
'billing' => 'Abrechnung',
],
'notifications' => [
'title' => 'Benachrichtigungseinstellungen',
'heading' => 'E-Mail-Benachrichtigungen',
'description' => 'Wähle, welche E-Mail-Benachrichtigungen du erhalten möchtest',
'post_published' => 'Beitrag veröffentlicht',
'post_published_description' => 'Erhalte eine E-Mail, wenn dein Beitrag erfolgreich veröffentlicht wurde',
'post_failed' => 'Beitrag fehlgeschlagen',
'post_failed_description' => 'Erhalte eine E-Mail, wenn die Veröffentlichung deines Beitrags fehlschlägt',
'account_disconnected' => 'Konto getrennt',
'account_disconnected_description' => 'Erhalte eine E-Mail, wenn ein Social-Media-Konto getrennt wird',
'save' => 'Einstellungen speichern',
],
'profile' => [
'title' => 'Profileinstellungen',
'photo_heading' => 'Profilfoto',
'photo_description' => 'Lade ein Profilfoto hoch',
'heading' => 'Profilinformationen',
'description' => 'Aktualisiere deinen Namen und deine E-Mail-Adresse',
'avatar' => 'Avatar',
'name' => 'Name',
'name_placeholder' => 'Vollständiger Name',
'email' => 'E-Mail-Adresse',
'email_placeholder' => 'E-Mail-Adresse',
'email_unverified' => 'Deine E-Mail-Adresse ist nicht bestätigt.',
'resend_verification' => 'Klicke hier, um die Bestätigungs-E-Mail erneut zu senden.',
'verification_sent' => 'Ein neuer Bestätigungslink wurde an deine E-Mail-Adresse gesendet.',
'save' => 'Speichern',
],
'authentication' => [
'title' => 'Authentifizierung',
'page_title' => 'Authentifizierungseinstellungen',
'sessions' => [
'title' => 'Aktive Sitzungen',
'description' => 'Wenn dir etwas Verdächtiges auffällt, melde dich von anderen Geräten ab.',
'unknown_browser' => 'Unbekannter Browser',
'unknown_ip' => 'Unbekannte IP',
'on' => 'am',
'active_now' => 'Jetzt aktiv',
'log_out_others' => 'Andere Geräte abmelden',
'modal_title' => 'Andere Geräte abmelden',
'modal_description_password' => 'Gib dein aktuelles Passwort ein, um zu bestätigen, dass du andere Browser-Sitzungen abmelden möchtest.',
'modal_description_email' => 'Gib deine E-Mail-Adresse ein, um zu bestätigen, dass du andere Browser-Sitzungen abmelden möchtest.',
'password_placeholder' => 'Aktuelles Passwort',
'email_placeholder' => 'E-Mail deines Kontos',
'cancel' => 'Abbrechen',
'submit' => 'Andere Geräte abmelden',
'email_mismatch' => 'Die E-Mail-Adresse stimmt nicht mit deinem Konto überein.',
'flash_logged_out' => 'Du wurdest von anderen Geräten abgemeldet.',
],
'password' => [
'update_title' => 'Passwort aktualisieren',
'set_title' => 'Passwort festlegen',
'update_description' => 'Stelle sicher, dass dein Konto ein langes, zufälliges Passwort verwendet, um sicher zu bleiben.',
'set_description' => 'Füge ein Passwort hinzu, damit du dich ohne verbundenen Anbieter anmelden kannst.',
'current_password' => 'Aktuelles Passwort',
'new_password' => 'Neues Passwort',
'confirm_password' => 'Passwort bestätigen',
'save' => 'Passwort speichern',
'set' => 'Passwort festlegen',
],
'providers' => [
'title' => 'Verbundene Konten',
'description' => 'Melde dich schneller mit diesen verbundenen Anbietern an.',
'connected' => 'Verbunden',
'not_connected' => 'Nicht verbunden',
'connect' => 'Verbinden',
'disconnect' => 'Trennen',
'flash_disconnected' => ':provider erfolgreich getrennt.',
'flash_connected' => ':provider erfolgreich verbunden.',
'flash_already_linked' => 'Dieses :provider-Konto ist bereits mit einem anderen Benutzer verknüpft.',
'flash_cannot_disconnect' => 'Du kannst deine einzige Anmeldemethode nicht trennen. Lege zuerst ein Passwort fest oder verbinde einen anderen Anbieter.',
],
],
'delete_account' => [
'heading' => 'Konto löschen',
'description' => 'Lösche dein Konto und alle zugehörigen Ressourcen',
'warning' => 'Warnung',
'warning_message' => 'Bitte gehe mit Vorsicht vor, dies kann nicht rückgängig gemacht werden.',
'button' => 'Konto löschen',
'modal_title' => 'Möchtest du dein Konto wirklich löschen?',
'modal_description_password' => 'Sobald dein Konto gelöscht ist, werden auch alle zugehörigen Ressourcen und Daten dauerhaft gelöscht. Bitte gib dein Passwort ein, um zu bestätigen.',
'modal_description_email' => 'Sobald dein Konto gelöscht ist, werden auch alle zugehörigen Ressourcen und Daten dauerhaft gelöscht. Bitte gib deine E-Mail-Adresse :email ein, um zu bestätigen.',
'password' => 'Passwort',
'password_placeholder' => 'Passwort',
'email_placeholder' => 'E-Mail deines Kontos',
'email_mismatch' => 'Die E-Mail-Adresse stimmt nicht mit deinem Konto überein.',
'cancel' => 'Abbrechen',
'confirm' => 'Konto löschen',
],
'workspace' => [
'tabs' => [
'workspace' => 'Workspace',
'brand' => 'Marke',
'users' => 'Mitglieder',
'api_keys' => 'API-Keys',
],
'title' => 'Workspace-Einstellungen',
'logo_heading' => 'Workspace-Logo',
'logo_description' => 'Lade ein Logo für deinen Workspace hoch',
'heading' => 'Workspace-Name',
'description' => 'Aktualisiere den Namen deines Workspace',
'members_heading' => 'Mitglieder',
'members_description' => 'Verwalte die Mitglieder und Einladungen des Workspace',
'name' => 'Name',
'name_placeholder' => 'Mein Workspace',
'save' => 'Speichern',
],
'brand' => [
'title' => 'Marke',
'description' => 'Konfiguriere deine Markenidentität für KI-generierte Inhalte.',
'name' => 'Workspace-Name',
'name_placeholder' => 'Meine Marke',
'website' => 'Website',
'website_placeholder' => 'https://yourbrand.com',
'brand_description' => 'Beschreibung',
'brand_description_placeholder' => 'Erzähl uns von deiner Marke, was du machst und wer deine Zielgruppe ist...',
'voice' => 'Markenton',
'voice_description' => 'Wähle die Eigenschaften, die den Klang deiner Inhalte bestimmen.',
'voice_group' => [
'pov' => 'Perspektive',
'formality' => 'Förmlichkeit',
'energy' => 'Energie',
'humor' => 'Humor',
'attitude' => 'Haltung',
'warmth' => 'Wärme',
'confidence' => 'Selbstbewusstsein',
'style' => 'Stil',
],
'voice_trait' => [
'first_person' => 'Erste Person',
'second_person' => 'Zweite Person (du)',
'third_person' => 'Dritte Person',
'formal' => 'Förmlich',
'balanced' => 'Ausgewogen',
'casual' => 'Locker',
'calm' => 'Ruhig',
'moderate' => 'Moderat',
'enthusiastic' => 'Enthusiastisch',
'vibrant' => 'Lebhaft',
'serious' => 'Ernst',
'dry' => 'Trocken / subtil',
'witty' => 'Geistreich',
'playful' => 'Verspielt',
'respectful' => 'Respektvoll',
'even_handed' => 'Unparteiisch',
'bold' => 'Mutig',
'provocative' => 'Provokativ',
'neutral' => 'Neutral',
'friendly' => 'Freundlich',
'empathetic' => 'Einfühlsam',
'humble' => 'Bescheiden',
'confident' => 'Selbstbewusst',
'assertive' => 'Durchsetzungsstark',
'direct' => 'Direkt',
'concise' => 'Prägnant',
'transparent' => 'Transparent',
'no_hype' => 'Ohne Hype',
'practical' => 'Praktisch',
'data_driven' => 'Datenbasiert',
'storytelling' => 'Storytelling',
'inspirational' => 'Inspirierend',
'educational' => 'Lehrreich',
'technical' => 'Technisch',
'minimalist' => 'Wenige Emojis',
],
'brand_color' => 'Markenfarbe',
'background_color' => 'Hintergrundfarbe',
'text_color' => 'Textfarbe',
'font' => 'Schriftart',
'image_style' => 'Bildstil',
'image_style_description' => 'Visueller Stil, der beim Generieren von Slide- und Coverbildern für KI-Beiträge angewendet wird.',
'image_style_cinematic' => 'Filmisch',
'image_style_illustration' => 'Illustration',
'image_style_isometric_3d' => 'Isometrisch',
'image_style_cartoon' => 'Cartoon',
'image_style_typographic' => 'Typografisch',
'image_style_infographic' => 'Infografik',
'image_style_minimalist' => 'Minimalistisch',
'image_style_mockup' => 'Mockup',
'content_language' => 'Inhaltssprache',
'content_language_description' => 'Sprache für KI-generierte Bildunterschriften, Hashtags und jeglichen Text in generierten Bildern oder Videos.',
'font_placeholder' => 'Schriftart auswählen…',
'font_search' => 'Schriftart suchen…',
'font_empty' => 'Keine Schriftarten gefunden.',
'language_placeholder' => 'Sprache auswählen…',
'language_search' => 'Sprache suchen…',
'language_empty' => 'Keine Sprache gefunden.',
],
'members' => [
'title' => 'Mitglieder',
'heading' => 'Teammitglieder',
'description' => 'Verwalte Mitglieder und Einladungen für diesen Workspace',
'cancel' => 'Abbrechen',
'remove' => 'Entfernen',
'make_role' => 'Zu :role machen',
'invite' => [
'title' => 'Mitglied einladen',
'description' => 'Sende eine E-Mail-Einladung, um Mitarbeiter hinzuzufügen',
'email' => 'E-Mail',
'email_placeholder' => 'mitarbeiter@email.com',
'role' => 'Rolle',
'role_placeholder' => 'Rolle auswählen',
'submit' => 'Einladung senden',
],
'pending' => [
'title' => 'Ausstehende Einladungen',
'description' => 'Einladungen, die auf Annahme warten',
'empty' => 'Keine ausstehenden Einladungen',
],
'list' => [
'title' => 'Mitglieder',
'description' => 'Personen mit Zugriff auf diesen Workspace',
'empty' => 'Keine Mitglieder außer dem Inhaber',
],
'remove_modal' => [
'title' => 'Mitglied entfernen',
'description' => 'Möchtest du dieses Mitglied wirklich aus dem Workspace entfernen? Es verliert den Zugriff auf alle Workspace-Ressourcen.',
'action' => 'Mitglied entfernen',
],
'cancel_invite_modal' => [
'title' => 'Einladung zurückziehen',
'description' => 'Möchtest du diese Einladung wirklich zurückziehen?',
'action' => 'Einladung zurückziehen',
],
'roles' => [
'owner' => 'Inhaber',
'admin' => 'Admin',
'member' => 'Mitglied',
'viewer' => 'Betrachter',
],
'flash' => [
'invite_sent' => 'Einladung erfolgreich gesendet!',
'invite_deleted' => 'Einladung gelöscht.',
'member_removed' => 'Mitglied erfolgreich entfernt.',
'role_updated' => 'Rolle des Mitglieds aktualisiert.',
'wrong_email' => 'Diese Einladung gilt für eine andere E-Mail-Adresse.',
'already_member' => 'Du bist bereits Mitglied dieses Workspace.',
'invite_accepted' => 'Willkommen! Du bist jetzt Mitglied des Workspace.',
'invite_declined' => 'Einladung abgelehnt.',
],
],
'account' => [
'tabs' => [
'account' => 'Konto',
'usage' => 'Nutzung',
'billing' => 'Abrechnung',
],
'title' => 'Kontoeinstellungen',
'description' => 'Verwalte deinen Kontonamen und deine Rechnungs-E-Mail',
'name' => 'Kontoname',
'name_placeholder' => 'Meine Firma',
'billing_email' => 'Rechnungs-E-Mail',
'billing_email_placeholder' => 'rechnung@firma.com',
'billing_email_hint' => 'Diese E-Mail-Adresse wird für Rechnungen und Abrechnungskommunikation von Stripe verwendet.',
'submit' => 'Speichern',
],
'flash' => [
'account_updated' => 'Konto erfolgreich aktualisiert!',
'profile_updated' => 'Profil erfolgreich aktualisiert!',
'password_updated' => 'Passwort erfolgreich aktualisiert!',
'workspace_updated' => 'Einstellungen erfolgreich aktualisiert!',
'photo_updated' => 'Foto erfolgreich aktualisiert!',
'photo_deleted' => 'Foto erfolgreich entfernt!',
'logo_updated' => 'Logo erfolgreich hochgeladen!',
'logo_deleted' => 'Logo erfolgreich entfernt!',
'notifications_updated' => 'Benachrichtigungseinstellungen aktualisiert!',
],
'api_keys' => [
'title' => 'API-Keys',
'page_title' => 'API-Keys',
'heading' => 'API-Keys',
'description' => 'Verwalte API-Keys für den programmatischen Zugriff auf deinen Workspace.',
'create' => 'API-Key erstellen',
'copy' => 'Kopieren',
'new_token_message' => 'Dein neuer API-Key wurde erstellt. Kopiere ihn jetzt – du kannst ihn danach nicht mehr sehen.',
'table' => [
'name' => 'Name',
'key' => 'Key',
'status' => 'Status',
'expires' => 'Läuft ab',
'last_used' => 'Zuletzt verwendet',
'never' => 'Nie',
],
'actions' => [
'copy_id' => 'API-Key-ID kopieren',
'copy_id_success' => 'API-Key-ID in die Zwischenablage kopiert',
'delete' => 'Löschen',
],
'empty' => [
'title' => 'Noch keine API-Keys',
'description' => 'Erstelle einen API-Key, um programmatisch auf deinen Workspace zuzugreifen.',
],
'delete_modal' => [
'title' => 'API-Key löschen',
'description' => 'Möchtest du diesen API-Key wirklich löschen? Alle Anwendungen, die diesen Key verwenden, verlieren sofort den Zugriff.',
'action' => 'API-Key löschen',
],
'create_dialog' => [
'title' => 'API-Key erstellen',
'description' => 'Erstelle einen neuen API-Key für den programmatischen Zugriff auf deinen Workspace.',
'name' => 'Name',
'name_placeholder' => 'z. B. Produktions-API-Key',
'expires' => 'Ablaufdatum (optional)',
'expires_placeholder' => 'Kein Ablauf',
'submit' => 'Erstellen',
'cancel' => 'Abbrechen',
],
'flash' => [
'created' => 'API-Key erfolgreich erstellt!',
'deleted' => 'API-Key erfolgreich gelöscht!',
],
],
];

61
lang/de/sidebar.php Normal file
View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
return [
'workspaces' => 'Workspaces',
'select_workspace' => 'Workspace auswählen',
'create_workspace' => 'Workspace erstellen',
'create_post' => 'Beitrag erstellen',
'profile' => 'Profil',
'log_out' => 'Abmelden',
'workspace' => 'Workspace: :name',
'workspace_select' => 'Workspace: Auswählen',
'theme' => 'Design: :name',
'theme_light' => 'Hell',
'theme_dark' => 'Dunkel',
'theme_system' => 'System',
'language' => 'Sprache: :name',
'language_select' => 'Sprache: Auswählen',
'groups' => [
'posts' => 'Beiträge',
'workspace' => 'Workspace',
'others' => 'Sonstiges',
],
'analytics' => 'Analytics',
'automations' => 'Automatisierungen',
'settings' => 'Einstellungen',
'posts' => [
'calendar' => 'Kalender',
'all' => 'Alle',
'scheduled' => 'Geplant',
'posted' => 'Veröffentlicht',
'drafts' => 'Entwürfe',
],
'workspace' => [
'connections' => 'Verbindungen',
'signatures' => 'Signaturen',
'labels' => 'Labels',
'assets' => 'Assets',
'api_keys' => 'API-Keys',
],
'notifications' => 'Benachrichtigungen',
'mark_all_read' => 'Alle als gelesen markieren',
'mark_as_read' => 'Als gelesen markieren',
'archive_all' => 'Alle archivieren',
'no_notifications' => 'Keine Benachrichtigungen',
'support' => [
'docs' => 'Dokumentation',
'referral' => '30% Provision verdienen',
'stay_updated' => 'Auf dem Laufenden bleiben',
],
];

61
lang/de/signatures.php Normal file
View file

@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
return [
'title' => 'Signaturen',
'description' => 'Erstelle wiederverwendbare Signaturen, um sie schnell an deine Beiträge anzuhängen',
'search' => 'Signaturen suchen...',
'new' => 'Neue Signatur',
'empty_title' => 'Noch keine Signaturen',
'empty_description' => 'Erstelle Signaturen, um schnell Hashtags, Links oder beliebige wiederverwendbare Texte an deine Beiträge anzuhängen',
'no_search_results' => 'Keine Signaturen passen zu deiner Suche',
'try_different_search' => 'Versuche ein anderes Stichwort oder setze die Suche zurück.',
'table' => [
'name' => 'Name',
'content' => 'Inhalt',
'created_at' => 'Erstellt',
],
'actions' => [
'edit' => 'Signatur bearbeiten',
'delete' => 'Signatur löschen',
],
'create' => [
'title' => 'Signatur erstellen',
'description' => 'Gib deiner Signatur einen Namen und den Inhalt zum Anhängen (Hashtags, Links, individueller Text – alles, was du wiederverwendest).',
'name' => 'Name',
'name_placeholder' => 'z. B. Marketing, Reisen, Marken-Grußformel',
'content' => 'Inhalt',
'content_placeholder' => "#marketing #socialmedia\nMehr erfahren: https://yourbrand.com",
'content_hint' => 'Hashtags, Links, individuelle Einleitungen, Grußformeln – alles, was du an Beiträge anhängst.',
'submit' => 'Signatur erstellen',
'submitting' => 'Wird erstellt...',
],
'edit' => [
'title' => 'Signatur bearbeiten',
'description' => 'Aktualisiere Name und Inhalt für diese Signatur.',
'name' => 'Name',
'name_placeholder' => 'z. B. Marketing, Reisen, Marken-Grußformel',
'content' => 'Inhalt',
'content_placeholder' => "#marketing #socialmedia\nMehr erfahren: https://yourbrand.com",
'content_hint' => 'Hashtags, Links, individuelle Einleitungen, Grußformeln – alles, was du an Beiträge anhängst.',
'submit' => 'Änderungen speichern',
'submitting' => 'Wird gespeichert...',
],
'delete' => [
'title' => 'Signatur löschen',
'description' => 'Möchtest du diese Signatur wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.',
'confirm' => 'Löschen',
'cancel' => 'Abbrechen',
],
'flash' => [
'created' => 'Signatur erstellt.',
'updated' => 'Signatur aktualisiert.',
'deleted' => 'Signatur gelöscht.',
],
];

17
lang/de/usage.php Normal file
View file

@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
return [
'title' => 'Nutzung',
'section_account' => 'Konto',
'section_account_description' => 'Kontingente und Limits für deinen Tarif.',
'section_ai' => 'KI-Credits',
'section_ai_description' => 'Credits werden bei der Nutzung von KI-Funktionen abgezogen. Sie werden am Ersten jedes Monats zurückgesetzt.',
'workspaces' => 'Workspaces',
'social_accounts' => 'Social-Media-Konten',
'members' => 'Mitglieder',
'credits' => 'Credits',
];

202
lang/de/validation.php Normal file
View file

@ -0,0 +1,202 @@
<?php
declare(strict_types=1);
return [
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => ':attribute muss akzeptiert werden.',
'accepted_if' => ':attribute muss akzeptiert werden, wenn :other :value ist.',
'active_url' => ':attribute muss eine gültige URL sein.',
'after' => ':attribute muss ein Datum nach :date sein.',
'after_or_equal' => ':attribute muss ein Datum nach oder gleich :date sein.',
'alpha' => ':attribute darf nur Buchstaben enthalten.',
'alpha_dash' => ':attribute darf nur Buchstaben, Zahlen, Bindestriche und Unterstriche enthalten.',
'alpha_num' => ':attribute darf nur Buchstaben und Zahlen enthalten.',
'any_of' => ':attribute ist ungültig.',
'array' => ':attribute muss ein Array sein.',
'ascii' => ':attribute darf nur alphanumerische Ein-Byte-Zeichen und Symbole enthalten.',
'before' => ':attribute muss ein Datum vor :date sein.',
'before_or_equal' => ':attribute muss ein Datum vor oder gleich :date sein.',
'between' => [
'array' => ':attribute muss zwischen :min und :max Elemente haben.',
'file' => ':attribute muss zwischen :min und :max Kilobyte groß sein.',
'numeric' => ':attribute muss zwischen :min und :max liegen.',
'string' => ':attribute muss zwischen :min und :max Zeichen lang sein.',
],
'boolean' => ':attribute muss wahr oder falsch sein.',
'can' => ':attribute enthält einen unzulässigen Wert.',
'confirmed' => 'Die Bestätigung von :attribute stimmt nicht überein.',
'contains' => ':attribute fehlt ein erforderlicher Wert.',
'current_password' => 'Das Passwort ist falsch.',
'date' => ':attribute muss ein gültiges Datum sein.',
'date_equals' => ':attribute muss ein Datum gleich :date sein.',
'date_format' => ':attribute muss dem Format :format entsprechen.',
'decimal' => ':attribute muss :decimal Dezimalstellen haben.',
'declined' => ':attribute muss abgelehnt werden.',
'declined_if' => ':attribute muss abgelehnt werden, wenn :other :value ist.',
'different' => ':attribute und :other müssen unterschiedlich sein.',
'digits' => ':attribute muss :digits Ziffern lang sein.',
'digits_between' => ':attribute muss zwischen :min und :max Ziffern lang sein.',
'dimensions' => ':attribute hat ungültige Bildabmessungen.',
'distinct' => ':attribute hat einen doppelten Wert.',
'doesnt_contain' => ':attribute darf keinen der folgenden Werte enthalten: :values.',
'doesnt_end_with' => ':attribute darf nicht mit einem der folgenden Werte enden: :values.',
'doesnt_start_with' => ':attribute darf nicht mit einem der folgenden Werte beginnen: :values.',
'email' => ':attribute muss eine gültige E-Mail-Adresse sein.',
'encoding' => ':attribute muss in :encoding kodiert sein.',
'ends_with' => ':attribute muss mit einem der folgenden Werte enden: :values.',
'enum' => 'Das ausgewählte :attribute ist ungültig.',
'exists' => 'Das ausgewählte :attribute ist ungültig.',
'extensions' => ':attribute muss eine der folgenden Dateiendungen haben: :values.',
'file' => ':attribute muss eine Datei sein.',
'filled' => ':attribute muss einen Wert haben.',
'gt' => [
'array' => ':attribute muss mehr als :value Elemente haben.',
'file' => ':attribute muss größer als :value Kilobyte sein.',
'numeric' => ':attribute muss größer als :value sein.',
'string' => ':attribute muss länger als :value Zeichen sein.',
],
'gte' => [
'array' => ':attribute muss :value oder mehr Elemente haben.',
'file' => ':attribute muss größer oder gleich :value Kilobyte sein.',
'numeric' => ':attribute muss größer oder gleich :value sein.',
'string' => ':attribute muss mindestens :value Zeichen lang sein.',
],
'hex_color' => ':attribute muss eine gültige Hexadezimalfarbe sein.',
'image' => ':attribute muss ein Bild sein.',
'in' => 'Das ausgewählte :attribute ist ungültig.',
'in_array' => ':attribute muss in :other vorhanden sein.',
'in_array_keys' => ':attribute muss mindestens einen der folgenden Schlüssel enthalten: :values.',
'integer' => ':attribute muss eine ganze Zahl sein.',
'ip' => ':attribute muss eine gültige IP-Adresse sein.',
'ipv4' => ':attribute muss eine gültige IPv4-Adresse sein.',
'ipv6' => ':attribute muss eine gültige IPv6-Adresse sein.',
'json' => ':attribute muss eine gültige JSON-Zeichenkette sein.',
'list' => ':attribute muss eine Liste sein.',
'lowercase' => ':attribute muss in Kleinbuchstaben geschrieben sein.',
'lt' => [
'array' => ':attribute muss weniger als :value Elemente haben.',
'file' => ':attribute muss kleiner als :value Kilobyte sein.',
'numeric' => ':attribute muss kleiner als :value sein.',
'string' => ':attribute muss kürzer als :value Zeichen sein.',
],
'lte' => [
'array' => ':attribute darf nicht mehr als :value Elemente haben.',
'file' => ':attribute muss kleiner oder gleich :value Kilobyte sein.',
'numeric' => ':attribute muss kleiner oder gleich :value sein.',
'string' => ':attribute darf höchstens :value Zeichen lang sein.',
],
'mac_address' => ':attribute muss eine gültige MAC-Adresse sein.',
'max' => [
'array' => ':attribute darf nicht mehr als :max Elemente haben.',
'file' => ':attribute darf nicht größer als :max Kilobyte sein.',
'numeric' => ':attribute darf nicht größer als :max sein.',
'string' => ':attribute darf nicht länger als :max Zeichen sein.',
],
'max_digits' => ':attribute darf nicht mehr als :max Ziffern haben.',
'mimes' => ':attribute muss eine Datei des folgenden Typs sein: :values.',
'mimetypes' => ':attribute muss eine Datei des folgenden Typs sein: :values.',
'min' => [
'array' => ':attribute muss mindestens :min Elemente haben.',
'file' => ':attribute muss mindestens :min Kilobyte groß sein.',
'numeric' => ':attribute muss mindestens :min sein.',
'string' => ':attribute muss mindestens :min Zeichen lang sein.',
],
'min_digits' => ':attribute muss mindestens :min Ziffern haben.',
'missing' => ':attribute muss fehlen.',
'missing_if' => ':attribute muss fehlen, wenn :other :value ist.',
'missing_unless' => ':attribute muss fehlen, es sei denn :other ist :value.',
'missing_with' => ':attribute muss fehlen, wenn :values vorhanden ist.',
'missing_with_all' => ':attribute muss fehlen, wenn :values vorhanden sind.',
'multiple_of' => ':attribute muss ein Vielfaches von :value sein.',
'not_in' => 'Das ausgewählte :attribute ist ungültig.',
'not_regex' => 'Das Format von :attribute ist ungültig.',
'numeric' => ':attribute muss eine Zahl sein.',
'password' => [
'letters' => ':attribute muss mindestens einen Buchstaben enthalten.',
'mixed' => ':attribute muss mindestens einen Groß- und einen Kleinbuchstaben enthalten.',
'numbers' => ':attribute muss mindestens eine Zahl enthalten.',
'symbols' => ':attribute muss mindestens ein Symbol enthalten.',
'uncompromised' => 'Das angegebene :attribute ist in einem Datenleck aufgetaucht. Bitte wähle ein anderes :attribute.',
],
'present' => ':attribute muss vorhanden sein.',
'present_if' => ':attribute muss vorhanden sein, wenn :other :value ist.',
'present_unless' => ':attribute muss vorhanden sein, es sei denn :other ist :value.',
'present_with' => ':attribute muss vorhanden sein, wenn :values vorhanden ist.',
'present_with_all' => ':attribute muss vorhanden sein, wenn :values vorhanden sind.',
'prohibited' => ':attribute ist unzulässig.',
'prohibited_if' => ':attribute ist unzulässig, wenn :other :value ist.',
'prohibited_if_accepted' => ':attribute ist unzulässig, wenn :other akzeptiert wurde.',
'prohibited_if_declined' => ':attribute ist unzulässig, wenn :other abgelehnt wurde.',
'prohibited_unless' => ':attribute ist unzulässig, es sei denn :other ist in :values enthalten.',
'prohibits' => ':attribute verhindert, dass :other vorhanden ist.',
'regex' => 'Das Format von :attribute ist ungültig.',
'required' => ':attribute muss ausgefüllt werden.',
'required_array_keys' => ':attribute muss Einträge für Folgendes enthalten: :values.',
'required_if' => ':attribute muss ausgefüllt werden, wenn :other :value ist.',
'required_if_accepted' => ':attribute muss ausgefüllt werden, wenn :other akzeptiert wurde.',
'required_if_declined' => ':attribute muss ausgefüllt werden, wenn :other abgelehnt wurde.',
'required_unless' => ':attribute muss ausgefüllt werden, es sei denn :other ist in :values enthalten.',
'required_with' => ':attribute muss ausgefüllt werden, wenn :values vorhanden ist.',
'required_with_all' => ':attribute muss ausgefüllt werden, wenn :values vorhanden sind.',
'required_without' => ':attribute muss ausgefüllt werden, wenn :values nicht vorhanden ist.',
'required_without_all' => ':attribute muss ausgefüllt werden, wenn keiner der Werte :values vorhanden ist.',
'same' => ':attribute muss mit :other übereinstimmen.',
'size' => [
'array' => ':attribute muss :size Elemente enthalten.',
'file' => ':attribute muss :size Kilobyte groß sein.',
'numeric' => ':attribute muss :size sein.',
'string' => ':attribute muss :size Zeichen lang sein.',
],
'starts_with' => ':attribute muss mit einem der folgenden Werte beginnen: :values.',
'string' => ':attribute muss eine Zeichenkette sein.',
'timezone' => ':attribute muss eine gültige Zeitzone sein.',
'unique' => ':attribute ist bereits vergeben.',
'uploaded' => ':attribute konnte nicht hochgeladen werden.',
'uppercase' => ':attribute muss in Großbuchstaben geschrieben sein.',
'url' => ':attribute muss eine gültige URL sein.',
'ulid' => ':attribute muss eine gültige ULID sein.',
'uuid' => ':attribute muss eine gültige UUID sein.',
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
/*
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap our attribute placeholder
| with something more reader friendly such as "E-Mail Address" instead
| of "email". This simply helps us make our message more expressive.
|
*/
'attributes' => [],
];

50
lang/de/workspaces.php Normal file
View file

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
return [
'title' => 'Workspaces',
'select_title' => 'Deine Workspaces',
'select_description' => 'Wähle einen Workspace, um fortzufahren',
'current' => 'Aktuell',
'connections' => ':count Verbindungen',
'posts' => ':count Beiträge',
'create' => [
'page_title' => 'Erstelle deinen Workspace',
'title' => 'Richte deinen Workspace ein',
'description' => 'Erzähl uns ein wenig über dich oder dein Projekt. Wir nutzen das, um KI-generierte Beiträge an deinen Ton anzupassen.',
'website' => 'Website',
'website_placeholder' => 'https://yourbrand.com',
'autofill' => 'Von Website automatisch ausfüllen',
'autofill_missing_url' => 'Gib zuerst eine URL ein.',
'autofill_success' => 'Markeninformationen geladen.',
'autofill_error' => 'Automatisches Ausfüllen nicht möglich. Du kannst die Felder manuell ausfüllen.',
'autofill_errors' => [
'unreachable' => 'Wir konnten diese Website nicht erreichen (:reason).',
'http_status' => 'Die Website hat einen unerwarteten Status zurückgegeben (:status).',
'invalid_scheme' => 'Nur http- und https-URLs werden unterstützt.',
'missing_host' => 'Der URL fehlt ein Host.',
'unresolvable_host' => 'Wir konnten den Host nicht auflösen (:host).',
'private_network' => 'URLs, die auf private Netzwerke verweisen, sind nicht zulässig.',
],
'logo_captured' => 'Logo von deiner Website übernommen.',
'name' => 'Workspace-Name',
'name_placeholder' => 'z. B. Acme Inc',
'brand_description' => 'Markenbeschreibung',
'brand_description_placeholder' => 'Was macht deine Marke?',
'content_language' => 'Inhaltssprache',
'content_language_description' => 'KI-generierte Bildunterschriften werden in dieser Sprache verfasst.',
'brand_color' => 'Markenfarbe',
'background_color' => 'Hintergrundfarbe',
'text_color' => 'Textfarbe',
'submit' => 'Workspace erstellen',
'success' => 'Workspace erstellt. Verbinde ein Social-Media-Konto, um mit dem Posten zu beginnen.',
],
'cannot_delete_last' => 'Du kannst deinen einzigen Workspace nicht löschen. Kündige dein Abonnement in den Abrechnungseinstellungen, um dein Konto zu schließen.',
'flash' => [
'deleted' => 'Workspace erfolgreich gelöscht.',
],
];

148
lang/el/accounts.php Normal file
View file

@ -0,0 +1,148 @@
<?php
return [
'title' => 'Συνδέσεις',
'page_title' => 'Λογαριασμοί κοινωνικών δικτύων',
'description' => 'Επισκόπηση όλων των συνδεδεμένων λογαριασμών κοινωνικών δικτύων σας',
'connect_cta' => 'Σύνδεση',
'not_connected' => 'Μη συνδεδεμένος',
'connect' => 'Σύνδεση',
'connection_lost' => 'Η σύνδεση χάθηκε',
'reconnect' => 'Επανασύνδεση',
'reconnect_account' => 'Επανασύνδεση λογαριασμού',
'view_profile' => 'Προβολή προφίλ',
'disconnect' => 'Αποσύνδεση',
'descriptions' => [
'linkedin' => 'Συνδέστε το προφίλ LinkedIn ή τη σελίδα εταιρείας σας',
'linkedin-page' => 'Συνδέστε μια σελίδα εταιρείας LinkedIn',
'x' => 'Συνδέστε τον λογαριασμό σας X (Twitter)',
'tiktok' => 'Συνδέστε τον λογαριασμό σας TikTok',
'youtube' => 'Συνδέστε ένα κανάλι YouTube',
'facebook' => 'Συνδέστε μια σελίδα Facebook',
'instagram' => 'Συνδέστε έναν επαγγελματικό λογαριασμό Instagram',
'instagram-facebook' => 'Συνδέστε το Instagram μέσω σελίδας Facebook',
'threads' => 'Συνδέστε τον λογαριασμό σας Threads',
'pinterest' => 'Συνδέστε τον λογαριασμό σας Pinterest',
'bluesky' => 'Συνδέστε τον λογαριασμό σας Bluesky',
'mastodon' => 'Συνδέστε τον λογαριασμό σας Mastodon',
'telegram' => 'Συνδέστε ένα κανάλι ή ομάδα Telegram',
'discord' => 'Συνδέστε έναν διακομιστή Discord',
],
'disconnect_modal' => [
'title' => 'Αποσύνδεση λογαριασμού',
'description' => 'Είστε βέβαιοι ότι θέλετε να αποσυνδέσετε αυτόν τον λογαριασμό; Μπορείτε να τον επανασυνδέσετε ανά πάσα στιγμή.',
'confirm' => 'Αποσύνδεση',
'cancel' => 'Ακύρωση',
],
'bluesky' => [
'title' => 'Σύνδεση Bluesky',
'description' => 'Εισάγετε τα διαπιστευτήριά σας για σύνδεση',
'email' => 'Email',
'email_placeholder' => 'yourhandle.bsky.social',
'app_password' => 'App Password',
'app_password_placeholder' => 'xxxx-xxxx-xxxx-xxxx',
'app_password_hint' => 'Χρησιμοποιήστε ένα <strong>App Password</strong> για ασφάλεια. Δημιουργήστε ένα στο <a href="https://bsky.app/settings/app-passwords" target="_blank" class="underline">bsky.app/settings</a>.',
'submit' => 'Σύνδεση Bluesky',
'submitting' => 'Σύνδεση...',
],
'mastodon' => [
'title' => 'Σύνδεση Mastodon',
'description' => 'Εισάγετε το instance του Mastodon σας',
'instance_url' => 'URL instance',
'instance_placeholder' => 'https://mastodon.social',
'instance_hint' => 'Εισάγετε τη διεύθυνση URL του instance Mastodon σας (π.χ. mastodon.social, techhub.social)',
'submit' => 'Συνέχεια με Mastodon',
'submitting' => 'Σύνδεση...',
],
'telegram' => [
'title' => 'Σύνδεση Telegram',
'description' => 'Συνδέστε ένα κανάλι ή ομάδα',
'step_admin' => 'Προσθέστε το :bot ως διαχειριστή στο κανάλι ή την ομάδα Telegram σας.',
'step_command' => 'Δημοσιεύστε αυτή την εντολή στο κανάλι ή την ομάδα:',
'waiting' => 'Αναμονή για τη σύνδεση του καναλιού…',
'connected' => 'Το κανάλι συνδέθηκε!',
'connected_toast' => 'Το κανάλι Telegram συνδέθηκε με επιτυχία!',
'copied_toast' => 'Η εντολή αντιγράφηκε στο πρόχειρο',
'copy_tooltip' => 'Αντιγραφή εντολής',
'expired' => 'Αυτός ο κωδικός έληξε. Δημιουργήστε έναν νέο για να δοκιμάσετε ξανά.',
'new_code' => 'Δημιουργία νέου κωδικού',
'retry' => 'Δοκιμάστε ξανά',
'error_generic' => 'Δεν ήταν δυνατή η έναρξη της σύνδεσης. Παρακαλούμε δοκιμάστε ξανά.',
'network_taken' => 'Αυτό το workspace έχει ήδη συνδεδεμένο ένα κανάλι Telegram. Αποσυνδέστε το πρώτα.',
],
'facebook' => [
'title' => 'Επιλογή σελίδας Facebook',
'description' => 'Επιλέξτε ποια σελίδα θέλετε να συνδέσετε',
'no_pages' => 'Δεν βρέθηκαν σελίδες',
'no_pages_description' => 'Δεν είστε διαχειριστής καμίας σελίδας Facebook.',
'page_label' => 'Σελίδα Facebook',
'view' => 'Προβολή',
'choose' => 'Επιλογή',
],
'instagram_facebook' => [
'title' => 'Επιλογή λογαριασμού Instagram',
'description' => 'Επιλέξτε ποιον λογαριασμό Instagram θέλετε να συνδέσετε',
'no_pages' => 'Δεν βρέθηκαν λογαριασμοί Instagram',
'no_pages_description' => 'Δεν βρέθηκαν σελίδες Facebook με συνδεδεμένους επαγγελματικούς λογαριασμούς Instagram.',
'view' => 'Προβολή',
'choose' => 'Επιλογή',
],
'linkedin' => [
'title' => 'Επιλογή σελίδας LinkedIn',
'description' => 'Επιλέξτε ποια σελίδα θέλετε να συνδέσετε',
'no_pages' => 'Δεν βρέθηκαν σελίδες',
'no_pages_description' => 'Δεν είστε διαχειριστής καμίας σελίδας LinkedIn.',
'page_label' => 'Σελίδα LinkedIn',
'select_title' => 'Πού θέλετε να δημοσιεύσετε;',
'select_subtitle' => 'Δημοσιεύστε ως εσείς ή επιλέξτε μια σελίδα εταιρείας που διαχειρίζεστε.',
'person_tag' => 'Άτομο',
'organization_tag' => 'Οργανισμός',
'view' => 'Προβολή',
'choose' => 'Επιλογή',
],
'flash' => [
'disconnected' => 'Ο λογαριασμός αποσυνδέθηκε με επιτυχία!',
'connected' => 'Ο λογαριασμός συνδέθηκε με επιτυχία!',
'session_expired' => 'Η συνεδρία έληξε. Παρακαλούμε δοκιμάστε ξανά.',
'workspace_not_found' => 'Το workspace δεν βρέθηκε.',
'activated' => 'Ο λογαριασμός ενεργοποιήθηκε!',
'deactivated' => 'Ο λογαριασμός απενεργοποιήθηκε!',
'already_connected' => 'Αυτή η πλατφόρμα είναι ήδη συνδεδεμένη.',
'no_youtube_channels' => 'Δεν βρέθηκαν κανάλια YouTube. Παρακαλούμε δημιουργήστε πρώτα ένα κανάλι.',
],
'popup_callback' => [
'title_success' => 'Συνδέθηκε',
'title_error' => 'Σφάλμα',
'closing' => 'Αυτό το παράθυρο θα κλείσει αυτόματα...',
'manual_close' => 'Μπορείτε να κλείσετε αυτό το παράθυρο.',
'popup_blocked' => 'Δεν ήταν δυνατό το άνοιγμα του παραθύρου σύνδεσης. Παρακαλούμε επιτρέψτε τα αναδυόμενα παράθυρα και δοκιμάστε ξανά.',
'connected' => 'Ο λογαριασμός συνδέθηκε!',
'reconnected' => 'Ο λογαριασμός επανασυνδέθηκε!',
'error_connecting' => 'Σφάλμα κατά τη σύνδεση του λογαριασμού. Παρακαλούμε δοκιμάστε ξανά.',
'network_taken' => 'Αυτό το workspace έχει ήδη λογαριασμό για αυτό το δίκτυο. Αποσυνδέστε τον πρώτα.',
'error_connecting_page' => 'Σφάλμα κατά τη σύνδεση της σελίδας. Παρακαλούμε δοκιμάστε ξανά.',
'error_connecting_channel' => 'Σφάλμα κατά τη σύνδεση του καναλιού. Παρακαλούμε δοκιμάστε ξανά.',
'session_expired' => 'Η συνεδρία έληξε. Παρακαλούμε δοκιμάστε ξανά.',
'workspace_not_found' => 'Το workspace δεν βρέθηκε.',
'invalid_state' => 'Μη έγκυρη κατάσταση. Παρακαλούμε δοκιμάστε ξανά.',
'failed_to_authenticate' => 'Η ταυτοποίηση απέτυχε.',
'failed_to_get_profile' => 'Η ανάκτηση του προφίλ απέτυχε.',
'page_not_found' => 'Η σελίδα δεν βρέθηκε.',
'channel_not_found' => 'Το κανάλι δεν βρέθηκε.',
'no_facebook_pages' => 'Δεν βρέθηκαν σελίδες Facebook. Πρέπει να είστε διαχειριστής τουλάχιστον μίας σελίδας.',
'no_facebook_instagram_pages' => 'Δεν βρέθηκαν σελίδες Facebook με συνδεδεμένους λογαριασμούς Instagram.',
'no_youtube_channels' => 'Δεν βρέθηκαν κανάλια YouTube. Παρακαλούμε δημιουργήστε πρώτα ένα κανάλι.',
'not_linkedin_admin' => 'Δεν είστε διαχειριστής καμίας σελίδας LinkedIn.',
],
];

55
lang/el/analytics.php Normal file
View file

@ -0,0 +1,55 @@
<?php
return [
'no_accounts' => 'Δεν υπάρχουν συνδεδεμένοι λογαριασμοί με στατιστικά.',
'no_accounts_match' => 'Δεν ταιριάζει κανένας λογαριασμός.',
'search_account' => 'Αναζήτηση λογαριασμού…',
'select_account' => 'Επιλέξτε έναν λογαριασμό για να δείτε στατιστικά.',
'no_data' => 'Δεν υπάρχουν διαθέσιμα στατιστικά δεδομένα.',
'metrics' => [
'avg_view_duration' => 'Μέση διάρκεια προβολής (δευτ.)',
'avg_view_percentage' => 'Μέσο ποσοστό προβολής',
'bookmarks' => 'Σελιδοδείκτες',
'clicks' => 'Κλικ',
'comments' => 'Σχόλια',
'custom_reaction' => 'Προσαρμοσμένη',
'engagement' => 'Αλληλεπίδραση',
'favourites' => 'Αγαπημένα',
'followers' => 'Ακόλουθοι',
'following' => 'Ακολουθείτε',
'impressions' => 'Εμφανίσεις',
'interactions' => 'Αλληλεπιδράσεις',
'likes' => 'Μου αρέσει',
'members' => 'Μέλη',
'minutes_watched' => 'Λεπτά παρακολούθησης',
'organic_followers' => 'Οργανικοί ακόλουθοι',
'outbound_clicks' => 'Εξερχόμενα κλικ',
'page_followers' => 'Ακόλουθοι σελίδας',
'page_reach' => 'Απήχηση σελίδας',
'page_views' => 'Προβολές σελίδας',
'paid_followers' => 'Πληρωμένοι ακόλουθοι',
'pin_click_rate' => 'Ποσοστό κλικ pin',
'pin_clicks' => 'Κλικ pin',
'posts_engagement' => 'Αλληλεπίδραση δημοσιεύσεων',
'posts_reach' => 'Απήχηση δημοσιεύσεων',
'quotes' => 'Παραθέσεις',
'reach' => 'Απήχηση',
'reblogs' => 'Αναδημοσιεύσεις',
'recent_comments' => 'Πρόσφατα σχόλια',
'recent_likes' => 'Πρόσφατα μου αρέσει',
'recent_shares' => 'Πρόσφατες κοινοποιήσεις',
'replies' => 'Απαντήσεις',
'reposts' => 'Αναδημοσιεύσεις',
'retweets' => 'Retweets',
'saves' => 'Αποθηκεύσεις',
'shares' => 'Κοινοποιήσεις',
'subscribers' => 'Συνδρομητές',
'subscribers_gained' => 'Νέοι συνδρομητές',
'subscribers_lost' => 'Συνδρομητές που χάθηκαν',
'total_likes' => 'Συνολικά μου αρέσει',
'video_views' => 'Προβολές βίντεο',
'videos' => 'Βίντεο',
'views' => 'Προβολές',
],
];

52
lang/el/assets.php Normal file
View file

@ -0,0 +1,52 @@
<?php
return [
'title' => 'Στοιχεία',
'tabs' => [
'my_uploads' => 'Οι μεταφορτώσεις μου',
'stock_photos' => 'Έτοιμες φωτογραφίες',
'gifs' => 'GIF',
],
'upload' => [
'drag_drop' => 'Σύρετε και αποθέστε τα αρχεία σας εδώ ή κάντε κλικ για επιλογή',
'formats' => 'JPEG, PNG, GIF, WebP, MP4, PDF',
'uploading' => 'Μεταφόρτωση...',
'failed' => 'Δεν ήταν δυνατή η μεταφόρτωση του :file. Παρακαλούμε δοκιμάστε ξανά.',
],
'empty' => [
'title' => 'Δεν υπάρχουν στοιχεία ακόμη',
'description' => 'Μεταφορτώστε εικόνες και βίντεο για να χτίσετε τη βιβλιοθήκη πολυμέσων σας.',
],
'save_to_assets' => 'Αποθήκευση στα στοιχεία',
'saved' => 'Αποθηκεύτηκε στα στοιχεία σας!',
'create_post' => 'Δημιουργία δημοσίευσης',
'add_to_post' => 'Προσθήκη σε δημοσίευση',
'search_placeholder' => 'Αναζήτηση πολυμέσων...',
'delete' => [
'title' => 'Διαγραφή στοιχείου',
'description' => 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το στοιχείο; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.',
'confirm' => 'Διαγραφή',
'cancel' => 'Ακύρωση',
],
'unsplash' => [
'search_placeholder' => 'Αναζήτηση δωρεάν φωτογραφιών...',
'no_results' => 'Δεν βρέθηκαν φωτογραφίες',
'no_results_description' => 'Δοκιμάστε διαφορετικό όρο αναζήτησης.',
'trending' => 'Δημοφιλή στο Unsplash',
'start_searching' => 'Αναζητήστε δωρεάν έτοιμες φωτογραφίες από το Unsplash',
],
'giphy' => [
'trending' => 'Δημοφιλή στο Giphy',
'search_placeholder' => 'Αναζήτηση GIF...',
'no_results' => 'Δεν βρέθηκαν GIF',
'no_results_description' => 'Δοκιμάστε διαφορετικό όρο αναζήτησης.',
'powered_by' => 'Powered by GIPHY',
],
];

141
lang/el/auth.php Normal file
View file

@ -0,0 +1,141 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'Αυτά τα στοιχεία δεν ταιριάζουν με τα αρχεία μας.',
'password' => 'Ο κωδικός πρόσβασης που δώσατε είναι εσφαλμένος.',
'throttle' => 'Πάρα πολλές προσπάθειες σύνδεσης. Παρακαλούμε δοκιμάστε ξανά σε :seconds δευτερόλεπτα.',
'flash' => [
'welcome' => 'Καλώς ήρθατε στο TryPost!',
'welcome_trial' => 'Καλώς ήρθατε στο TryPost! Η δοκιμαστική σας περίοδος ξεκίνησε.',
],
'legal' => 'Συνεχίζοντας, συμφωνείτε με τους <a href="https://trypost.it/terms" target="_blank">Όρους Χρήσης</a> και την <a href="https://trypost.it/privacy" target="_blank">Πολιτική Απορρήτου</a> μας.',
'slides' => [
'calendar' => [
'title' => 'Οπτικό ημερολόγιο',
'description' => 'Σχεδιάστε και προγραμματίστε το περιεχόμενό σας με ένα διαισθητικό ημερολόγιο drag-and-drop σε όλους τους λογαριασμούς κοινωνικών δικτύων σας.',
],
'scheduling' => [
'title' => 'Έξυπνος προγραμματισμός',
'description' => 'Προγραμματίστε δημοσιεύσεις σε LinkedIn, X, Instagram, TikTok, YouTube και άλλα — όλα από ένα μέρος.',
],
'media' => [
'title' => 'Πλούσια πολυμέσα',
'description' => 'Δημοσιεύστε εικόνες, carousels, stories και reels. Κάθε πλατφόρμα λαμβάνει αυτόματα τη σωστή μορφή.',
],
'video' => [
'title' => 'Δημοσίευση βίντεο',
'description' => 'Μεταφορτώστε βίντεο μία φορά και δημοσιεύστε σε TikTok, YouTube Shorts, Instagram Reels και Facebook Reels.',
],
'team' => [
'title' => 'Workspaces ομάδας',
'description' => 'Προσκαλέστε την ομάδα σας, αναθέστε ρόλους και διαχειριστείτε πολλές μάρκες από ξεχωριστά workspaces.',
],
'signatures' => [
'title' => 'Υπογραφές',
'description' => 'Αποθηκεύστε επαναχρησιμοποιήσιμες υπογραφές (hashtags, συνδέσμους, κλεισίματα) και προσθέστε τις στις δημοσιεύσεις με ένα κλικ.',
],
],
'or_continue_with' => 'Ή συνεχίστε με',
'or_continue_with_email' => 'Ή συνεχίστε με email',
'google_login' => 'Σύνδεση με Google',
'google_signup' => 'Εγγραφή με Google',
'github_login' => 'Σύνδεση με GitHub',
'github_signup' => 'Εγγραφή με GitHub',
'github_email_unavailable' => 'Δεν ήταν δυνατή η ανάκτηση του email σας από το GitHub. Κάντε δημόσιο το email σας στο GitHub ή παραχωρήστε το scope email και δοκιμάστε ξανά.',
'signup_success' => [
'page_title' => 'Καλώς ήρθατε',
'title' => 'Ρύθμιση του λογαριασμού σας',
'description' => 'Αυτό συνήθως διαρκεί μόνο λίγα δευτερόλεπτα...',
],
'login' => [
'title' => 'Συνδεθείτε στον λογαριασμό σας',
'description' => 'Εισάγετε το email και τον κωδικό πρόσβασής σας παρακάτω για να συνδεθείτε',
'page_title' => 'Σύνδεση',
'email' => 'Διεύθυνση email',
'password' => 'Κωδικός πρόσβασης',
'forgot_password' => 'Ξεχάσατε τον κωδικό;',
'remember_me' => 'Να με θυμάσαι',
'submit' => 'Σύνδεση',
'no_account' => 'Δεν έχετε λογαριασμό;',
'sign_up' => 'Εγγραφή',
],
'register' => [
'title' => 'Όλο το κοινωνικό σας ημερολόγιο, σε ένα μέρος',
'description' => 'Δημιουργήστε τον λογαριασμό σας και ξεκινήστε να προγραμματίζετε δημοσιεύσεις σε κάθε δίκτυο.',
'page_title' => 'Εγγραφή',
'signup_with_email' => 'Εγγραφή με email',
'name' => 'Όνομα',
'name_placeholder' => 'Ονοματεπώνυμο',
'email' => 'Διεύθυνση email',
'password' => 'Κωδικός πρόσβασης',
'show_password' => 'Εμφάνιση κωδικού',
'hide_password' => 'Απόκρυψη κωδικού',
'submit' => 'Δημιουργία λογαριασμού',
'has_account' => 'Έχετε ήδη λογαριασμό;',
'log_in' => 'Σύνδεση',
],
'forgot_password' => [
'title' => 'Ξεχάσατε τον κωδικό',
'description' => 'Εισάγετε το email σας για να λάβετε έναν σύνδεσμο επαναφοράς κωδικού',
'page_title' => 'Ξεχάσατε τον κωδικό',
'email' => 'Διεύθυνση email',
'submit' => 'Αποστολή συνδέσμου επαναφοράς μέσω email',
'return_to' => 'Ή, επιστρέψτε στη',
'log_in' => 'σύνδεση',
],
'reset_password' => [
'title' => 'Επαναφορά κωδικού',
'description' => 'Παρακαλούμε εισάγετε τον νέο κωδικό πρόσβασής σας παρακάτω',
'page_title' => 'Επαναφορά κωδικού',
'email' => 'Email',
'password' => 'Κωδικός πρόσβασης',
'confirm_password' => 'Επιβεβαίωση κωδικού',
'confirm_placeholder' => 'Επιβεβαίωση κωδικού',
'submit' => 'Επαναφορά κωδικού',
],
'verify_email' => [
'title' => 'Επαλήθευση email',
'description' => 'Παρακαλούμε επαληθεύστε τη διεύθυνση email σας κάνοντας κλικ στον σύνδεσμο που μόλις σας στείλαμε.',
'page_title' => 'Επαλήθευση email',
'link_sent' => 'Ένας νέος σύνδεσμος επαλήθευσης στάλθηκε στη διεύθυνση email που δώσατε κατά την εγγραφή.',
'resend' => 'Επαναποστολή email επαλήθευσης',
'log_out' => 'Αποσύνδεση',
],
'accept_invite' => [
'page_title' => 'Αποδοχή πρόσκλησης',
'title' => 'Λάβατε πρόσκληση!',
'description' => 'Λάβατε πρόσκληση να συμμετάσχετε στο workspace :workspace.',
'workspace' => 'Workspace',
'your_role' => 'Ο ρόλος σας',
'email' => 'Email',
'accept' => 'Αποδοχή πρόσκλησης',
'decline' => 'Απόρριψη πρόσκλησης',
'login_prompt' => 'Συνδεθείτε ή δημιουργήστε λογαριασμό για να αποδεχτείτε αυτή την πρόσκληση.',
'log_in' => 'Σύνδεση',
'create_account' => 'Δημιουργία λογαριασμού',
],
];

411
lang/el/automations.php Normal file
View file

@ -0,0 +1,411 @@
<?php
declare(strict_types=1);
return [
'title' => 'Αυτοματισμοί',
'default_name' => 'Νέος αυτοματισμός',
'actions' => [
'new' => 'Νέος αυτοματισμός',
'edit' => 'Επεξεργασία',
'save' => 'Αποθήκευση',
'activate' => 'Ενεργοποίηση',
'pause' => 'Παύση',
'delete' => 'Διαγραφή',
'retry' => 'Επανάληψη',
'guide' => 'Μάθετε πώς λειτουργεί',
],
'tabs' => [
'build' => 'Δημιουργία',
'variables' => 'Μεταβλητές',
'test' => 'Δοκιμή',
],
'nav' => [
'workflow' => 'Ροή εργασίας',
'invocations' => 'Εκτελέσεις',
'metrics' => 'Μετρήσεις',
'settings' => 'Ρυθμίσεις',
],
'settings' => [
'general' => 'Γενικά',
'general_description' => 'Μετονομάστε αυτόν τον αυτοματισμό.',
'name_label' => 'Όνομα',
'name_saved' => 'Ο αυτοματισμός μετονομάστηκε.',
'status_title' => 'Κατάσταση',
'status_description' => 'Ενεργοποιήστε για να ξεκινήσει η εκτέλεση ή κάντε παύση για να σταματήσει.',
'activated_at' => 'Ενεργοποιήθηκε :date',
'paused_at' => 'Σε παύση :date',
'created_at' => 'Δημιουργήθηκε :date',
'danger_title' => 'Ζώνη κινδύνου',
'danger_description' => 'Μη αναστρέψιμες ενέργειες.',
'delete_title' => 'Διαγραφή αυτού του αυτοματισμού',
'delete_description' => 'Αφαιρεί οριστικά τον αυτοματισμό και το ιστορικό εκτελέσεών του.',
],
'status_run' => [
'pending' => 'Σε εκκρεμότητα',
'running' => 'Σε εξέλιξη',
'waiting' => 'Σε αναμονή',
'completed' => 'Ολοκληρώθηκε',
'failed' => 'Απέτυχε',
'cancelled' => 'Ακυρώθηκε',
],
'node_type' => [
'trigger' => 'Έναυσμα',
'generate' => 'Δημιουργία περιεχομένου',
'delay' => 'Καθυστέρηση',
'condition' => 'Συνθήκη',
'publish' => 'Δημοσίευση',
'webhook' => 'Webhook',
'end' => 'Τέλος',
'fetch_rss' => 'Ανάκτηση RSS',
'http_request' => 'Αίτημα HTTP',
],
'invocations' => [
'empty' => 'Δεν υπάρχουν εκτελέσεις ακόμη.',
'refresh' => 'Ανανέωση',
'search_placeholder' => 'Αναζήτηση με ID εκτέλεσης…',
'copied' => 'Το ID εκτέλεσης αντιγράφηκε.',
'loading' => 'Φόρτωση βημάτων…',
'no_steps' => 'Δεν καταγράφηκαν βήματα.',
'load_error' => 'Δεν ήταν δυνατή η φόρτωση των βημάτων.',
'steps' => '{0}Κανένα βήμα|{1}:count βήμα|[2,*]:count βήματα',
'filter' => [
'all' => 'Όλες οι καταστάσεις',
],
'columns' => [
'timestamp' => 'Χρονική σήμανση',
'run' => 'Εκτέλεση',
'status' => 'Κατάσταση',
'message' => 'Τελευταίο μήνυμα',
'duration' => 'Διάρκεια',
],
'summary' => [
'completed' => 'Η ροή εργασίας ολοκληρώθηκε',
'failed' => 'Η ροή εργασίας απέτυχε',
'running' => 'Η ροή εργασίας εκτελείται',
'cancelled' => 'Η ροή εργασίας ακυρώθηκε',
'pending' => 'Η ροή εργασίας εκκρεμεί',
],
],
'metrics' => [
'overview' => 'Επισκόπηση',
'runs_over_time' => 'Εκτελέσεις με την πάροδο του χρόνου',
'posts_by_platform' => 'Δημοσιεύσεις ανά πλατφόρμα',
'no_posts' => 'Δεν δημοσιεύτηκαν δημοσιεύσεις σε αυτή την περίοδο.',
'cards' => [
'runs' => 'Συνολικές εκτελέσεις',
'completed' => 'Ολοκληρώθηκαν',
'failed' => 'Απέτυχαν',
'in_progress' => 'Σε εξέλιξη',
'success_rate' => 'Ποσοστό επιτυχίας',
'avg_duration' => 'Μέση διάρκεια',
'posts_created' => 'Δημοσιεύσεις που δημιουργήθηκαν',
],
'legend' => [
'started' => 'Ξεκίνησαν',
'completed' => 'Ολοκληρώθηκαν',
'failed' => 'Απέτυχαν',
],
],
'categories' => [
'sources' => 'Πηγές',
'content' => 'Περιεχόμενο',
'flow' => 'Ροή',
'output' => 'Έξοδος',
],
'variables' => [
'title' => 'Μεταβλητές ροής εργασίας',
'hint' => 'Επαναχρησιμοποιήσιμες τιμές που αναφέρονται οπουδήποτε με {{ variables.KEY }}. Αποθηκεύονται κρυπτογραφημένες.',
'empty' => 'Δεν υπάρχουν μεταβλητές ακόμη.',
'key' => 'Κλειδί',
'value' => 'Τιμή',
'key_placeholder' => 'API_KEY',
'value_placeholder' => 'Τιμή',
'add' => 'Νέα μεταβλητή',
],
'expr' => [
'trigger_event' => 'Όνομα συμβάντος εναύσματος',
'trigger_fired_at' => 'Πότε ενεργοποιήθηκε το έναυσμα',
'trigger_post_id' => 'ID δημοσίευσης εναύσματος',
'trigger_post_content' => 'Περιεχόμενο δημοσίευσης εναύσματος',
'trigger_post_status' => 'Κατάσταση δημοσίευσης εναύσματος',
'trigger_post_scheduled_at' => 'Πότε είναι προγραμματισμένη η δημοσίευση',
'trigger_post_published_at' => 'Πότε δημοσιεύτηκε η δημοσίευση',
'fetched_title' => 'Τίτλος ανακτηθέντος στοιχείου',
'fetched_link' => 'Σύνδεσμος ανακτηθέντος στοιχείου',
'fetched_date' => 'Ημερομηνία δημοσίευσης ανακτηθέντος στοιχείου',
'fetched_content' => 'Πλήρες περιεχόμενο ανακτηθέντος στοιχείου',
'fetched_description' => 'Σύνοψη ανακτηθέντος στοιχείου',
'fetched_author' => 'Συντάκτης ανακτηθέντος στοιχείου',
'fetched_image' => 'URL εικόνας ανακτηθέντος στοιχείου',
'fetched_categories' => 'Κατηγορίες ανακτηθέντος στοιχείου',
'fetched_enclosure' => 'Πολυμέσα ανακτηθέντος στοιχείου (ήχος/βίντεο/αρχείο)',
'fetched_pubdate' => 'Ημερομηνία δημοσίευσης ανακτηθέντος στοιχείου',
'fetched_http' => 'Ανακτηθέν στοιχείο HTTP (προσθέστε ένα πεδίο)',
'generated_content' => 'Περιεχόμενο δημοσίευσης που δημιούργησε το AI',
'generated_post_url' => 'URL δημοσίευσης που δημιούργησε το AI',
'variable' => 'Μεταβλητή ροής εργασίας',
'now' => 'Τρέχουσα ημερομηνία και ώρα',
],
'test' => [
'description' => 'Εκτελεί τον αυτοματισμό από άκρη σε άκρη χρησιμοποιώντας ένα συνθετικό payload εναύσματος. Χρήσιμο για την επικύρωση κάθε κόμβου χωρίς αναμονή για το πραγματικό χρονοδιάγραμμα ή τη ροή.',
'starting' => 'Έναρξη δοκιμαστικής εκτέλεσης…',
'in_progress' => 'Σε εξέλιξη',
'completed' => 'Ολοκληρώθηκε',
'failed' => 'Απέτυχε',
'waiting' => 'Σε αναμονή',
'close' => 'Κλείσιμο',
'no_node_runs' => 'Αναμονή για την έναρξη του πρώτου κόμβου…',
'node_input' => 'Είσοδος',
'node_output' => 'Έξοδος',
'node_error' => 'Σφάλμα',
'no_new_items' => 'Δεν υπάρχουν νέα στοιχεία — τίποτα δεν εκτελέστηκε παρακάτω.',
'error_starting' => 'Δεν ήταν δυνατή η έναρξη της δοκιμαστικής εκτέλεσης.',
'with_real_data' => 'Με πραγματικά δεδομένα',
'run' => 'Εκτέλεση δοκιμής',
'idle_hint' => 'Πατήστε Εκτέλεση δοκιμής για να εκτελέσετε τον αυτοματισμό από άκρη σε άκρη.',
'real_data_hint' => 'Αυτή η δοκιμή θα δημοσιεύσει δημοσιεύσεις, θα προωθήσει τα σημεία ελέγχου polling και θα ενεργοποιήσει εξωτερικές παρενέργειες.',
'dry_badge' => 'Δοκιμαστική εκτέλεση',
],
'status' => [
'draft' => 'Πρόχειρο',
'active' => 'Ενεργός',
'paused' => 'Σε παύση',
],
'index' => [
'empty_title' => 'Δεν υπάρχουν αυτοματισμοί ακόμη',
'empty_description' => 'Δημιουργήστε τον πρώτο σας αυτοματισμό για να ξεκινήσετε να δημοσιεύετε αυτόματα.',
'columns' => [
'name' => 'Όνομα',
'status' => 'Κατάσταση',
'created' => 'Δημιουργήθηκε',
],
],
'form' => [
'activate_error_fallback' => 'Δεν ήταν δυνατή η ενεργοποίηση του αυτοματισμού.',
'pause_error_fallback' => 'Δεν ήταν δυνατή η παύση του αυτοματισμού.',
'save_error_fallback' => 'Δεν ήταν δυνατή η αποθήκευση του αυτοματισμού.',
'save_success' => 'Ο αυτοματισμός αποθηκεύτηκε.',
'empty_canvas_title' => 'Ξεκινήστε να δημιουργείτε τον αυτοματισμό σας',
'empty_canvas_description' => 'Σύρετε έναν κόμβο από τον αριστερό πίνακα για να ξεκινήσετε.',
'name_placeholder' => 'Αυτοματισμός χωρίς τίτλο',
],
'nodes' => [
'trigger' => 'Έναυσμα',
'generate' => 'Δημιουργία',
'delay' => 'Καθυστέρηση',
'condition' => 'Συνθήκη',
'publish' => 'Δημοσίευση',
'webhook' => 'Webhook',
'end' => 'Τέλος',
'end_summary' => 'Σταματά τον αυτοματισμό εδώ',
'fetch_rss' => 'Ανάκτηση RSS',
'http_request' => 'Αίτημα HTTP',
'handles' => [
'items' => 'έχει στοιχεία',
'no_items' => 'κανένα στοιχείο',
],
],
'config' => [
'select_placeholder' => 'Επιλέξτε…',
'invalid_json' => 'Αυτό δεν είναι ακόμη έγκυρο JSON.',
'expand_editor' => 'Ανάπτυξη επεξεργαστή',
'minimize_editor' => 'Ελαχιστοποίηση',
'trigger' => [
'type' => 'Τύπος εναύσματος',
'types' => [
'schedule' => 'Χρονοδιάγραμμα',
'post_published' => 'Όταν δημοσιεύεται μια δημοσίευση',
'post_scheduled' => 'Όταν προγραμματίζεται μια δημοσίευση',
],
'post_published_hint' => 'Εκτελείται κάθε φορά που δημοσιεύεται οποιαδήποτε δημοσίευση σε αυτό το workspace. Η δημοσιευμένη δημοσίευση γίνεται διαθέσιμη στο {{ trigger.post }} για τους επόμενους κόμβους.',
'post_scheduled_hint' => 'Εκτελείται κάθε φορά που προγραμματίζεται οποιαδήποτε δημοσίευση σε αυτό το workspace. Η προγραμματισμένη δημοσίευση είναι διαθέσιμη στο {{ trigger.post }}.',
'schedule' => [
'field' => 'Διάστημα εναύσματος',
'fields' => [
'minutes' => 'Λεπτά',
'hours' => 'Ώρες',
'days' => 'Ημέρες',
'weeks' => 'Εβδομάδες',
'months' => 'Μήνες',
],
'minutes_interval' => 'Λεπτά μεταξύ εναυσμάτων',
'hours_interval' => 'Ώρες μεταξύ εναυσμάτων',
'days_interval' => 'Ημέρες μεταξύ εναυσμάτων',
'hour' => 'Έναυσμα στην ώρα',
'minute' => 'Έναυσμα στο λεπτό',
'weekdays' => 'Έναυσμα σε ημέρες της εβδομάδας',
'day_of_month' => 'Ημέρα του μήνα',
'weekday_names' => [
'sun' => 'Κυρ',
'mon' => 'Δευ',
'tue' => 'Τρί',
'wed' => 'Τετ',
'thu' => 'Πέμ',
'fri' => 'Παρ',
'sat' => 'Σάβ',
],
'summary' => [
'every_n_minutes' => 'Εκτελείται κάθε λεπτό|Εκτελείται κάθε :count λεπτά',
'every_n_hours' => 'Εκτελείται κάθε ώρα στο λεπτό :minute|Εκτελείται κάθε :count ώρες στο λεπτό :minute',
'every_n_days' => 'Εκτελείται κάθε ημέρα στις :time|Εκτελείται κάθε :count ημέρες στις :time',
'weekly' => 'Εκτελείται κάθε :days στις :time',
'monthly' => 'Εκτελείται την ημέρα :day κάθε μήνα στις :time',
],
],
],
'generate' => [
'social_accounts' => 'Λογαριασμοί κοινωνικών δικτύων',
'social_accounts_empty' => 'Δεν υπάρχουν συνδεδεμένοι λογαριασμοί κοινωνικών δικτύων. Συνδέστε πρώτα έναν.',
'target_slide_count' => 'Slides προς δημιουργία',
'prompt_template' => 'Πρότυπο prompt',
'prompt_template_hint' => 'Πληκτρολογήστε {{ για εισαγωγή δεδομένων από προηγούμενα βήματα.',
'image_count' => 'Εικόνες προς δημιουργία',
'image_count_hint' => '0 = δημοσίευση μόνο με κείμενο (χωρίς εικόνα). 1 = μία εικόνα. 2+ = carousel.',
'use_brand_voice' => 'Χρήση φωνής μάρκας',
'use_brand_voice_hint' => 'Εφαρμόστε την περιγραφή και τη φωνή της μάρκας σας. Απενεργοποιήστε το για πιστή επιμέλεια πηγών τρίτων (ειδήσεις, RSS).',
'use_brand_visuals' => 'Χρήση οπτικών στοιχείων μάρκας',
'use_brand_visuals_hint' => 'Κατευθύνετε τις εικόνες AI με τα χρώματα και την ταυτότητα της μάρκας σας. Απενεργοποιήστε το για ουδέτερες εικόνες που καθορίζονται μόνο από το θέμα της δημοσίευσης.',
'style' => 'Ύφος',
'account_summary' => ':count λογαριασμός · :format|:count λογαριασμοί · :format',
'formats' => [
'single' => 'μεμονωμένο',
'carousel' => 'carousel',
],
],
'delay' => [
'duration' => 'Διάρκεια',
'unit' => 'Μονάδα',
'units' => [
'minutes' => 'Λεπτά',
'hours' => 'Ώρες',
'days' => 'Ημέρες',
],
],
'condition' => [
'field' => 'Πεδίο',
'operator' => 'Τελεστής',
'operators' => [
'contains' => 'περιέχει',
'not_contains' => 'δεν περιέχει',
'equals' => 'ισούται με',
'not_equals' => 'δεν ισούται με',
'matches' => 'ταιριάζει (regex)',
'greater_than' => 'μεγαλύτερο από',
'less_than' => 'μικρότερο από',
],
'value' => 'Τιμή',
],
'publish' => [
'mode' => 'Λειτουργία',
'modes' => [
'now' => 'Δημοσίευση τώρα',
'scheduled' => 'Χρονοδιάγραμμα',
'draft' => 'Αποθήκευση ως πρόχειρο',
],
'scheduled_offset' => 'Μετατόπιση από το έναυσμα (λεπτά)',
'offset_summary' => ':mode · +:offset λεπτά',
],
'webhook' => [
'url' => 'URL',
'method' => 'Μέθοδος',
'payload_template' => 'Πρότυπο payload (JSON)',
],
'end' => [
'reason' => 'Αιτία (προαιρετικό)',
'reason_placeholder' => 'π.χ. Φιλτραρίστηκε από τη συνθήκη',
],
'fetch_rss' => [
'feed_url' => 'URL ροής',
'feed_url_hint' => 'Στην πρώτη εκτέλεση, το σημείο ελέγχου ορίζεται στο «τώρα» ώστε τα παλαιότερα στοιχεία να μην πλημμυρίσουν τους επόμενους κόμβους. Οι επόμενες εκτελέσεις βλέπουν μόνο στοιχεία νεότερα από το προηγούμενο poll.',
'inspect' => 'Επιθεώρηση ροής',
'inspecting' => 'Επιθεώρηση…',
'inspect_hint' => 'Ανακτήστε ένα δείγμα για να ανακαλύψετε τα διαθέσιμα πεδία προς χρήση στους επόμενους κόμβους.',
'inspect_error' => 'Δεν ήταν δυνατή η ανάγνωση αυτής της ροής. Ελέγξτε τη διεύθυνση URL και δοκιμάστε ξανά.',
'discovered_fields' => 'Διαθέσιμα πεδία',
'discovered_empty' => 'Δεν βρέθηκαν πεδία στο πιο πρόσφατο στοιχείο.',
],
'http_request' => [
'url' => 'URL',
'method' => 'Μέθοδος',
'auth_type' => 'Ταυτοποίηση',
'auth' => [
'none' => 'Καμία (δημόσιο)',
'bearer' => 'Bearer token',
'basic' => 'Basic auth',
'api_key' => 'Κεφαλίδα κλειδιού API',
],
'bearer_token' => 'Bearer token',
'basic_username' => 'Όνομα χρήστη',
'basic_password' => 'Κωδικός πρόσβασης',
'api_key_header' => 'Όνομα κεφαλίδας',
'api_key_value' => 'Κλειδί API',
'body_template' => 'Πρότυπο σώματος (JSON)',
'headers' => 'Κεφαλίδες',
'header_name' => 'Όνομα κεφαλίδας',
'header_value' => 'Τιμή',
'add_header' => 'Προσθήκη κεφαλίδας',
'polling_section' => 'Λίστα και αφαίρεση διπλότυπων (προαιρετικό)',
'polling_hint' => 'Όταν η απόκριση είναι λίστα, κάθε στοιχείο εκτελεί τη ροή εργασίας ξεχωριστά. Ένα μεμονωμένο αντικείμενο εκτελείται μία φορά.',
'items_path' => 'Διαδρομή στοιχείων',
'items_path_hint' => 'Αφήστε το κενό αν η απόκριση είναι ήδη πίνακας. Χρησιμοποιήστε διαδρομή με τελείες (π.χ. data.items) για εμφωλευμένο πίνακα ή * για αντικείμενο με κλειδί το id.',
'item_key_path' => 'Διαδρομή κλειδιού στοιχείου',
'item_key_path_hint' => 'Διαδρομή JSON προς ένα μοναδικό id (π.χ. id). Τα στοιχεία που έχουν ήδη εμφανιστεί παραλείπονται, ώστε μια ροή χωρίς ημερομηνίες να προωθεί μόνο νέες καταχωρίσεις.',
'item_date_path' => 'Διαδρομή ημερομηνίας στοιχείου',
'item_date_path_hint' => 'Διαδρομή JSON προς τη χρονική σήμανση του στοιχείου (π.χ. published_at). Προτιμάται έναντι της διαδρομής κλειδιού όταν είναι διαθέσιμη. Το πρώτο poll καταγράφει τη γραμμή βάσης και δεν προωθεί τίποτα, ώστε μια υπάρχουσα ροή να μην πλημμυρίζει την πρώτη ημέρα.',
],
],
'delete' => [
'title' => 'Διαγραφή αυτοματισμού',
'description' => 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον αυτοματισμό; Όλες οι εκτελέσεις και τα στοιχεία εναύσματος θα αφαιρεθούν επίσης. Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.',
'confirm' => 'Διαγραφή',
'cancel' => 'Ακύρωση',
],
'flash' => [
'deleted' => 'Ο αυτοματισμός διαγράφηκε με επιτυχία!',
],
'errors' => [
'no_active_social_accounts' => 'Δεν έχουν ρυθμιστεί ενεργοί λογαριασμοί κοινωνικών δικτύων για αυτόν τον αυτοματισμό.',
'must_have_one_trigger' => 'Ο αυτοματισμός πρέπει να έχει ακριβώς έναν κόμβο εναύσματος.',
'trigger_must_be_connected' => 'Ο κόμβος εναύσματος πρέπει να είναι συνδεδεμένος με τουλάχιστον έναν κόμβο.',
'graph_contains_cycle' => 'Το γράφημα του αυτοματισμού περιέχει κύκλο.',
'only_failed_can_retry' => 'Μόνο οι αποτυχημένες εκτελέσεις μπορούν να επαναληφθούν.',
'no_generated_post' => 'Δεν βρέθηκε δημιουργημένη δημοσίευση στην εκτέλεση.',
'webhook_server_error' => 'Σφάλμα διακομιστή webhook.',
'webhook_request_failed' => 'Το αίτημα webhook δεν ήταν δυνατό να ολοκληρωθεί.',
'webhook_missing_url' => 'Από τον κόμβο webhook λείπει μια διεύθυνση URL.',
'webhook_invalid_payload_json' => 'Το πρότυπο payload δεν είναι έγκυρο JSON.',
'url_not_allowed' => 'Η διεύθυνση URL του αιτήματος δείχνει σε ιδιωτική ή μη προσβάσιμη διεύθυνση και αποκλείστηκε.',
'node_no_longer_exists' => 'Ο κόμβος :node_id δεν υπάρχει πλέον στον αυτοματισμό.',
'no_trigger_connection' => 'Κανένας κόμβος δεν είναι συνδεδεμένος με τον κόμβο εναύσματος.',
'fetch_rss_missing_url' => 'Από τον κόμβο Ανάκτησης RSS λείπει μια διεύθυνση URL ροής.',
'fetch_rss_request_failed' => 'Το αίτημα της ροής RSS απέτυχε.',
'fetch_rss_malformed' => 'Η ροή RSS είναι δυσμορφική.',
'http_missing_url' => 'Από τον κόμβο αιτήματος HTTP λείπει μια διεύθυνση URL.',
'http_request_exception' => 'Το αίτημα HTTP προκάλεσε εξαίρεση.',
'http_request_failed' => 'Το αίτημα HTTP απέτυχε.',
'http_items_path_not_array' => 'Η διαδρομή στοιχείων δεν αντιστοιχήθηκε σε λίστα.',
],
];

76
lang/el/billing.php Normal file
View file

@ -0,0 +1,76 @@
<?php
return [
'title' => 'Χρέωση',
'past_due_notice' => [
'title' => 'Ληξιπρόθεσμη πληρωμή',
'description' => 'Ενημερώστε τη μέθοδο πληρωμής σας για να διατηρήσετε ενεργή τη συνδρομή σας.',
'cta' => 'Ενημέρωση πληρωμής',
],
'annual_banner' => [
'title' => 'Κερδίστε 2 μήνες δωρεάν',
'description' => 'Μεταβείτε σε ετήσια χρέωση και πληρώνετε λιγότερα κάθε μήνα — ίδιο πρόγραμμα, τίποτα άλλο δεν αλλάζει.',
'cta' => 'Αναβάθμιση σε ετήσιο',
],
'subscribe' => [
'billed_monthly' => 'Μηνιαία χρέωση',
'billed_yearly' => 'Ετήσια χρέωση',
'prices' => [
'workspace' => ['monthly' => '$12', 'yearly_per_month' => '$10', 'yearly' => '$120'],
],
],
'plan' => [
'title' => 'Πρόγραμμα',
'description' => 'Διαχειριστείτε το πρόγραμμα συνδρομής σας.',
'label' => 'Πρόγραμμα',
'workspaces' => '{1}:count workspace|[2,*]:count workspaces',
'per_workspace' => 'ανά workspace',
'price' => 'Τιμή',
'month' => 'μήνας',
'trial' => 'Δοκιμαστική περίοδος',
'active' => 'Ενεργό',
'past_due' => 'Ληξιπρόθεσμο',
'cancelling' => 'Ακυρώνεται',
'trial_ends' => 'Η δοκιμαστική περίοδος λήγει',
],
'subscription' => [
'title' => 'Συνδρομή',
'description' => 'Διαχειριστείτε τη μέθοδο πληρωμής, τα στοιχεία χρέωσης και τη συνδρομή σας.',
'payment_method' => 'Μέθοδος πληρωμής',
'no_payment_method' => 'Δεν υπάρχει καταχωρημένη μέθοδος πληρωμής ακόμη.',
'expires_on' => 'Λήγει :month/:year',
'manage_label' => 'Συνδρομή',
'manage_stripe' => 'Διαχείριση στο Stripe',
],
'invoices' => [
'title' => 'Τιμολόγια',
'description' => 'Κατεβάστε τα προηγούμενα τιμολόγιά σας.',
'empty' => 'Δεν βρέθηκαν τιμολόγια',
'paid' => 'Πληρωμένο',
],
'flash' => [
'plan_changed' => 'Είστε πλέον στο πρόγραμμα :plan.',
'switched_to_yearly' => 'Είστε πλέον σε ετήσια χρέωση.',
'cannot_manage' => 'Μόνο ο κάτοχος του λογαριασμού μπορεί να διαχειρίζεται τη χρέωση.',
'credits_exhausted' => 'Εξαντλήθηκαν τα credits AI — το μηνιαίο σας όριο των :limit έχει χρησιμοποιηθεί. Αναβαθμίστε το πρόγραμμά σας ή περιμένετε μέχρι τον επόμενο μήνα.',
'subscription_required' => 'Απαιτείται ενεργή συνδρομή για τη χρήση των λειτουργιών AI.',
],
'processing' => [
'page_title' => 'Επεξεργασία...',
'title' => 'Επεξεργασία της συνδρομής σας',
'description' => 'Παρακαλούμε περιμένετε όσο ρυθμίζουμε τον λογαριασμό σας. Θα πάρει μόνο μια στιγμή.',
'success_title' => 'Είστε έτοιμοι!',
'success_description' => 'Η συνδρομή σας είναι ενεργή. Σας ανακατευθύνουμε στα workspaces σας...',
'cancelled_title' => 'Η πληρωμή ακυρώθηκε',
'cancelled_description' => 'Η πληρωμή σας ακυρώθηκε. Δεν έγινε καμία χρέωση.',
'retry' => 'Δοκιμάστε ξανά',
],
];

39
lang/el/brands.php Normal file
View file

@ -0,0 +1,39 @@
<?php
return [
'new_brand' => 'Νέα μάρκα',
'no_brands_yet' => 'Δεν υπάρχουν μάρκες ακόμη',
'no_brands_description' => 'Δημιουργήστε μάρκες για να οργανώσετε τους λογαριασμούς κοινωνικών δικτύων σας ανά πελάτη ή έργο',
'accounts_count' => ':count λογαριασμοί',
'create' => [
'title' => 'Δημιουργία μάρκας',
'description' => 'Δώστε ένα όνομα στη μάρκα σας για να ομαδοποιήσετε λογαριασμούς κοινωνικών δικτύων',
'name' => 'Όνομα μάρκας',
'name_placeholder' => 'π.χ. Acme Corp, Προσωπική',
'submit' => 'Δημιουργία μάρκας',
'submitting' => 'Δημιουργία...',
],
'edit' => [
'title' => 'Επεξεργασία μάρκας',
'description' => 'Ενημερώστε το όνομα αυτής της μάρκας',
'name' => 'Όνομα μάρκας',
'name_placeholder' => 'π.χ. Acme Corp, Προσωπική',
'submit' => 'Αποθήκευση αλλαγών',
'submitting' => 'Αποθήκευση...',
],
'delete' => [
'title' => 'Διαγραφή μάρκας',
'description' => 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτή τη μάρκα; Οι λογαριασμοί κοινωνικών δικτύων θα αποδεσμευτούν αλλά δεν θα διαγραφούν.',
'confirm' => 'Διαγραφή',
'cancel' => 'Ακύρωση',
],
'flash' => [
'created' => 'Η μάρκα δημιουργήθηκε με επιτυχία!',
'updated' => 'Η μάρκα ενημερώθηκε με επιτυχία!',
'deleted' => 'Η μάρκα διαγράφηκε με επιτυχία!',
],
];

12
lang/el/calendar.php Normal file
View file

@ -0,0 +1,12 @@
<?php
return [
'title' => 'Ημερολόγιο',
'today' => 'Σήμερα',
'day' => 'Ημέρα',
'week' => 'Εβδομάδα',
'month' => 'Μήνας',
'new_post' => 'Νέα δημοσίευση',
'no_content' => 'Χωρίς περιεχόμενο',
'more' => '+:count ακόμη',
];

Some files were not shown because too many files have changed in this diff Show more