Compare commits
6 Commits
01cbaab498
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 19a9014f61 | |||
| 2cc52a3fab | |||
| 4c832549f2 | |||
| 3f7369fc86 | |||
| d77046194a | |||
| 6f1d93fc07 |
87
AGENTS.md
Normal file
87
AGENTS.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
This file provides guidance to WARP (warp.dev) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
CGR App - A Next.js 16 admin dashboard application with internationalization (i18n) support for English, German, and Russian. Uses React 19, TypeScript, Tailwind CSS v4, and shadcn/ui components.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
# Run dev server via Docker (preferred)
|
||||||
|
make run
|
||||||
|
|
||||||
|
# Or directly with npm
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build & Lint
|
||||||
|
```bash
|
||||||
|
npm run build # Production build
|
||||||
|
npm run lint # ESLint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Operations
|
||||||
|
```bash
|
||||||
|
make run # Start dev container (docker-compose.yml)
|
||||||
|
make stop # Stop containers
|
||||||
|
make logs # View container logs
|
||||||
|
make build # Rebuild container
|
||||||
|
|
||||||
|
# Production deployment (uses docker-compose.prod.yml)
|
||||||
|
make ENV=prod deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding Dependencies
|
||||||
|
```bash
|
||||||
|
# Install npm package via Docker
|
||||||
|
make i package=<package-name>
|
||||||
|
|
||||||
|
# Add shadcn/ui component via Docker
|
||||||
|
make ui component=<component-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### App Router Structure
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── layout.tsx # Root layout (pass-through for i18n)
|
||||||
|
├── [locale]/ # Dynamic locale segment (en, de, ru)
|
||||||
|
│ ├── layout.tsx # Main layout with providers (Theme, i18n)
|
||||||
|
│ └── (backend)/ # Route group for admin dashboard
|
||||||
|
│ ├── layout.tsx # Dashboard shell (Sidebar + Header)
|
||||||
|
│ ├── page.tsx # Overview page
|
||||||
|
│ ├── admin/
|
||||||
|
│ └── users/
|
||||||
|
│ └── components/ # Page-specific components
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Patterns
|
||||||
|
|
||||||
|
**Internationalization (next-intl)**
|
||||||
|
- Routing config: `i18n/routing.ts` defines supported locales
|
||||||
|
- Request handler: `i18n/request.ts` loads messages dynamically
|
||||||
|
- Navigation: Use `@/i18n/navigation` exports (`Link`, `useRouter`, `usePathname`) for locale-aware navigation
|
||||||
|
- Messages: JSON files in `messages/` directory (`en.json`, `de.json`, `ru.json`)
|
||||||
|
|
||||||
|
**Component Organization**
|
||||||
|
- `components/ui/` - shadcn/ui primitives (new-york style, RSC enabled)
|
||||||
|
- `components/` - App-specific components (Header, Sidebar, etc.)
|
||||||
|
- Page-specific components live under their route: `app/[locale]/(backend)/users/components/`
|
||||||
|
|
||||||
|
**Providers Hierarchy** (in `app/[locale]/layout.tsx`)
|
||||||
|
```
|
||||||
|
ThemeProvider (next-themes) → NextIntlClientProvider → children
|
||||||
|
```
|
||||||
|
|
||||||
|
### Path Aliases
|
||||||
|
- `@/*` maps to project root (e.g., `@/components`, `@/lib/utils`, `@/hooks`)
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
|
||||||
|
- Tailwind CSS v4 with CSS variables for theming
|
||||||
|
- `cn()` utility from `lib/utils.ts` for conditional class merging
|
||||||
|
- Global styles in `app/globals.css`
|
||||||
@@ -14,7 +14,10 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
|||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
const getPageTitle = (path: string) => {
|
const getPageTitle = (path: string) => {
|
||||||
if (path === "/") return "Overview";
|
const pathSegments = path.split("/").filter(Boolean);
|
||||||
|
|
||||||
|
if (pathSegments.length <= 1) return "Overview";
|
||||||
|
const purePath = `/${pathSegments.slice(1).join("/")}`;
|
||||||
|
|
||||||
const titles: Record<string, string> = {
|
const titles: Record<string, string> = {
|
||||||
"/users": "Users",
|
"/users": "Users",
|
||||||
@@ -24,7 +27,8 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
|||||||
"/events": "Worship & Events",
|
"/events": "Worship & Events",
|
||||||
};
|
};
|
||||||
|
|
||||||
return titles[path] || "Dashboard";
|
return titles[purePath] || "Dashboard";
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
32
app/[locale]/(backend)/lib/dailyVerseData.ts
Normal file
32
app/[locale]/(backend)/lib/dailyVerseData.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// Local data storage for development without DB
|
||||||
|
// Each object represents a verse for a specific day
|
||||||
|
export interface localizedContent {
|
||||||
|
en: string;
|
||||||
|
de: string;
|
||||||
|
ru: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BibleVerse {
|
||||||
|
reference: string;
|
||||||
|
content: localizedContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const bibleVerses: BibleVerse[] = [
|
||||||
|
{
|
||||||
|
reference: "Epheser 2:19-22",
|
||||||
|
content: {
|
||||||
|
en: "So then you are no longer strangers and aliens, but you are fellow citizens with the saints and members of the household of God, built on the foundation of the apostles and prophets, Christ Jesus himself being the cornerstone, in whom the whole structure, being joined together, grows into a holy temple in the Lord. In him you also are being built together into a dwelling place for God by the Spirit.",
|
||||||
|
de: "So seid ihr nun nicht mehr Gäste und Fremdlinge, sondern Mitbürger der Heiligen und Gottes Hausgenossen, erbaut auf den Grund der Apostel und Propheten, da Jesus Christus der Eckstein ist, auf welchem der ganze Bau ineinandergefügt wächst zu einem heiligen Tempel in dem Herrn. Durch ihn werdet auch ihr mit erbaut zu einer Wohnung Gottes im Geist.",
|
||||||
|
ru: "Итак, вы уже не чужие и не пришельцы, но сограждане святым и свои Богу, быв утверждены на основании Апостолов и пророков, имея Самого Иисуса Христа краеугольным камнем, на котором всё здание, слагаясь стройно, возрастает в святой храм в Господе, на котором и вы устрояетесь в жилище Божие Духом."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reference: "Psalm 23:1",
|
||||||
|
content: {
|
||||||
|
en: "The Lord is my shepherd...",
|
||||||
|
de: "Der Herr ist mein Hirte...",
|
||||||
|
ru: "Господь — Пастырь мой..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// Add as many as you want here
|
||||||
|
];
|
||||||
@@ -22,11 +22,27 @@ import {
|
|||||||
Users,
|
Users,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
|
import { useParams } from "next/navigation";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { bibleVerses, localizedContent } from "./lib/dailyVerseData";
|
||||||
|
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
const Dashboard: React.FC = () => {
|
const Dashboard: React.FC = () => {
|
||||||
|
// 1. Get a unique number for the current day
|
||||||
|
const today = new Date();
|
||||||
|
today.setHours(0, 0, 0, 0); // Normalize to midnight
|
||||||
|
const dayTimestamp = today.getTime();
|
||||||
|
|
||||||
|
// 2. Use the timestamp to get a consistent index
|
||||||
|
// The modulo (%) operator ensures the index is always within array bounds
|
||||||
|
const verseIndex = dayTimestamp % bibleVerses.length;
|
||||||
|
const todayVerse = bibleVerses[verseIndex];
|
||||||
|
const params = useParams();
|
||||||
|
const lng = params.locale as keyof localizedContent || "en"; // Default to English if no locale is provided
|
||||||
const t = useTranslations("dashboard");
|
const t = useTranslations("dashboard");
|
||||||
|
|
||||||
const categories: ModuleCategory[] = [
|
const categories: ModuleCategory[] = [
|
||||||
{
|
{
|
||||||
title: "People & Community",
|
title: "People & Community",
|
||||||
@@ -169,19 +185,23 @@ const Dashboard: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="mx-auto max-w-7xl space-y-8">
|
<div className="mx-auto max-w-7xl space-y-8">
|
||||||
{/* Welcome Section */}
|
{/* Welcome Section */}
|
||||||
<div className="flex flex-col justify-between gap-4 md:flex-row md:items-center">
|
<div data-cmp="ModuleCard" className="group bg-card border border-border rounded-xl p-6 h-full overflow-hidden">
|
||||||
<div>
|
<div className="animate-in items-baseline fade-in slide-in-from-bottom-4 duration-700 flex flex-col sm:flex-row grow pr-6 gap-2">
|
||||||
<h1 className="text-foreground text-3xl font-bold tracking-tight">
|
<span className="text-2xl md:text-3xl text-nowrap font-semibold leading-none">{t("greeting_name", { user: "Alexander" })}</span>
|
||||||
{t("title")}
|
<span className="text-xl font-semibold text-nowrap leading-none"> {t("greeting")}</span>
|
||||||
</h1>
|
|
||||||
<p className="text-muted-foreground mt-1">{t("welcome")}</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex space-x-3">
|
<div className="flex-col mt-4">
|
||||||
<Badge variant="secondary" className="px-2.5 py-0.5 text-sm">
|
<p>
|
||||||
v2.4.0 Live
|
<span className="font-semibold">{t("verse_intro")}</span> <br />
|
||||||
|
<i className="italic text-foreground">"{todayVerse.content[lng]}"</i>
|
||||||
|
</p>
|
||||||
|
<div className="flex justify-end mt-3">
|
||||||
|
<Badge variant="outline" className="rounded-sm self-start">
|
||||||
|
{todayVerse.reference}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Quick Stats */}
|
{/* Quick Stats */}
|
||||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-3">
|
||||||
|
|||||||
168
app/globals.css
168
app/globals.css
@@ -44,72 +44,114 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.625rem;
|
--radius: 0.125rem;
|
||||||
--background: oklch(1 0 0);
|
/* ---------- Base background (warm light) ---------- */
|
||||||
--foreground: oklch(0.129 0.042 264.695);
|
--background: oklch(0.97 0.01 95);
|
||||||
--card: oklch(1 0 0);
|
--foreground: oklch(0.22 0.02 30);
|
||||||
--card-foreground: oklch(0.129 0.042 264.695);
|
|
||||||
--popover: oklch(1 0 0);
|
/* ---------- Surfaces ---------- */
|
||||||
--popover-foreground: oklch(0.129 0.042 264.695);
|
--card: oklch(0.99 0.005 95);
|
||||||
--primary: oklch(0.208 0.042 265.755);
|
--card-foreground: oklch(0.22 0.02 30);
|
||||||
--primary-foreground: oklch(0.984 0.003 247.858);
|
|
||||||
--secondary: oklch(0.968 0.007 247.896);
|
--popover: oklch(1 0.004 95);
|
||||||
--secondary-foreground: oklch(0.208 0.042 265.755);
|
--popover-foreground: oklch(0.22 0.02 30);
|
||||||
--muted: oklch(0.968 0.007 247.896);
|
|
||||||
--muted-foreground: oklch(0.554 0.046 257.417);
|
/* ---------- Ubuntu orange primary ---------- */
|
||||||
--accent: oklch(0.968 0.007 247.896);
|
--primary: oklch(0.62 0.2 45);
|
||||||
--accent-foreground: oklch(0.208 0.042 265.755);
|
--primary-foreground: oklch(0.99 0.005 95);
|
||||||
--destructive: oklch(0.577 0.245 27.325);
|
|
||||||
--border: oklch(0.929 0.013 255.508);
|
/* ---------- Secondary / muted warm grays ---------- */
|
||||||
--input: oklch(0.929 0.013 255.508);
|
--secondary: oklch(0.92 0.01 90);
|
||||||
--ring: oklch(0.704 0.04 256.788);
|
--secondary-foreground: oklch(0.3 0.02 35);
|
||||||
--chart-1: oklch(0.646 0.222 41.116);
|
|
||||||
--chart-2: oklch(0.6 0.118 184.704);
|
--muted: oklch(0.94 0.008 90);
|
||||||
--chart-3: oklch(0.398 0.07 227.392);
|
--muted-foreground: oklch(0.45 0.015 35);
|
||||||
--chart-4: oklch(0.828 0.189 84.429);
|
|
||||||
--chart-5: oklch(0.769 0.188 70.08);
|
--accent: oklch(0.9 0.015 85);
|
||||||
--sidebar: oklch(0.984 0.003 247.858);
|
--accent-foreground: oklch(0.3 0.02 35);
|
||||||
--sidebar-foreground: oklch(0.129 0.042 264.695);
|
|
||||||
--sidebar-primary: oklch(0.208 0.042 265.755);
|
/* ---------- Destructive ---------- */
|
||||||
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
--destructive: oklch(0.58 0.23 25);
|
||||||
--sidebar-accent: oklch(0.968 0.007 247.896);
|
|
||||||
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
|
/* ---------- Borders / inputs ---------- */
|
||||||
--sidebar-border: oklch(0.929 0.013 255.508);
|
--border: oklch(0.85 0.01 90);
|
||||||
--sidebar-ring: oklch(0.704 0.04 256.788);
|
--input: oklch(0.88 0.01 90);
|
||||||
|
--ring: oklch(0.62 0.2 45 / 0.5);
|
||||||
|
|
||||||
|
/* ---------- Charts ---------- */
|
||||||
|
--chart-1: oklch(0.62 0.2 45); /* orange */
|
||||||
|
--chart-2: oklch(0.55 0.16 150); /* green */
|
||||||
|
--chart-3: oklch(0.7 0.17 85); /* yellow */
|
||||||
|
--chart-4: oklch(0.6 0.18 300); /* purple */
|
||||||
|
--chart-5: oklch(0.6 0.2 20); /* red */
|
||||||
|
|
||||||
|
/* ---------- Sidebar ---------- */
|
||||||
|
--sidebar: oklch(0.95 0.01 90);
|
||||||
|
--sidebar-foreground: oklch(0.28 0.02 30);
|
||||||
|
|
||||||
|
--sidebar-primary: oklch(0.62 0.2 45);
|
||||||
|
--sidebar-primary-foreground: oklch(0.99 0.005 95);
|
||||||
|
|
||||||
|
--sidebar-accent: oklch(0.9 0.015 85);
|
||||||
|
--sidebar-accent-foreground: oklch(0.3 0.02 35);
|
||||||
|
|
||||||
|
--sidebar-border: oklch(0.85 0.01 90);
|
||||||
|
--sidebar-ring: oklch(0.62 0.2 45 / 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: oklch(0.129 0.042 264.695);
|
/* ---------- Base background (warm charcoal) ---------- */
|
||||||
--foreground: oklch(0.984 0.003 247.858);
|
--background: oklch(0.11 0.015 30);
|
||||||
--card: oklch(0.208 0.042 265.755);
|
--foreground: oklch(0.97 0.01 95);
|
||||||
--card-foreground: oklch(0.984 0.003 247.858);
|
|
||||||
--popover: oklch(0.208 0.042 265.755);
|
/* ---------- Surfaces ---------- */
|
||||||
--popover-foreground: oklch(0.984 0.003 247.858);
|
--card: oklch(0.16 0.018 32);
|
||||||
--primary: oklch(0.929 0.013 255.508);
|
--card-foreground: oklch(0.97 0.01 95);
|
||||||
--primary-foreground: oklch(0.208 0.042 265.755);
|
|
||||||
--secondary: oklch(0.279 0.041 260.031);
|
--popover: oklch(0.18 0.02 32);
|
||||||
--secondary-foreground: oklch(0.984 0.003 247.858);
|
--popover-foreground: oklch(0.97 0.01 95);
|
||||||
--muted: oklch(0.279 0.041 260.031);
|
|
||||||
--muted-foreground: oklch(0.704 0.04 256.788);
|
/* ---------- Ubuntu orange primary ---------- */
|
||||||
--accent: oklch(0.279 0.041 260.031);
|
--primary: oklch(0.68 0.19 45);
|
||||||
--accent-foreground: oklch(0.984 0.003 247.858);
|
--primary-foreground: oklch(0.98 0.01 95);
|
||||||
--destructive: oklch(0.704 0.191 22.216);
|
|
||||||
--border: oklch(1 0 0 / 10%);
|
/* ---------- Secondary / muted warm grays ---------- */
|
||||||
--input: oklch(1 0 0 / 15%);
|
--secondary: oklch(0.22 0.02 30);
|
||||||
--ring: oklch(0.551 0.027 264.364);
|
--secondary-foreground: oklch(0.92 0.015 95);
|
||||||
--chart-1: oklch(0.488 0.243 264.376);
|
|
||||||
--chart-2: oklch(0.696 0.17 162.48);
|
--muted: oklch(0.22 0.02 30);
|
||||||
--chart-3: oklch(0.769 0.188 70.08);
|
--muted-foreground: oklch(0.68 0.02 90);
|
||||||
--chart-4: oklch(0.627 0.265 303.9);
|
|
||||||
--chart-5: oklch(0.645 0.246 16.439);
|
--accent: oklch(0.26 0.025 35);
|
||||||
--sidebar: oklch(0.208 0.042 265.755);
|
--accent-foreground: oklch(0.95 0.01 95);
|
||||||
--sidebar-foreground: oklch(0.984 0.003 247.858);
|
|
||||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
/* ---------- Destructive (Ubuntu red tone) ---------- */
|
||||||
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
--destructive: oklch(0.62 0.22 25);
|
||||||
--sidebar-accent: oklch(0.279 0.041 260.031);
|
|
||||||
--sidebar-accent-foreground: oklch(0.984 0.003 247.858);
|
/* ---------- Borders / inputs ---------- */
|
||||||
--sidebar-border: oklch(1 0 0 / 10%);
|
--border: oklch(0.3 0.015 35 / 0.6);
|
||||||
--sidebar-ring: oklch(0.551 0.027 264.364);
|
--input: oklch(0.3 0.015 35 / 0.8);
|
||||||
|
--ring: oklch(0.68 0.19 45 / 0.6);
|
||||||
|
|
||||||
|
/* ---------- Charts ---------- */
|
||||||
|
--chart-1: oklch(0.68 0.19 45); /* orange */
|
||||||
|
--chart-2: oklch(0.7 0.15 150); /* green */
|
||||||
|
--chart-3: oklch(0.78 0.16 85); /* yellow */
|
||||||
|
--chart-4: oklch(0.66 0.18 300); /* purple */
|
||||||
|
--chart-5: oklch(0.7 0.18 20); /* red */
|
||||||
|
|
||||||
|
/* ---------- Sidebar (slightly darker & warmer) ---------- */
|
||||||
|
--sidebar: oklch(0.14 0.018 30);
|
||||||
|
--sidebar-foreground: oklch(0.95 0.01 95);
|
||||||
|
|
||||||
|
--sidebar-primary: oklch(0.68 0.19 45);
|
||||||
|
--sidebar-primary-foreground: oklch(0.98 0.01 95);
|
||||||
|
|
||||||
|
--sidebar-accent: oklch(0.24 0.02 32);
|
||||||
|
--sidebar-accent-foreground: oklch(0.95 0.01 95);
|
||||||
|
|
||||||
|
--sidebar-border: oklch(0.3 0.015 35 / 0.5);
|
||||||
|
--sidebar-ring: oklch(0.68 0.19 45 / 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === CUSTOM COLOR THEME === */
|
/* === CUSTOM COLOR THEME === */
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ interface HeaderProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Header: React.FC<HeaderProps> = ({ onMenuClick, pageTitle }) => {
|
const Header: React.FC<HeaderProps> = ({ onMenuClick, pageTitle }) => {
|
||||||
|
const [hasError, setHasError] = React.useState(false);
|
||||||
return (
|
return (
|
||||||
<header
|
<header
|
||||||
data-cmp="Header"
|
data-cmp="Header"
|
||||||
@@ -55,9 +56,19 @@ const Header: React.FC<HeaderProps> = ({ onMenuClick, pageTitle }) => {
|
|||||||
<p className="text-foreground text-sm font-medium">Community Admin</p>
|
<p className="text-foreground text-sm font-medium">Community Admin</p>
|
||||||
<p className="text-muted-foreground text-xs">Super Administrator</p>
|
<p className="text-muted-foreground text-xs">Super Administrator</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-primary/10 border-primary/20 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border">
|
{hasError ? (
|
||||||
<User className="text-primary h-5 w-5" />
|
<div className="w-10 h-10 rounded-full border border-border bg-muted flex items-center justify-center">
|
||||||
|
<User className="w-6 h-6 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<img
|
||||||
|
src="/images/IMG_84271.jpg"
|
||||||
|
alt="Profile"
|
||||||
|
className="w-10 h-10 rounded-full object-cover border border-border"
|
||||||
|
/* If image fails to load, set hasError to true */
|
||||||
|
onError={() => setHasError(true)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -10,7 +10,10 @@
|
|||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"title": "Community-Dashboard",
|
"title": "Community-Dashboard",
|
||||||
"welcome": "Willkommen im Admin-Bereich. Verwalten Sie Ihre Community-Ressourcen sicher."
|
"welcome": "Willkommen im Admin-Bereich. Verwalten Sie Ihre Community-Ressourcen sicher.",
|
||||||
|
"greeting_name": "Lieber Bruder {user},",
|
||||||
|
"greeting": "Friede sei mit Dir!",
|
||||||
|
"verse_intro": "Zur Ermutigung:"
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"title": "Benutzer",
|
"title": "Benutzer",
|
||||||
|
|||||||
@@ -10,6 +10,13 @@
|
|||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"title": "Community Dashboard",
|
"title": "Community Dashboard",
|
||||||
"welcome": "Welcome to the admin area. Manage your community resources safely."
|
"welcome": "Welcome to the admin area. Manage your community resources safely.",
|
||||||
|
"greeting_name": "Dear brother {user},",
|
||||||
|
"greeting": "peace be with you!",
|
||||||
|
"verse_intro": "For encouragement:"
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"title": "Users",
|
||||||
|
"welcome": "Manage your community members, roles, and permissions here."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,10 @@
|
|||||||
},
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"title": "Community Dashboard",
|
"title": "Community Dashboard",
|
||||||
"welcome": "Добро пожаловать в административный раздел. Безопасно управляйте ресурсами вашего сообщества."
|
"welcome": "Добро пожаловать в административный раздел. Безопасно управляйте ресурсами вашего сообщества.",
|
||||||
|
"greeting_name": "Дорогой брат {user},",
|
||||||
|
"greeting": "мир Тебе!",
|
||||||
|
"verse_intro": "Для ободрения:"
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"title": "Пользователи",
|
"title": "Пользователи",
|
||||||
|
|||||||
BIN
public/images/IMG_84271.jpg
Normal file
BIN
public/images/IMG_84271.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 143 KiB |
Reference in New Issue
Block a user