Skip to content

Commit f091b0b

Browse files
authored
Merge pull request #17 from LexaFrontDev/dev
Dev
2 parents 15f3114 + 65edb32 commit f091b0b

17 files changed

Lines changed: 539 additions & 329 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ php bin/console doctrine:migrations:migrate -n
6060
### 5. Load fixtures
6161

6262
```bash
63-
php bin/console doctrine:fixtures:load
63+
php bin/console app:resources:sync
6464
exit
6565
```
6666

README.ru.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ php bin/console doctrine:migrations:migrate -n
5858
### 5. Загрузка фикстур
5959

6060
```bash
61-
php bin/console doctrine:fixtures:load
61+
php bin/console app:resources:sync
6262
exit
6363
```
6464

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Aplication\Dto\ResourceDto;
4+
5+
final class BenefitsDto
6+
{
7+
/**
8+
* @param string $title Заголовок преимущества
9+
* @param string $desc Описание преимущества
10+
* @param string $icon Путь к иконке
11+
*/
12+
public function __construct(
13+
public readonly string $title,
14+
public readonly string $desc,
15+
public readonly string $icon,
16+
) {
17+
}
18+
19+
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace App\Aplication\Dto\ResourceDto;
4+
5+
final class FaqDto
6+
{
7+
public function __construct(
8+
public readonly string $question,
9+
public readonly string $answer,
10+
) {
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace App\Aplication\Dto\ResourceDto;
4+
5+
final class HabitsTemplatesDto
6+
{
7+
public function __construct(
8+
public readonly string $title,
9+
public readonly string $quote,
10+
public readonly string $notification,
11+
public readonly string $datesType,
12+
) {
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace App\Aplication\Dto\ResourceDto;
4+
5+
final class LanguageDto
6+
{
7+
public function __construct(
8+
public readonly string $name,
9+
public readonly string $prefix,
10+
) {
11+
}
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace App\Aplication\Dto\ResourceDto;
4+
5+
final class PremiumPlansDto
6+
{
7+
/**
8+
* @param string[] $features
9+
*/
10+
public function __construct(
11+
public readonly string $name,
12+
public readonly string $desc,
13+
public readonly string $price,
14+
public readonly array $features,
15+
public readonly bool $highlight,
16+
) {
17+
}
18+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace App\Aplication\UseCase\ResourceUseCase;
4+
5+
use App\Domain\Exception\Message\MessageException;
6+
use App\Domain\Resource\v1_resourses\DatabaseResources;
7+
use App\Domain\Service\ResourceService\ResourceSyncInterface;
8+
9+
class CommandResourceUseCase
10+
{
11+
public function __construct(
12+
private ResourceSyncInterface $resourceSync,
13+
private DatabaseResources $databaseResources,
14+
) {
15+
}
16+
17+
public function saveResources(): void
18+
{
19+
$this->sync('языки', [$this->databaseResources, 'getLanguages'], [$this->resourceSync, 'setLanguage']);
20+
$this->sync('переводы', [$this->databaseResources, 'getTranslates'], [$this->resourceSync, 'setTranslation']);
21+
$this->sync('планы', [$this->databaseResources, 'getPremiumPlans'], [$this->resourceSync, 'setPremiumPlans']);
22+
$this->sync('шаблоны привычек', [$this->databaseResources, 'getHabitsTemplates'], [$this->resourceSync, 'setHabitsTemplates']);
23+
$this->sync('FAQ', [$this->databaseResources, 'getFaq'], [$this->resourceSync, 'setFaq']);
24+
$this->sync('бенефиты', [$this->databaseResources, 'getBenefits'], [$this->resourceSync, 'setBenefits']);
25+
}
26+
27+
private function sync(string $name, callable $getData, callable $setData): void
28+
{
29+
$data = $getData();
30+
$result = $setData($data);
31+
32+
if (empty($result)) {
33+
throw new MessageException("Не удалось сохранить $name, результат: ".json_encode($result));
34+
}
35+
}
36+
}

src/Infrastructure/DataFixtures/V1Fixtures/LanguagePageTranslationFixture.php renamed to src/Domain/Resource/v1_resourses/DatabaseResources.php

Lines changed: 149 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
<?php
22

3-
namespace App\Infrastructure\DataFixtures\V1Fixtures;
3+
namespace App\Domain\Resource\v1_resourses;
44

5-
use App\Domain\Entity\Language\Language;
6-
use App\Domain\Entity\Language\LanguagePageTranslation;
7-
use Doctrine\Bundle\FixturesBundle\Fixture;
8-
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
9-
use Doctrine\Persistence\ObjectManager;
5+
use App\Aplication\Dto\ResourceDto\BenefitsDto;
6+
use App\Aplication\Dto\ResourceDto\FaqDto;
7+
use App\Aplication\Dto\ResourceDto\HabitsTemplatesDto;
8+
use App\Aplication\Dto\ResourceDto\LanguageDto;
9+
use App\Aplication\Dto\ResourceDto\PremiumPlansDto;
1010

11-
class LanguagePageTranslationFixture extends Fixture implements DependentFixtureInterface
11+
class DatabaseResources
1212
{
13-
public function load(ObjectManager $manager): void
13+
/**
14+
* @return LanguageDto[]
15+
*/
16+
public function getLanguages(): array
1417
{
15-
$languages = [
16-
'ru' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'ru']),
17-
'en' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'en']),
18-
'kz' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'kz']),
19-
'de' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'de']),
20-
'kg' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'kg']),
21-
'uz' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'uz']),
22-
'ko' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'ko']),
23-
'ja' => $manager->getRepository(Language::class)->findOneBy(['prefix' => 'ja']),
18+
return [
19+
new LanguageDto(name: 'Русский', prefix: 'ru'),
20+
new LanguageDto(name: 'English', prefix: 'en'),
21+
new LanguageDto(name: 'Қазақ тілі', prefix: 'kz'),
22+
new LanguageDto(name: 'Deutsch', prefix: 'de'),
23+
new LanguageDto(name: 'Кыргыз тили', prefix: 'kg'),
24+
new LanguageDto(name: 'O‘zbek tili', prefix: 'uz'),
25+
new LanguageDto(name: '한국어', prefix: 'ko'),
26+
new LanguageDto(name: '日本語', prefix: 'ja'),
2427
];
28+
}
2529

26-
$v1_translate_site = [
30+
/**
31+
* @return array<string, array<string, array<string, string>>>
32+
*/
33+
public function getTranslates(): array
34+
{
35+
return [
2736
'landing' => [
2837
'loginButtonText' => [
2938
'ru' => 'Войти', 'en' => 'Login', 'kz' => 'Кіру',
@@ -751,72 +760,140 @@ public function load(ObjectManager $manager): void
751760
],
752761

753762
];
763+
}
754764

755-
756-
757-
$this->createTranslation('v1_translate_site', $v1_translate_site, $languages, $manager);
758-
$manager->flush();
765+
/**
766+
* @return PremiumPlansDto[]
767+
*/
768+
public function getPremiumPlans(): array
769+
{
770+
return [
771+
new PremiumPlansDto(
772+
name: 'Free',
773+
desc: 'Базовые функции для старта',
774+
price: '0₸ / мес',
775+
features: ['20 задач в день', '5 привычек', 'Матрица Эйзенхауэра', 'Помодоро', 'Базовый Кастомный фон'],
776+
highlight: true,
777+
),
778+
new PremiumPlansDto(
779+
name: 'Pro',
780+
desc: 'Для продуктивной работы',
781+
price: '999₸ / мес',
782+
features: [
783+
'50 задач в день',
784+
'50 привычек',
785+
'Кастомный фон',
786+
'ИИ-помощник',
787+
'канбан',
788+
'Больше звуков для помодора',
789+
'полный Кастомный фон и возможность добавлять свой фоны',
790+
],
791+
highlight: true,
792+
),
793+
new PremiumPlansDto(
794+
name: 'Pro Год',
795+
desc: 'Экономия и приоритет',
796+
price: '9 999₸ / год',
797+
features: ['Всё из Pro', 'Приоритетная поддержка'],
798+
highlight: true,
799+
),
800+
];
759801
}
760802

761803
/**
762-
* @param array<string, array<string, array<string, string>>> $translations
763-
* @param array<string, Language|null> $languages
804+
* @return HabitsTemplatesDto[]
764805
*/
765-
private function createTranslation(
766-
string $pageName,
767-
array $translations,
768-
array $languages,
769-
ObjectManager $manager,
770-
): void {
771-
foreach ($languages as $prefix => $language) {
772-
if (!$language) {
773-
continue;
774-
}
775-
776-
$pageTranslate = $this->extractTranslationsForLanguage($translations, $prefix);
777-
$existing = $manager->getRepository(LanguagePageTranslation::class)
778-
->findOneBy(['pageName' => $pageName]);
779-
780-
if ($existing) {
781-
continue;
782-
}
783-
784-
$translation = new LanguagePageTranslation();
785-
$translation->setPageName($pageName);
786-
$translation->setPageTranslate($pageTranslate);
787-
$translation->setLanguage($language);
788-
789-
$manager->persist($translation);
790-
}
806+
public function getHabitsTemplates(): array
807+
{
808+
return [
809+
new HabitsTemplatesDto(
810+
title: 'Ранний подъем',
811+
quote: 'Кто рано встает, тому Бог дает!',
812+
notification: '06:30',
813+
datesType: 'daily',
814+
),
815+
new HabitsTemplatesDto(
816+
title: 'Утренняя пробежка',
817+
quote: 'Бег - это жизнь!',
818+
notification: '10:30',
819+
datesType: 'daily',
820+
),
821+
new HabitsTemplatesDto(
822+
title: 'Чтение книги',
823+
quote: 'Книги - корабли мысли',
824+
notification: '16:30',
825+
datesType: 'daily',
826+
),
827+
new HabitsTemplatesDto(
828+
title: 'Медитация',
829+
quote: 'Тишина - великий учитель',
830+
notification: '14:30',
831+
datesType: 'daily',
832+
),
833+
];
791834
}
792835

793836
/**
794-
* @param array<string, mixed> $translations
795-
*
796-
* @return array<string, string>
837+
* @return FaqDto[]
797838
*/
798-
private function extractTranslationsForLanguage(array $translations, string $languageCode): array
839+
public function getFaq(): array
799840
{
800-
$result = [];
801-
802-
foreach ($translations as $key => $value) {
803-
if (is_array($value)) {
804-
if (isset($value[$languageCode]) && is_string($value[$languageCode])) {
805-
$result[$key] = $value[$languageCode];
806-
} else {
807-
$nested = $this->extractTranslationsForLanguage($value, $languageCode);
808-
foreach ($nested as $nestedKey => $nestedValue) {
809-
$result[$key.'.'.$nestedKey] = $nestedValue;
810-
}
811-
}
812-
}
813-
}
814-
815-
return $result;
841+
return [
842+
new FaqDto(
843+
question: 'Можно ли вернуть деньги после покупки?',
844+
answer: 'Да, вы можете оформить возврат в течение 14 дней после оплаты. Просто отправьте нам запрос через раздел "Обратная связь" в приложении. Если вы оформили подписку через App Store или Google Play, отмену и возврат необходимо оформить через соответствующую платформу.',
845+
),
846+
new FaqDto(
847+
question: 'Что будет с моими данными, если я не продлю подписку?',
848+
answer: 'Мы не удалим ваши привычки, задачи и статистику. Всё останется сохранено. Если количество привычек превышает лимит бесплатной версии, привычки с низким приоритетом будут автоматически перемещены в архив. Доступ к премиум-функциям будет временно ограничен до продления подписки.',
849+
),
850+
new FaqDto(
851+
question: 'Как отменить подписку?',
852+
answer: 'Если вы оформили подписку через Google Play или App Store — откройте соответствующее приложение, перейдите в раздел "Подписки" и отмените TaskFlow PremiumUseCases. Если подписка оформлена напрямую, просто напишите нам через "Обратная связь".',
853+
),
854+
new FaqDto(
855+
question: 'Что делать, если остались вопросы?',
856+
answer: 'Напишите нам в поддержку через приложение или на почту support@taskflow.app. Мы всегда готовы помочь!',
857+
),
858+
];
816859
}
817860

818-
public function getDependencies(): array
861+
/**
862+
* @return BenefitsDto[]
863+
*/
864+
public function getBenefits(): array
819865
{
820-
return [LanguageFixture::class];
866+
return [
867+
new BenefitsDto(
868+
title: 'ИИ помогает достигать целей',
869+
desc: 'Интеллектуальный помощник подсказывает приоритеты и экономит время',
870+
icon: '/icons/ai.svg',
871+
),
872+
new BenefitsDto(
873+
title: '50 привычек и задач в день',
874+
desc: 'Достаточно, чтобы охватить все сферы жизни',
875+
icon: '/icons/checklist.svg',
876+
),
877+
new BenefitsDto(
878+
title: 'Кастомный календарь',
879+
desc: 'Гибкий инструмент под твоё расписание и стиль',
880+
icon: '/icons/calendar.svg',
881+
),
882+
new BenefitsDto(
883+
title: 'Система рейтингов',
884+
desc: 'Соревнуйся с собой и другими',
885+
icon: '/icons/rating.svg',
886+
),
887+
new BenefitsDto(
888+
title: 'Темы и настройка',
889+
desc: 'Темная/светлая тема, фоны, звуки и многое другое',
890+
icon: '/icons/theme.svg',
891+
),
892+
new BenefitsDto(
893+
title: 'Уведомления и напоминания',
894+
desc: 'Никогда не пропусти важную задачу',
895+
icon: '/icons/bell.svg',
896+
),
897+
];
821898
}
822899
}

0 commit comments

Comments
 (0)