Merge branch 'centralEmailDB'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@ yarn-error.log
|
|||||||
/.nova
|
/.nova
|
||||||
/.vscode
|
/.vscode
|
||||||
/.zed
|
/.zed
|
||||||
|
/stripe.exe
|
||||||
|
|||||||
47
app/ColorPicker.php
Normal file
47
app/ColorPicker.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
trait ColorPicker
|
||||||
|
{
|
||||||
|
public static function chooseColor($letter): array
|
||||||
|
{
|
||||||
|
$colorReferences = [
|
||||||
|
"A" => ["dark" => "dark:bg-amber-500", "light" => "bg-amber-800"],
|
||||||
|
"B" => ["dark" => "dark:bg-blue-500", "light" => "bg-blue-800"],
|
||||||
|
"C" => ["dark" => "dark:bg-cyan-500", "light" => "bg-cyan-800"],
|
||||||
|
"D" => ["dark" => "dark:bg-emerald-500", "light" => "bg-emerald-800"],
|
||||||
|
"E" => ["dark" => "dark:bg-fuchsia-500", "light" => "bg-fuchsia-800"],
|
||||||
|
"F" => ["dark" => "dark:bg-gray-500", "light" => "bg-gray-800"],
|
||||||
|
"G" => ["dark" => "dark:bg-green-500", "light" => "bg-green-800"],
|
||||||
|
"H" => ["dark" => "dark:bg-indigo-500", "light" => "bg-indigo-800"],
|
||||||
|
"I" => ["dark" => "dark:bg-lime-500", "light" => "bg-lime-800"],
|
||||||
|
"J" => ["dark" => "dark:bg-neutral-500", "light" => "bg-neutral-800"],
|
||||||
|
"K" => ["dark" => "dark:bg-orange-500", "light" => "bg-orange-800"],
|
||||||
|
"L" => ["dark" => "dark:bg-pink-500", "light" => "bg-pink-800"],
|
||||||
|
"M" => ["dark" => "dark:bg-purple-500", "light" => "bg-purple-800"],
|
||||||
|
"N" => ["dark" => "dark:bg-red-500", "light" => "bg-red-800"],
|
||||||
|
"O" => ["dark" => "dark:bg-rose-500", "light" => "bg-rose-800"],
|
||||||
|
"P" => ["dark" => "dark:bg-sky-500", "light" => "bg-sky-800"],
|
||||||
|
"Q" => ["dark" => "dark:bg-slate-500", "light" => "bg-slate-800"],
|
||||||
|
"R" => ["dark" => "dark:bg-stone-500", "light" => "bg-stone-800"],
|
||||||
|
"S" => ["dark" => "dark:bg-teal-500", "light" => "bg-teal-800"],
|
||||||
|
"T" => ["dark" => "dark:bg-violet-500", "light" => "bg-violet-800"],
|
||||||
|
"U" => ["dark" => "dark:bg-yellow-500", "light" => "bg-yellow-800"],
|
||||||
|
"V" => ["dark" => "dark:bg-zinc-500", "light" => "bg-zinc-800"],
|
||||||
|
"W" => ["dark" => "dark:bg-neutral-500", "light" => "bg-neutral-800"],
|
||||||
|
"X" => ["dark" => "dark:bg-slate-500", "light" => "bg-slate-800"],
|
||||||
|
"Y" => ["dark" => "dark:bg-stone-500", "light" => "bg-stone-800"],
|
||||||
|
"Z" => ["dark" => "dark:bg-teal-500", "light" => "bg-teal-800"]
|
||||||
|
];
|
||||||
|
|
||||||
|
$letter = strtoupper($letter);
|
||||||
|
|
||||||
|
if (isset($colorReferences[$letter])) {
|
||||||
|
return $colorReferences[$letter];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ["dark" => "dark:bg-gray-500", "light" => "bg-gray-800"];
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
150
app/Filament/Resources/BlogResource.php
Normal file
150
app/Filament/Resources/BlogResource.php
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\BlogResource\Pages;
|
||||||
|
use App\Filament\Resources\BlogResource\RelationManagers;
|
||||||
|
use App\Models\Blog;
|
||||||
|
use App\Models\Category;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\FileUpload;
|
||||||
|
use Filament\Forms\Components\KeyValue;
|
||||||
|
use Filament\Forms\Components\Repeater;
|
||||||
|
use Filament\Forms\Components\RichEditor;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\Textarea;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\RelationManagers\RelationManager;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
use Filament\Forms\Set;
|
||||||
|
use Filament\Tables\Columns\IconColumn;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Filters\SelectFilter;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class BlogResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Blog::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-m-newspaper';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Content';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
$categories = Category::pluck('name', 'id')->toArray();
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
Section::make('Post Information')
|
||||||
|
->description('Add a new post')
|
||||||
|
->schema([
|
||||||
|
TextInput::make('post')->label('Post Title')
|
||||||
|
->required()
|
||||||
|
->live(1)
|
||||||
|
->columnSpanFull()
|
||||||
|
->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))),
|
||||||
|
|
||||||
|
TextInput::make('slug')
|
||||||
|
->required()
|
||||||
|
->columnSpan(2),
|
||||||
|
|
||||||
|
Select::make('category_id')
|
||||||
|
->relationship('category', 'name')
|
||||||
|
->label('Category')
|
||||||
|
->searchable()
|
||||||
|
->required()
|
||||||
|
->preload(10)
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
Select::make('is_published')
|
||||||
|
->options([
|
||||||
|
0 => 'Draft',
|
||||||
|
1 => 'Published'
|
||||||
|
])
|
||||||
|
->searchable()
|
||||||
|
->default(1)
|
||||||
|
->required()
|
||||||
|
->label('Status')
|
||||||
|
->columnSpan(1),
|
||||||
|
|
||||||
|
RichEditor::make('content')
|
||||||
|
->label('Page Content')
|
||||||
|
->columnSpan(4),
|
||||||
|
|
||||||
|
FileUpload::make('post_image')
|
||||||
|
->label('Custom Image (Optional)')
|
||||||
|
->directory('media/posts')
|
||||||
|
->columnSpan(4)
|
||||||
|
->preserveFilenames()
|
||||||
|
->image()
|
||||||
|
->maxSize(2048),
|
||||||
|
])
|
||||||
|
->columns(4),
|
||||||
|
|
||||||
|
Section::make('Customize Post')
|
||||||
|
->description('Modifiy Post SEO and Meta Information')
|
||||||
|
->schema([
|
||||||
|
KeyValue::make('meta')
|
||||||
|
->label('Meta (Optional)')
|
||||||
|
->keyPlaceholder('Name')
|
||||||
|
->valuePlaceholder('Content'),
|
||||||
|
Textarea::make('custom_header')->rows(6)->label('Custom Header (Optional)'),
|
||||||
|
|
||||||
|
|
||||||
|
]),
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('post')->searchable(),
|
||||||
|
TextColumn::make('slug'),
|
||||||
|
TextColumn::make('category.name'),
|
||||||
|
IconColumn::make('is_published')->label('Published')->boolean(),
|
||||||
|
TextColumn::make('created_at')
|
||||||
|
->label('Created At'),
|
||||||
|
])
|
||||||
|
->defaultSort('created_at', 'desc')
|
||||||
|
->filters([
|
||||||
|
SelectFilter::make('is_published')
|
||||||
|
->label('Status')
|
||||||
|
->options([
|
||||||
|
0 => 'Draft',
|
||||||
|
1 => 'Published',
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListBlogs::route('/'),
|
||||||
|
'create' => Pages\CreateBlog::route('/create'),
|
||||||
|
'edit' => Pages\EditBlog::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Filament/Resources/BlogResource/Pages/CreateBlog.php
Normal file
21
app/Filament/Resources/BlogResource/Pages/CreateBlog.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\BlogResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\BlogResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateBlog extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = BlogResource::class;
|
||||||
|
|
||||||
|
protected function getCreatedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Post created')
|
||||||
|
->body('Post created successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Filament/Resources/BlogResource/Pages/EditBlog.php
Normal file
32
app/Filament/Resources/BlogResource/Pages/EditBlog.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\BlogResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\BlogResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditBlog extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = BlogResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
protected function getRedirectUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->getResource()::getUrl('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSavedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Post updated')
|
||||||
|
->body('Post updated successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Filament/Resources/BlogResource/Pages/ListBlogs.php
Normal file
19
app/Filament/Resources/BlogResource/Pages/ListBlogs.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\BlogResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\BlogResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListBlogs extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = BlogResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
86
app/Filament/Resources/CategoryResource.php
Normal file
86
app/Filament/Resources/CategoryResource.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CategoryResource\Pages;
|
||||||
|
use App\Filament\Resources\CategoryResource\RelationManagers;
|
||||||
|
use App\Models\Category;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
use Filament\Forms\Set;
|
||||||
|
use Filament\Tables\Columns\IconColumn;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class CategoryResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Category::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-ticket';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Content';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
TextInput::make('name')
|
||||||
|
->required()
|
||||||
|
->live(1)
|
||||||
|
->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))),
|
||||||
|
TextInput::make('slug')->required(),
|
||||||
|
Select::make('is_active')
|
||||||
|
->options([
|
||||||
|
0 => 'Inactive',
|
||||||
|
1 => 'Active',
|
||||||
|
])
|
||||||
|
->columnSpanFull()
|
||||||
|
->required()
|
||||||
|
->default(1)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('name'),
|
||||||
|
TextColumn::make('slug'),
|
||||||
|
IconColumn::make('is_active')->label('Active')->boolean(),
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListCategories::route('/'),
|
||||||
|
'create' => Pages\CreateCategory::route('/create'),
|
||||||
|
'edit' => Pages\EditCategory::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CategoryResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CategoryResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateCategory extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = CategoryResource::class;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CategoryResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CategoryResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditCategory extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = CategoryResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\CategoryResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\CategoryResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListCategories extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = CategoryResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
90
app/Filament/Resources/MenuResource.php
Normal file
90
app/Filament/Resources/MenuResource.php
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\MenuResource\Pages;
|
||||||
|
use App\Filament\Resources\MenuResource\RelationManagers;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Columns\IconColumn;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
|
||||||
|
class MenuResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Menu::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-bars-3-bottom-left';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Content';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
$menus = Menu::Pluck('name', 'id')->toArray();
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
TextInput::make('name')
|
||||||
|
->label('Menu Name')
|
||||||
|
->required(),
|
||||||
|
TextInput::make('url')
|
||||||
|
->label('URL')
|
||||||
|
->url()
|
||||||
|
->required(),
|
||||||
|
Select::make('parent')
|
||||||
|
->options($menus)
|
||||||
|
->searchable()
|
||||||
|
->columnSpanFull()
|
||||||
|
->label('Parents (Optional)'),
|
||||||
|
Toggle::make('new_tab')
|
||||||
|
->default(1)
|
||||||
|
->label('Open in new tab'),
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('name'),
|
||||||
|
TextColumn::make('url')->label('URL'),
|
||||||
|
TextColumn::make('parentname.name')->label('Parent Name'),
|
||||||
|
IconColumn::make('new_tab')->label('Open in New Tab')->boolean()
|
||||||
|
])
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListMenus::route('/'),
|
||||||
|
'create' => Pages\CreateMenu::route('/create'),
|
||||||
|
'edit' => Pages\EditMenu::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Filament/Resources/MenuResource/Pages/CreateMenu.php
Normal file
21
app/Filament/Resources/MenuResource/Pages/CreateMenu.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\MenuResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\MenuResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreateMenu extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = MenuResource::class;
|
||||||
|
|
||||||
|
protected function getCreatedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Menu created')
|
||||||
|
->body('Menu created successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Filament/Resources/MenuResource/Pages/EditMenu.php
Normal file
32
app/Filament/Resources/MenuResource/Pages/EditMenu.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\MenuResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\MenuResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditMenu extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = MenuResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
protected function getRedirectUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->getResource()::getUrl('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSavedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Menu updated')
|
||||||
|
->body('Menu updated successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Filament/Resources/MenuResource/Pages/ListMenus.php
Normal file
19
app/Filament/Resources/MenuResource/Pages/ListMenus.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\MenuResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\MenuResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListMenus extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = MenuResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
131
app/Filament/Resources/PageResource.php
Normal file
131
app/Filament/Resources/PageResource.php
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PageResource\Pages;
|
||||||
|
use App\Filament\Resources\PageResource\RelationManagers;
|
||||||
|
use App\Models\Page;
|
||||||
|
use Filament\Forms;
|
||||||
|
use Filament\Forms\Components\FileUpload;
|
||||||
|
use Filament\Forms\Components\KeyValue;
|
||||||
|
use Filament\Forms\Components\Repeater;
|
||||||
|
use Filament\Forms\Components\RichEditor;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\Textarea;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Forms\Components\Toggle;
|
||||||
|
use Filament\Forms\Form;
|
||||||
|
use Filament\Forms\Set;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Columns\IconColumn;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||||
|
use Symfony\Contracts\Service\Attribute\Required;
|
||||||
|
|
||||||
|
class PageResource extends Resource
|
||||||
|
{
|
||||||
|
protected static ?string $model = Page::class;
|
||||||
|
|
||||||
|
protected static ?string $navigationIcon = 'heroicon-o-document';
|
||||||
|
|
||||||
|
protected static ?string $navigationGroup = 'Content';
|
||||||
|
|
||||||
|
public static function form(Form $form): Form
|
||||||
|
{
|
||||||
|
$pages = Page::Pluck('title', 'id')->toArray();
|
||||||
|
|
||||||
|
return $form
|
||||||
|
->schema([
|
||||||
|
|
||||||
|
Section::make('Page Information')
|
||||||
|
->description('Add a new page')
|
||||||
|
->schema([
|
||||||
|
TextInput::make('title')->label('Page Title')
|
||||||
|
->required()
|
||||||
|
->live(1)
|
||||||
|
->columnSpanFull()
|
||||||
|
->afterStateUpdated(fn (Set $set, ?string $state) => $set('slug', Str::slug($state))),
|
||||||
|
TextInput::make('slug')->required()->columnSpan(3),
|
||||||
|
Select::make('is_published')
|
||||||
|
->options([
|
||||||
|
0 => 'Draft',
|
||||||
|
1 => 'Published'
|
||||||
|
])
|
||||||
|
->default(1)
|
||||||
|
->required()
|
||||||
|
->searchable()
|
||||||
|
->label('Status')
|
||||||
|
->columnSpan(1),
|
||||||
|
RichEditor::make('content')->label('Page Content')->columnSpanFull(),
|
||||||
|
FileUpload::make('page_image')
|
||||||
|
->label('Custom Image (Optional)')
|
||||||
|
->directory('media/pages')
|
||||||
|
->columnSpanFull()
|
||||||
|
->preserveFilenames()
|
||||||
|
->image()
|
||||||
|
->maxSize(2048),
|
||||||
|
])
|
||||||
|
->columns(4),
|
||||||
|
|
||||||
|
Section::make('Customize Page')
|
||||||
|
->description('Modifiy Page SEO and Meta Information')
|
||||||
|
->schema([
|
||||||
|
KeyValue::make('meta')
|
||||||
|
->label('Meta (Optional)')
|
||||||
|
->keyPlaceholder('Name')
|
||||||
|
->valuePlaceholder('Content')
|
||||||
|
->reorderable(),
|
||||||
|
Select::make('parent')->options($pages)->label('Parents (Optional)'),
|
||||||
|
Textarea::make('custom_header')->rows(6)->label('Custom Header (Optional)'),
|
||||||
|
]),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function table(Table $table): Table
|
||||||
|
{
|
||||||
|
return $table
|
||||||
|
->columns([
|
||||||
|
TextColumn::make('title')->searchable(),
|
||||||
|
TextColumn::make('slug'),
|
||||||
|
IconColumn::make('is_published')->label('Published')->boolean(),
|
||||||
|
TextColumn::make('created_at')
|
||||||
|
->label('Created At'),
|
||||||
|
])
|
||||||
|
->defaultSort('created_at', 'desc')
|
||||||
|
->filters([
|
||||||
|
//
|
||||||
|
])
|
||||||
|
->actions([
|
||||||
|
Tables\Actions\EditAction::make(),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Tables\Actions\BulkActionGroup::make([
|
||||||
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getRelations(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPages(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'index' => Pages\ListPages::route('/'),
|
||||||
|
'create' => Pages\CreatePage::route('/create'),
|
||||||
|
'edit' => Pages\EditPage::route('/{record}/edit'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
21
app/Filament/Resources/PageResource/Pages/CreatePage.php
Normal file
21
app/Filament/Resources/PageResource/Pages/CreatePage.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PageResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PageResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
|
|
||||||
|
class CreatePage extends CreateRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = PageResource::class;
|
||||||
|
|
||||||
|
protected function getCreatedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Page created')
|
||||||
|
->body('Page created successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Filament/Resources/PageResource/Pages/EditPage.php
Normal file
32
app/Filament/Resources/PageResource/Pages/EditPage.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PageResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PageResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
|
use Filament\Resources\Pages\EditRecord;
|
||||||
|
|
||||||
|
class EditPage extends EditRecord
|
||||||
|
{
|
||||||
|
protected static string $resource = PageResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\DeleteAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
protected function getRedirectUrl(): ?string
|
||||||
|
{
|
||||||
|
return $this->getResource()::getUrl('index');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSavedNotification(): ?Notification
|
||||||
|
{
|
||||||
|
return Notification::make()
|
||||||
|
->success()
|
||||||
|
->title('Page updated')
|
||||||
|
->body('Page updated successfully');
|
||||||
|
}
|
||||||
|
}
|
||||||
19
app/Filament/Resources/PageResource/Pages/ListPages.php
Normal file
19
app/Filament/Resources/PageResource/Pages/ListPages.php
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Resources\PageResource\Pages;
|
||||||
|
|
||||||
|
use App\Filament\Resources\PageResource;
|
||||||
|
use Filament\Actions;
|
||||||
|
use Filament\Resources\Pages\ListRecords;
|
||||||
|
|
||||||
|
class ListPages extends ListRecords
|
||||||
|
{
|
||||||
|
protected static string $resource = PageResource::class;
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Actions\CreateAction::make(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,10 @@ class AppController extends Controller
|
|||||||
{
|
{
|
||||||
public function mailbox($email = null) {
|
public function mailbox($email = null) {
|
||||||
if ($email) {
|
if ($email) {
|
||||||
|
$validatedData = validator(['email' => $email], [
|
||||||
|
'email' => 'required|email',
|
||||||
|
])->validate();
|
||||||
|
|
||||||
if (json_decode(config('app.settings.configuration_settings'))->enable_create_from_url) {
|
if (json_decode(config('app.settings.configuration_settings'))->enable_create_from_url) {
|
||||||
ZEmail::createCustomEmailFull($email);
|
ZEmail::createCustomEmailFull($email);
|
||||||
}
|
}
|
||||||
@@ -26,6 +30,32 @@ class AppController extends Controller
|
|||||||
public function app() {
|
public function app() {
|
||||||
return redirect()->route('home');
|
return redirect()->route('home');
|
||||||
}
|
}
|
||||||
|
public function switch($email) {
|
||||||
|
ZEmail::setEmail($email);
|
||||||
|
if (json_decode(config('app.settings.configuration_settings'))->disable_mailbox_slug) {
|
||||||
|
return redirect()->route('home');
|
||||||
|
}
|
||||||
|
return redirect()->route('mailbox');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($email = null) {
|
||||||
|
if ($email) {
|
||||||
|
$emails = ZEmail::getEmails();
|
||||||
|
ZEmail::removeEmail($email);
|
||||||
|
return redirect()->route('mailbox');
|
||||||
|
} else {
|
||||||
|
return redirect()->route('home');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function locale($locale) {
|
||||||
|
if (in_array($locale, config('app.locales'))) {
|
||||||
|
session(['locale' => $locale]);
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
abort(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private function getStringBetween($string, $start, $end) {
|
private function getStringBetween($string, $start, $end) {
|
||||||
$string = ' ' . $string;
|
$string = ' ' . $string;
|
||||||
|
|||||||
40
app/Http/Middleware/CheckPageSlug.php
Normal file
40
app/Http/Middleware/CheckPageSlug.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class CheckPageSlug
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
$slug = $request->route('slug');
|
||||||
|
|
||||||
|
$publicPath = public_path($slug);
|
||||||
|
|
||||||
|
if (file_exists($publicPath) && is_file($publicPath) && pathinfo($slug, PATHINFO_EXTENSION) === 'php') {
|
||||||
|
ob_start();
|
||||||
|
include($publicPath);
|
||||||
|
$content = ob_get_clean();
|
||||||
|
ob_flush();
|
||||||
|
return response($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_exists($publicPath) && is_file($publicPath)) {
|
||||||
|
return response()->file($publicPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_dir($publicPath)) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/Http/Middleware/Locale.php
Normal file
28
app/Http/Middleware/Locale.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class Locale
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$locale = explode('-', explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE'])[0])[0];
|
||||||
|
if (in_array($locale, config('app.locales'))) {
|
||||||
|
session(['browser-locale' => $locale]);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
}
|
||||||
|
app()->setLocale(session('locale', session('browser-locale', config('app.settings.language', config('app.locale', 'en')))));
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/Livewire/Blog.php
Normal file
22
app/Livewire/Blog.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Blog extends Component
|
||||||
|
{
|
||||||
|
public $postDetail;
|
||||||
|
public $category;
|
||||||
|
|
||||||
|
public function mount($slug) {
|
||||||
|
$this->postDetail = \App\Models\Blog::where('slug', $slug)->firstOrFail();
|
||||||
|
$this->category = Category::where('id', $this->postDetail->category_id)->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.blog')->with('postDetail', $this->postDetail)->with('category', $this->category);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,8 +41,7 @@ class Action extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->email = ZEmail::createCustomEmail($this->username, $this->domain);
|
$this->email = ZEmail::createCustomEmail($this->username, $this->domain);
|
||||||
$this->dispatch('updateEmail');
|
return redirect()->route('mailbox');
|
||||||
$this->dispatch('closeModal');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public function random() {
|
public function random() {
|
||||||
@@ -50,10 +49,8 @@ class Action extends Component
|
|||||||
return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.'));
|
return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.'));
|
||||||
}
|
}
|
||||||
$this->email = ZEmail::generateRandomEmail();
|
$this->email = ZEmail::generateRandomEmail();
|
||||||
$this->dispatch('updateEmail');
|
|
||||||
$this->dispatch('closeModal');
|
|
||||||
|
|
||||||
//$this->redirect(route('mailbox'));
|
return redirect()->route('mailbox');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function gmail() {
|
public function gmail() {
|
||||||
@@ -61,21 +58,12 @@ class Action extends Component
|
|||||||
return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.'));
|
return $this->showAlert('error', __('You have reached daily limit of maximum ') . json_decode(config('app.settings.configuration_settings'))->email_limit . __(' temp mail addresses.'));
|
||||||
}
|
}
|
||||||
$this->email = ZEmail::generateRandomGmail();
|
$this->email = ZEmail::generateRandomGmail();
|
||||||
$this->dispatch('updateEmail');
|
return redirect()->route('mailbox');
|
||||||
$this->dispatch('closeModal');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deleteEmail(): void
|
public function deleteEmail()
|
||||||
{
|
{
|
||||||
ZEmail::removeEmail($this->email);
|
return redirect()->route('delete', ['email' => $this->email]);
|
||||||
// if (count($this->emails) <= 1 && json_decode(config('app.settings.configuration_settings'))->after_last_email_delete == 'redirect_to_homepage') {
|
|
||||||
// return redirect()->route('home');
|
|
||||||
// }
|
|
||||||
$this->email = ZEmail::getEmail(true);
|
|
||||||
$this->emails = ZEmail::getEmails();
|
|
||||||
|
|
||||||
$this->dispatch('updateEmail');
|
|
||||||
$this->dispatch('closeModal');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function showAlert($type, $message): void
|
private function showAlert($type, $message): void
|
||||||
|
|||||||
@@ -1,222 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire\Frontend;
|
|
||||||
|
|
||||||
use App\Models\Log;
|
|
||||||
use App\Models\ZEmail;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Support\Facades\Http;
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class ActionOld extends Component
|
|
||||||
{
|
|
||||||
public $in_app = false;
|
|
||||||
public $user, $domain, $domains, $email, $emails, $captcha;
|
|
||||||
|
|
||||||
protected $listeners = ['syncEmail', 'checkReCaptcha3'];
|
|
||||||
|
|
||||||
public function mount() {
|
|
||||||
$this->domains = config('app.settings.domains');
|
|
||||||
$this->email = ZEmail::getEmail();
|
|
||||||
$this->emails = ZEmail::getEmails();
|
|
||||||
$this->validateDomainInEmail();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function refreshMessages()
|
|
||||||
{
|
|
||||||
$this->emit('fetchMessages');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadMsg($email) {
|
|
||||||
$this->email = $email;
|
|
||||||
if (count($this->emails) == 0) {
|
|
||||||
$this->emails = [$email];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function syncEmail($email) {
|
|
||||||
$this->email = $email;
|
|
||||||
if (count($this->emails) == 0) {
|
|
||||||
$this->emails = [$email];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDomain($domain) {
|
|
||||||
$this->domain = $domain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkReCaptcha3($token, $action) {
|
|
||||||
$response = Http::post('https://www.google.com/recaptcha/api/siteverify?secret=' . config('app.settings.recaptcha3.secret_key') . '&response=' . $token);
|
|
||||||
$data = $response->json();
|
|
||||||
if ($data['success']) {
|
|
||||||
$captcha = $data['score'];
|
|
||||||
if ($captcha > 0.5) {
|
|
||||||
if ($action == 'create') {
|
|
||||||
$this->create();
|
|
||||||
} else {
|
|
||||||
$this->random();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return $this->showAlert('error', __('Captcha Failed! Please try again'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return $this->showAlert('error', __('Captcha Failed! Error: ') . json_encode($data['error-codes']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public function create() {
|
|
||||||
if (!$this->user) {
|
|
||||||
return $this->showAlert('error', __('Please enter Username'));
|
|
||||||
}
|
|
||||||
$this->checkDomainInUsername();
|
|
||||||
if (strlen($this->user) < config('app.settings.custom.min') || strlen($this->user) > config('app.settings.custom.max')) {
|
|
||||||
return $this->showAlert('error', __('Username length cannot be less than') . ' ' . config('app.settings.custom.min') . ' ' . __('and greater than') . ' ' . config('app.settings.custom.max'));
|
|
||||||
}
|
|
||||||
if (!$this->domain) {
|
|
||||||
return $this->showAlert('error', __('Please Select a Domain'));
|
|
||||||
}
|
|
||||||
if (in_array($this->user, config('app.settings.forbidden_ids'))) {
|
|
||||||
return $this->showAlert('error', __('Username not allowed'));
|
|
||||||
}
|
|
||||||
if (!$this->checkEmailLimit()) {
|
|
||||||
return $this->showAlert('error', __('You have reached daily limit of MAX ') . config('app.settings.email_limit', 5) . __(' temp mail'));
|
|
||||||
}
|
|
||||||
if (!$this->checkUsedEmail()) {
|
|
||||||
return $this->showAlert('error', __('Sorry! That email is already been used by someone else. Please try a different email address.'));
|
|
||||||
}
|
|
||||||
if (!$this->validateCaptcha()) {
|
|
||||||
return $this->showAlert('error', __('Invalid Captcha. Please try again'));
|
|
||||||
}
|
|
||||||
$this->email = ZEmail::createCustomEmail($this->user, $this->domain);
|
|
||||||
$this->redirect(route('mailbox'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function random() {
|
|
||||||
if (!$this->checkEmailLimit()) {
|
|
||||||
return $this->showAlert('error', __('You have reached daily limit of maximum ') . config('app.settings.email_limit', 5) . __(' temp mail addresses.'));
|
|
||||||
}
|
|
||||||
if (!$this->validateCaptcha()) {
|
|
||||||
return $this->showAlert('error', __('Invalid Captcha. Please try again'));
|
|
||||||
}
|
|
||||||
$this->email = ZEmail::generateRandomEmail();
|
|
||||||
$this->redirect(route('mailbox'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function tempgmail() {
|
|
||||||
if (!$this->checkEmailLimit()) {
|
|
||||||
return $this->showAlert('error', __('You have reached daily limit of maximum ') . config('app.settings.email_limit', 5) . __(' temp mail addresses.'));
|
|
||||||
}
|
|
||||||
if (!$this->validateCaptcha()) {
|
|
||||||
return $this->showAlert('error', __('Invalid Captcha. Please try again'));
|
|
||||||
}
|
|
||||||
$this->email = ZEmail::generateRandomGmail();
|
|
||||||
$this->redirect(route('mailbox'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteEmail() {
|
|
||||||
ZEmail::removeEmail($this->email);
|
|
||||||
if (count($this->emails) == 1 && config('app.settings.after_last_email_delete') == 'redirect_to_homepage') {
|
|
||||||
return redirect()->route('home');
|
|
||||||
}
|
|
||||||
$this->email = ZEmail::getEmail(true);
|
|
||||||
$this->emails = ZEmail::getEmails();
|
|
||||||
return redirect()->route('mailbox');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function render() {
|
|
||||||
if (count($this->emails) >= intval(config('app.settings.email_limit', 5))) {
|
|
||||||
for ($i = 0; $i < (count($this->emails) - intval(config('app.settings.email_limit', 5))); $i++) {
|
|
||||||
ZEmail::removeEmail($this->emails[$i]);
|
|
||||||
}
|
|
||||||
$this->emails = ZEmail::getEmails();
|
|
||||||
ZEmail::setEmail($this->email);
|
|
||||||
}
|
|
||||||
return view('livewire.frontend.action');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
private function showAlert($type, $message) {
|
|
||||||
$this->dispatchBrowserEvent('showAlert', ['type' => $type, 'message' => $message]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Don't allow used email
|
|
||||||
*/
|
|
||||||
private function checkUsedEmail() {
|
|
||||||
if (config('app.settings.disable_used_email', false)) {
|
|
||||||
$check = Log::where('email', $this->user . '@' . $this->domain)->where('ip', '<>', request()->ip())->count();
|
|
||||||
if ($check > 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate Captcha
|
|
||||||
*/
|
|
||||||
private function validateCaptcha() {
|
|
||||||
if (config('app.settings.captcha') == 'hcaptcha') {
|
|
||||||
$response = Http::asForm()->post('https://hcaptcha.com/siteverify', [
|
|
||||||
'response' => $this->captcha,
|
|
||||||
'secret' => config('app.settings.hcaptcha.secret_key')
|
|
||||||
])->object();
|
|
||||||
return $response->success;
|
|
||||||
} else if (config('app.settings.captcha') == 'recaptcha2') {
|
|
||||||
$response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
|
|
||||||
'response' => $this->captcha,
|
|
||||||
'secret' => config('app.settings.recaptcha2.secret_key')
|
|
||||||
])->object();
|
|
||||||
return $response->success;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the user is crossing email limit
|
|
||||||
*/
|
|
||||||
private function checkEmailLimit() {
|
|
||||||
$logs = Log::select('ip', 'email')->where('ip', request()->ip())->where('created_at', '>', Carbon::now()->subDay())->groupBy('email')->groupBy('ip')->get();
|
|
||||||
if (count($logs) >= config('app.settings.email_limit', 5)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if Username already consist of Domain
|
|
||||||
*/
|
|
||||||
private function checkDomainInUsername() {
|
|
||||||
$parts = explode('@', $this->user);
|
|
||||||
if (isset($parts[1])) {
|
|
||||||
if (in_array($parts[1], $this->domains)) {
|
|
||||||
$this->domain = $parts[1];
|
|
||||||
}
|
|
||||||
$this->user = $parts[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate if Domain in Email Exist
|
|
||||||
*/
|
|
||||||
private function validateDomainInEmail() {
|
|
||||||
$data = explode('@', $this->email);
|
|
||||||
if (isset($data[1])) {
|
|
||||||
$domain = $data[1];
|
|
||||||
$domains = config('app.settings.domains');
|
|
||||||
if (!in_array($domain, $domains)) {
|
|
||||||
$key = array_search($this->email, $this->emails);
|
|
||||||
TMail::removeEmail($this->email);
|
|
||||||
if ($key == 0 && count($this->emails) == 1 && config('app.settings.after_last_email_delete') == 'redirect_to_homepage') {
|
|
||||||
return redirect()->route('home');
|
|
||||||
} else {
|
|
||||||
return redirect()->route('mailbox');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire\Frontend\Components;
|
|
||||||
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class Mail extends Component
|
|
||||||
{
|
|
||||||
public $message;
|
|
||||||
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.frontend.components.mail')->with(['message' => $this->message]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,11 +32,9 @@ class Email extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function switchEmail($email): void
|
public function switchEmail($email)
|
||||||
{
|
{
|
||||||
ZEmail::setEmail($email);
|
return redirect()->route('switch', ['email' => $email]);
|
||||||
$this->email = $email;
|
|
||||||
$this->dispatch('updateEmail');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncEmail(): void
|
public function syncEmail(): void
|
||||||
|
|||||||
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Frontend;
|
namespace App\Livewire\Frontend;
|
||||||
|
|
||||||
|
use App\ColorPicker;
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
use App\Models\ZEmail;
|
use App\Models\ZEmail;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Mailbox extends Component
|
class Mailbox extends Component
|
||||||
{
|
{
|
||||||
|
use ColorPicker;
|
||||||
|
|
||||||
public $messages = [];
|
public $messages = [];
|
||||||
public $deleted = [];
|
public $deleted = [];
|
||||||
public $error = '';
|
public $error = '';
|
||||||
@@ -16,25 +20,32 @@ class Mailbox extends Component
|
|||||||
public $initial = false;
|
public $initial = false;
|
||||||
public $type;
|
public $type;
|
||||||
public $overflow = false;
|
public $overflow = false;
|
||||||
|
public $messageId;
|
||||||
|
|
||||||
protected $listeners = ['fetchMessages' => 'fetch', 'syncMailbox' => 'syncEmail'];
|
protected $listeners = ['fetchMessages' => 'fetch', 'syncMailbox' => 'syncEmail', 'setMessageId' => 'setMessageId'];
|
||||||
|
|
||||||
public function mount(): void
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->email = ZEmail::getEmail();
|
$this->email = ZEmail::getEmail();
|
||||||
$this->initial = false;
|
$this->initial = false;
|
||||||
|
if (!ZEmail::getEmail()) {
|
||||||
|
return redirect()->route('home');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public function syncEmail($email): void
|
public function syncEmail($email): void
|
||||||
{
|
{
|
||||||
$this->email = $email;
|
$this->email = $email;
|
||||||
$this->initial = false;
|
$this->initial = false;
|
||||||
|
$this->messages = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fetch(): void
|
public function fetch(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$count = count($this->messages);
|
$count = count($this->messages);
|
||||||
|
if ($count > 0) {
|
||||||
|
$this->messages = [];
|
||||||
|
}
|
||||||
$responses = [];
|
$responses = [];
|
||||||
if (config('app.beta_feature') || !json_decode(config('app.settings.imap_settings'))->cc_check) {
|
if (config('app.beta_feature') || !json_decode(config('app.settings.imap_settings'))->cc_check) {
|
||||||
$responses = [
|
$responses = [
|
||||||
@@ -51,21 +62,6 @@ class Mailbox extends Component
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// $responses = [
|
|
||||||
// 'to' => ZEmail::getMessages($this->email, 'to', $this->deleted),
|
|
||||||
// ];
|
|
||||||
// $imapSettings = json_decode(config('app.settings.imap_settings'));
|
|
||||||
// $betaFeature = config('app.beta_feature');
|
|
||||||
//
|
|
||||||
// if ($betaFeature || empty($imapSettings?->cc_check)) {
|
|
||||||
// $responses['cc'] = [
|
|
||||||
// 'data' => [],
|
|
||||||
// 'notifications' => []
|
|
||||||
// ];
|
|
||||||
// } else {
|
|
||||||
// $responses['cc'] = ZEmail::getMessages($this->email, 'cc', $this->deleted);
|
|
||||||
// }
|
|
||||||
|
|
||||||
$this->deleted = [];
|
$this->deleted = [];
|
||||||
$this->messages = array_merge($responses['to']['data'], $responses['cc']['data']);
|
$this->messages = array_merge($responses['to']['data'], $responses['cc']['data']);
|
||||||
$notifications = array_merge($responses['to']['notifications'], $responses['cc']['notifications']);
|
$notifications = array_merge($responses['to']['notifications'], $responses['cc']['notifications']);
|
||||||
@@ -90,22 +86,33 @@ class Mailbox extends Component
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->dispatch('stopLoader');
|
$this->dispatch('stopLoader');
|
||||||
$this->dispatch('loadDownload');
|
|
||||||
$this->initial = true;
|
$this->initial = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function delete($messageId) {
|
public function delete($messageId) {
|
||||||
|
|
||||||
|
try {
|
||||||
if (config('app.beta_feature')) {
|
if (config('app.beta_feature')) {
|
||||||
Message::find($messageId)->delete();
|
Message::find($messageId)->delete();
|
||||||
}
|
}
|
||||||
|
if (config('app.fetch_from_db')) {
|
||||||
|
\App\Models\Email::where(['message_id' => $messageId])->delete();
|
||||||
|
}
|
||||||
$this->deleted[] = $messageId;
|
$this->deleted[] = $messageId;
|
||||||
foreach ($this->messages as $key => $message) {
|
foreach ($this->messages as $key => $message) {
|
||||||
if ($message['id'] == $messageId) {
|
if ($message['id'] == $messageId) {
|
||||||
$directory = './tmp/attachments/' . $messageId;
|
$directory = public_path('tmp/attachments/') . $messageId;
|
||||||
$this->rrmdir($directory);
|
$this->rrmdir($directory);
|
||||||
unset($this->messages[$key]);
|
unset($this->messages[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (
|
||||||
|
\Exception $exception
|
||||||
|
) {
|
||||||
|
Log::error($exception->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
|||||||
@@ -2,10 +2,21 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\ZEmail;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Home extends Component
|
class Home extends Component
|
||||||
{
|
{
|
||||||
|
protected $listeners = ['fetchMessages' => 'checkIfAnyMessage'];
|
||||||
|
|
||||||
|
public function checkIfAnyMessage()
|
||||||
|
{
|
||||||
|
$email = ZEmail::getEmail();
|
||||||
|
$messages = ZEmail::getMessages($email);
|
||||||
|
if (count($messages['data']) > 0) {
|
||||||
|
return redirect()->route('mailbox');
|
||||||
|
}
|
||||||
|
}
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.home');
|
return view('livewire.home');
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
|
||||||
|
|
||||||
use Livewire\Component;
|
|
||||||
|
|
||||||
class Inbox extends Component
|
|
||||||
{
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('livewire.inbox');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,10 +4,10 @@ namespace App\Livewire;
|
|||||||
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Email extends Component
|
class ListBlog extends Component
|
||||||
{
|
{
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.email');
|
return view('livewire.list-blog');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
28
app/Livewire/Page.php
Normal file
28
app/Livewire/Page.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Page extends Component
|
||||||
|
{
|
||||||
|
public $slug;
|
||||||
|
|
||||||
|
public function mount($slug)
|
||||||
|
|
||||||
|
{
|
||||||
|
$this->slug = $slug;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$page = \App\Models\Page::where('slug', $this->slug)->firstOrFail();
|
||||||
|
|
||||||
|
if ($page->is_published == false ) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
return view('livewire.page', [
|
||||||
|
'page' => $page,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
app/Models/Blog.php
Normal file
32
app/Models/Blog.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class Blog extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'post',
|
||||||
|
'slug',
|
||||||
|
'content',
|
||||||
|
'meta',
|
||||||
|
'custom_header',
|
||||||
|
'post_image',
|
||||||
|
'is_published',
|
||||||
|
'category_id',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'meta' => 'json'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function category(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Category::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/Models/Category.php
Normal file
22
app/Models/Category.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
|
class Category extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'slug',
|
||||||
|
'is_active'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function blogs(): HasMany {
|
||||||
|
return $this->hasMany(Blog::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
459
app/Models/Email.php
Normal file
459
app/Models/Email.php
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\ColorPicker;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Carbon\CarbonImmutable;
|
||||||
|
use Ddeboer\Imap\Search\Date\Before;
|
||||||
|
use Ddeboer\Imap\Search\Date\Since;
|
||||||
|
use Ddeboer\Imap\SearchExpression;
|
||||||
|
use Ddeboer\Imap\Server;
|
||||||
|
use Ddeboer\Imap\Search\Email\Cc;
|
||||||
|
use Ddeboer\Imap\Search\Email\To;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\File;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class Email extends Model
|
||||||
|
{
|
||||||
|
|
||||||
|
use ColorPicker;
|
||||||
|
protected $table = 'emails';
|
||||||
|
|
||||||
|
// Fillable fields to allow mass assignment
|
||||||
|
protected $fillable = [
|
||||||
|
'message_id',
|
||||||
|
'subject',
|
||||||
|
'from_name',
|
||||||
|
'from_email',
|
||||||
|
'to',
|
||||||
|
'cc',
|
||||||
|
'bcc',
|
||||||
|
'timestamp',
|
||||||
|
'body_text',
|
||||||
|
'body_html',
|
||||||
|
'is_seen',
|
||||||
|
'is_flagged',
|
||||||
|
'size',
|
||||||
|
'mailbox',
|
||||||
|
'raw_headers',
|
||||||
|
'raw_body',
|
||||||
|
'attachments',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'to' => 'array',
|
||||||
|
'cc' => 'array',
|
||||||
|
'bcc' => 'array',
|
||||||
|
'attachments' => 'array', // If attachments are stored as a JSON field
|
||||||
|
'timestamp' => 'datetime', // Cast timestamp to Carbon instance
|
||||||
|
];
|
||||||
|
|
||||||
|
public static function connectMailBox($imap = null): \Ddeboer\Imap\ConnectionInterface
|
||||||
|
{
|
||||||
|
if ($imap === null) {
|
||||||
|
$imap = json_decode(config('app.settings.imap_settings'), true);
|
||||||
|
}
|
||||||
|
$flags = $imap['protocol'] . '/' . $imap['encryption'];
|
||||||
|
if ($imap['validate_cert']) {
|
||||||
|
$flags = $flags . '/validate-cert';
|
||||||
|
} else {
|
||||||
|
$flags = $flags . '/novalidate-cert';
|
||||||
|
}
|
||||||
|
$server = new Server($imap['host'], $imap['port'], $flags);
|
||||||
|
return $server->authenticate($imap['username'], $imap['password']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fetchProcessStoreEmail()
|
||||||
|
{
|
||||||
|
|
||||||
|
try {
|
||||||
|
$allowed = explode(',', 'doc,docx,xls,xlsx,ppt,pptx,xps,pdf,dxf,ai,psd,eps,ps,svg,ttf,zip,rar,tar,gzip,mp3,mpeg,wav,ogg,jpeg,jpg,png,gif,bmp,tif,webm,mpeg4,3gpp,mov,avi,mpegs,wmv,flx,txt');
|
||||||
|
$connection = \App\Models\Email::connectMailBox();
|
||||||
|
$mailbox = $connection->getMailbox('INBOX');
|
||||||
|
$messages = $mailbox->getMessages();
|
||||||
|
|
||||||
|
$result = '';
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
|
||||||
|
$sender = $message->getFrom();
|
||||||
|
$date = $message->getDate();
|
||||||
|
if (!$date) {
|
||||||
|
$date = new \DateTime();
|
||||||
|
if ($message->getHeaders()->get('udate')) {
|
||||||
|
$date->setTimestamp($message->getHeaders()->get('udate'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$content = '';
|
||||||
|
$contentText = '';
|
||||||
|
$html = $message->getBodyHtml();
|
||||||
|
$text = $message->getBodyText();
|
||||||
|
|
||||||
|
if ($text) {
|
||||||
|
$contentText = str_replace('<a', '<a target="blank"', str_replace(array("\r\n", "\n"), '', $text));
|
||||||
|
}
|
||||||
|
if ($html) {
|
||||||
|
$content = str_replace('<a', '<a target="blank"', $html);
|
||||||
|
} else {
|
||||||
|
$content = str_replace('<a', '<a target="blank"', str_replace(array("\r\n", "\n"), '<br/>', $text));
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = [];
|
||||||
|
|
||||||
|
$to = $message->getHeaders()->get('To') ? array_map(function ($entry) {
|
||||||
|
return $entry->mailbox . '@' . $entry->host;
|
||||||
|
}, $message->getHeaders()->get('To')) : [];
|
||||||
|
|
||||||
|
$cc = $message->getHeaders()->get('Cc') ? array_map(function ($entry) {
|
||||||
|
return $entry->mailbox . '@' . $entry->host;
|
||||||
|
}, $message->getHeaders()->get('Cc')) : [];
|
||||||
|
|
||||||
|
$bcc = $message->getHeaders()->get('Bcc') ? array_map(function ($entry) {
|
||||||
|
return $entry->mailbox . '@' . $entry->host;
|
||||||
|
}, $message->getHeaders()->get('Bcc')) : [];
|
||||||
|
|
||||||
|
$messageTime = $message->getDate();
|
||||||
|
$utcTime = CarbonImmutable::instance($messageTime)->setTimezone('UTC')->toDateTimeString();
|
||||||
|
|
||||||
|
$obj['id'] = $message->getNumber();
|
||||||
|
$obj['to'] = $to;
|
||||||
|
$obj['cc'] = $cc;
|
||||||
|
$obj['bcc'] = $bcc;
|
||||||
|
$obj['subject'] = $message->getSubject();
|
||||||
|
$obj['sender_name'] = $sender->getName();
|
||||||
|
$obj['sender_email'] = $sender->getAddress();
|
||||||
|
$obj['timestamp'] = $utcTime;
|
||||||
|
$obj['size'] = $message->getSize();
|
||||||
|
//$obj['date'] = $date->format(json_decode(config('app.settings.configuration_settings'))->date_format ?? 'd M Y h:i A');
|
||||||
|
$obj['content'] = $content;
|
||||||
|
$obj['contentText'] = $contentText;
|
||||||
|
$obj['attachments'] = [];
|
||||||
|
//$obj['raw_headers'] = $message->getRawHeaders();
|
||||||
|
//$obj['raw_body'] = $message->getRawMessage();
|
||||||
|
|
||||||
|
if ($message->hasAttachments()) {
|
||||||
|
$attachments = $message->getAttachments();
|
||||||
|
$directory = './tmp/attachments/' . $obj['id'] . '/';
|
||||||
|
|
||||||
|
is_dir($directory) || mkdir($directory, 0777, true);
|
||||||
|
foreach ($attachments as $attachment) {
|
||||||
|
$filenameArray = explode('.', $attachment->getFilename());
|
||||||
|
$extension = $filenameArray[count($filenameArray) - 1];
|
||||||
|
if (in_array($extension, $allowed)) {
|
||||||
|
if (!file_exists($directory . $attachment->getFilename())) {
|
||||||
|
try {
|
||||||
|
file_put_contents(
|
||||||
|
$directory . $attachment->getFilename(),
|
||||||
|
$attachment->getDecodedContent()
|
||||||
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($attachment->getFilename() !== 'undefined') {
|
||||||
|
$url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename());
|
||||||
|
$structure = $attachment->getStructure();
|
||||||
|
if (isset($structure->id) && str_contains($obj['content'], trim($structure->id, '<>'))) {
|
||||||
|
$obj['content'] = str_replace('cid:' . trim($structure->id, '<>'), $url, $obj['content']);
|
||||||
|
}
|
||||||
|
$obj['attachments'][] = [
|
||||||
|
'file' => $attachment->getFilename(),
|
||||||
|
'url' => $url
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$response['data'][] = $obj;
|
||||||
|
|
||||||
|
if (!$message->isSeen()) {
|
||||||
|
$initialData = $obj;
|
||||||
|
$data = [
|
||||||
|
'message_id' => Carbon::parse($utcTime)->format('Ymd').$initialData['id'],
|
||||||
|
'subject' => $initialData['subject'],
|
||||||
|
'from_name' => $initialData['sender_name'],
|
||||||
|
'from_email' => $initialData['sender_email'],
|
||||||
|
'to' => $initialData['to'],
|
||||||
|
'cc' => $initialData['cc'],
|
||||||
|
'bcc' => $initialData['bcc'],
|
||||||
|
'timestamp' => $initialData['timestamp'], // store in UTC
|
||||||
|
'body_text' => $initialData['contentText'],
|
||||||
|
'body_html' => $initialData['content'],
|
||||||
|
'is_seen' => false,
|
||||||
|
'is_flagged' => false,
|
||||||
|
'size' => $initialData['size'],
|
||||||
|
'mailbox' => 'INBOX',
|
||||||
|
'raw_headers' => null,
|
||||||
|
'raw_body' => null,
|
||||||
|
'attachments' => $initialData['attachments'],
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::create($data);
|
||||||
|
$checkAction = config('app.move_or_delete');
|
||||||
|
if ($checkAction != null) {
|
||||||
|
if ($checkAction == 'delete') {
|
||||||
|
$message->delete();
|
||||||
|
} else {
|
||||||
|
$newMailBox = $connection->getMailbox($checkAction);
|
||||||
|
$message->move($newMailBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// \Log::error($e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$initialData = $obj;
|
||||||
|
$data = [
|
||||||
|
'message_id' => Carbon::parse($utcTime)->format('Ymd').$initialData['id'],
|
||||||
|
'subject' => $initialData['subject'],
|
||||||
|
'from_name' => $initialData['sender_name'],
|
||||||
|
'from_email' => $initialData['sender_email'],
|
||||||
|
'to' => $initialData['to'],
|
||||||
|
'cc' => $initialData['cc'],
|
||||||
|
'bcc' => $initialData['bcc'],
|
||||||
|
'timestamp' => $initialData['timestamp'], // store in UTC
|
||||||
|
'body_text' => $initialData['contentText'],
|
||||||
|
'body_html' => $initialData['content'],
|
||||||
|
'is_seen' => true,
|
||||||
|
'is_flagged' => false,
|
||||||
|
'size' => $initialData['size'],
|
||||||
|
'mailbox' => 'INBOX',
|
||||||
|
'raw_headers' => null,
|
||||||
|
'raw_body' => null,
|
||||||
|
'attachments' => $initialData['attachments'],
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::create($data);
|
||||||
|
$checkAction = config('app.move_or_delete');
|
||||||
|
if ($checkAction != null) {
|
||||||
|
if ($checkAction == 'delete') {
|
||||||
|
$message->delete();
|
||||||
|
} else {
|
||||||
|
$newMailBox = $connection->getMailbox($checkAction);
|
||||||
|
$message->move($newMailBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// \Log::error($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$connection->expunge();
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function fetchEmailFromDB($email) {
|
||||||
|
|
||||||
|
$validator = Validator::make(['email' => $email], [
|
||||||
|
'email' => 'required|email'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return self::whereJsonContains('to', $email)->orderBy('timestamp', 'desc')->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function parseEmail($email, $deleted = []): array
|
||||||
|
{
|
||||||
|
$messages = self::fetchEmailFromDB($email);
|
||||||
|
$limit = json_decode(config('app.settings.configuration_settings'))->fetch_messages_limit ?? 15;
|
||||||
|
$count = 1;
|
||||||
|
$response = [
|
||||||
|
'data' => [],
|
||||||
|
'notifications' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
|
||||||
|
if (in_array($message['message_id'], $deleted)) {
|
||||||
|
// If it exists, delete the matching record from the 'emails' table
|
||||||
|
Email::where('message_id', $message['message_id'])->delete();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blocked = false;
|
||||||
|
|
||||||
|
$timestamp = $message['timestamp'];
|
||||||
|
$carbonTimestamp = Carbon::parse($timestamp, 'UTC');
|
||||||
|
$obj = [];
|
||||||
|
$obj['subject'] = $message['subject'];
|
||||||
|
$obj['sender_name'] = $message['from_name'];
|
||||||
|
$obj['sender_email'] = $message['from_email'];
|
||||||
|
$obj['timestamp'] = $message['timestamp'];
|
||||||
|
$obj['date'] = $carbonTimestamp->format('d M Y h:i A');
|
||||||
|
$obj['datediff'] = $carbonTimestamp->diffForHumans(Carbon::now('UTC'));
|
||||||
|
$obj['id'] = $message['message_id'];
|
||||||
|
$obj['content'] = $message['body_html'];
|
||||||
|
$obj['contentText'] = $message['body_text'];
|
||||||
|
$obj['attachments'] = [];
|
||||||
|
$obj['is_seen'] = $message['is_seen'];
|
||||||
|
$obj['sender_photo'] = self::chooseColor(strtoupper(substr($message['from_name'] ?: $message['from_email'], 0, 1) ));
|
||||||
|
|
||||||
|
|
||||||
|
$domain = explode('@', $obj['sender_email'])[1];
|
||||||
|
$blocked = in_array($domain, json_decode(config('app.settings.configuration_settings'))->blocked_domains);
|
||||||
|
if ($blocked) {
|
||||||
|
$obj['subject'] = __('Blocked');
|
||||||
|
$obj['content'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
|
||||||
|
$obj['contentText'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($message['attachments']) > 0 && !$blocked) {
|
||||||
|
$obj['attachments'] = $message['attachments'];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$response['data'][] = $obj;
|
||||||
|
if (!$message['is_seen']) {
|
||||||
|
$response['notifications'][] = [
|
||||||
|
'subject' => $obj['subject'],
|
||||||
|
'sender_name' => $obj['sender_name'],
|
||||||
|
'sender_email' => $obj['sender_email']
|
||||||
|
];
|
||||||
|
if (config('app.zemail_log')) {
|
||||||
|
file_put_contents(storage_path('logs/zemail.csv'), request()->ip() . "," . date("Y-m-d h:i:s a") . "," . $obj['sender_email'] . "," . $email . PHP_EOL, FILE_APPEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Email::where('message_id', $message['message_id'])->update(['is_seen' => true]);
|
||||||
|
if (++$count > $limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteBulkAttachments()
|
||||||
|
{
|
||||||
|
$dir = public_path('/tmp/attachments');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (File::exists($dir)) {
|
||||||
|
File::cleanDirectory($dir);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteBulkMailboxes()
|
||||||
|
{
|
||||||
|
$foldersToClean = ['INBOX', 'ZDUMP', 'Trash'];
|
||||||
|
$cutoff = (new \DateTime())->modify('-3 hours');
|
||||||
|
$totalDeleted = 0;
|
||||||
|
$maxToDelete = 100;
|
||||||
|
|
||||||
|
foreach ($foldersToClean as $folderName) {
|
||||||
|
$connection = \App\Models\Email::connectMailBox();
|
||||||
|
if ($totalDeleted >= $maxToDelete) {
|
||||||
|
$connection->expunge();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($connection->hasMailbox($folderName)) {
|
||||||
|
$mailbox = $connection->getMailbox($folderName);
|
||||||
|
$messages = $mailbox->getMessages(new Since(new \DateTime('today')));
|
||||||
|
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
if ($totalDeleted >= $maxToDelete) {
|
||||||
|
$connection->expunge();
|
||||||
|
break 2; // exit both loops
|
||||||
|
}
|
||||||
|
|
||||||
|
$messageDate = $message->getDate();
|
||||||
|
if ($messageDate < $cutoff) {
|
||||||
|
$message->delete();
|
||||||
|
$totalDeleted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$connection->expunge();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "$totalDeleted message(s) deleted from Trash and ZDUMP.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteMessagesFromDB() {
|
||||||
|
$cutoff = Carbon::now('UTC')->subHours(6)->toDateTimeString();
|
||||||
|
$count = count(self::where('timestamp', '<', $cutoff)
|
||||||
|
->orderBy('timestamp', 'desc')
|
||||||
|
->get());
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
self::where('timestamp', '<', $cutoff)->delete();
|
||||||
|
return "$count old message(s) deleted from the database.";
|
||||||
|
}
|
||||||
|
return "No messages older than 6 hours found.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function mailToDBStatus(): bool
|
||||||
|
{
|
||||||
|
$latestRecord = self::orderBy('timestamp', 'desc')->first();
|
||||||
|
if (!$latestRecord) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentTime = Carbon::now('UTC');
|
||||||
|
$lastRecordTime = Carbon::parse($latestRecord->timestamp);
|
||||||
|
|
||||||
|
if ($lastRecordTime->diffInMinutes($currentTime) < 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static function cleanMailbox(): string
|
||||||
|
{
|
||||||
|
$foldersToClean = ['INBOX'];
|
||||||
|
$cutoff = (new \DateTime())->modify('-6 hours');
|
||||||
|
$totalDeleted = 0;
|
||||||
|
$maxToDelete = 100;
|
||||||
|
|
||||||
|
foreach ($foldersToClean as $folderName) {
|
||||||
|
$connection = \App\Models\Email::connectMailBox();
|
||||||
|
if ($totalDeleted >= $maxToDelete) {
|
||||||
|
$connection->expunge();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($connection->hasMailbox($folderName)) {
|
||||||
|
$mailbox = $connection->getMailbox($folderName);
|
||||||
|
$messages = $mailbox->getMessages(new Since(new \DateTime('today')));
|
||||||
|
|
||||||
|
foreach ($messages as $message) {
|
||||||
|
if ($totalDeleted >= $maxToDelete) {
|
||||||
|
$connection->expunge();
|
||||||
|
break 2; // exit both loops
|
||||||
|
}
|
||||||
|
|
||||||
|
$messageDate = $message->getDate();
|
||||||
|
if ($messageDate < $cutoff) {
|
||||||
|
$message->delete();
|
||||||
|
$totalDeleted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$connection->expunge();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "$totalDeleted message(s) deleted from Trash and ZDUMP.";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
@@ -18,4 +19,17 @@ class Log extends Model
|
|||||||
'ip',
|
'ip',
|
||||||
'email',
|
'email',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public static function deleteLogsFromDB() {
|
||||||
|
$cutoff = Carbon::now('UTC')->subMonths(3)->toDateTimeString();
|
||||||
|
$count = count(self::where('created_at', '<', $cutoff)
|
||||||
|
->orderBy('created_at', 'desc')
|
||||||
|
->get());
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
self::where('created_at', '<', $cutoff)->delete();
|
||||||
|
return "$count old log(s) deleted from the database.";
|
||||||
|
}
|
||||||
|
return "No logs older than 3 months found.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
app/Models/Menu.php
Normal file
23
app/Models/Menu.php
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Menu extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'name',
|
||||||
|
'url',
|
||||||
|
'new_tab',
|
||||||
|
'parent'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function parentname()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Menu::class, 'parent');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\ColorPicker;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Ddeboer\Imap\Search\Date\Since;
|
use Ddeboer\Imap\Search\Date\Since;
|
||||||
use Ddeboer\Imap\Search\Email\Cc;
|
use Ddeboer\Imap\Search\Email\Cc;
|
||||||
@@ -14,7 +15,7 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
|
|
||||||
class Message extends Model
|
class Message extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory, ColorPicker;
|
||||||
|
|
||||||
public static function store(Request $request): void
|
public static function store(Request $request): void
|
||||||
{
|
{
|
||||||
@@ -149,7 +150,6 @@ class Message extends Model
|
|||||||
$content = '';
|
$content = '';
|
||||||
$contentText = '';
|
$contentText = '';
|
||||||
$html = $message->getBodyHtml();
|
$html = $message->getBodyHtml();
|
||||||
|
|
||||||
$text = $message->getBodyText();
|
$text = $message->getBodyText();
|
||||||
if ($text) {
|
if ($text) {
|
||||||
$contentText = str_replace('<a', '<a target="blank"', str_replace(array("\r\n", "\n"), '', $text));
|
$contentText = str_replace('<a', '<a target="blank"', str_replace(array("\r\n", "\n"), '', $text));
|
||||||
@@ -173,12 +173,16 @@ class Message extends Model
|
|||||||
$obj['content'] = $content;
|
$obj['content'] = $content;
|
||||||
$obj['contentText'] = $contentText;
|
$obj['contentText'] = $contentText;
|
||||||
$obj['attachments'] = [];
|
$obj['attachments'] = [];
|
||||||
|
$obj['is_seen'] = true;
|
||||||
|
$obj['sender_photo'] = self::chooseColor(strtoupper(substr($sender->getName() ?: $sender->getAddress(), 0, 1) ));
|
||||||
|
|
||||||
//Checking if Sender is Blocked
|
//Checking if Sender is Blocked
|
||||||
$domain = explode('@', $obj['sender_email'])[1];
|
$domain = explode('@', $obj['sender_email'])[1];
|
||||||
$blocked = in_array($domain, json_decode(config('app.settings.configuration_settings'))->blocked_domains);
|
$blocked = in_array($domain, json_decode(config('app.settings.configuration_settings'))->blocked_domains);
|
||||||
if ($blocked) {
|
if ($blocked) {
|
||||||
$obj['subject'] = __('Blocked');
|
$obj['subject'] = __('Blocked');
|
||||||
$obj['content'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
|
$obj['content'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
|
||||||
|
$obj['contentText'] = __('Emails from') . ' ' . $domain . ' ' . __('are blocked by Admin');
|
||||||
}
|
}
|
||||||
if ($message->hasAttachments() && !$blocked) {
|
if ($message->hasAttachments() && !$blocked) {
|
||||||
$attachments = $message->getAttachments();
|
$attachments = $message->getAttachments();
|
||||||
@@ -189,10 +193,14 @@ class Message extends Model
|
|||||||
$extension = $filenameArray[count($filenameArray) - 1];
|
$extension = $filenameArray[count($filenameArray) - 1];
|
||||||
if (in_array($extension, $allowed)) {
|
if (in_array($extension, $allowed)) {
|
||||||
if (!file_exists($directory . $attachment->getFilename())) {
|
if (!file_exists($directory . $attachment->getFilename())) {
|
||||||
|
try {
|
||||||
file_put_contents(
|
file_put_contents(
|
||||||
$directory . $attachment->getFilename(),
|
$directory . $attachment->getFilename(),
|
||||||
$attachment->getDecodedContent()
|
$attachment->getDecodedContent()
|
||||||
);
|
);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Illuminate\Support\Facades\Log::error($e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($attachment->getFilename() !== 'undefined') {
|
if ($attachment->getFilename() !== 'undefined') {
|
||||||
$url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename());
|
$url = config('app.settings.app_base_url') . str_replace('./', '/', $directory . $attachment->getFilename());
|
||||||
|
|||||||
26
app/Models/Page.php
Normal file
26
app/Models/Page.php
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Page extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'title',
|
||||||
|
'slug',
|
||||||
|
'content',
|
||||||
|
'parent',
|
||||||
|
'meta',
|
||||||
|
'custom_header',
|
||||||
|
'page_image',
|
||||||
|
'is_published'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'meta' => 'json'
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -14,11 +14,6 @@ use function str_replace;
|
|||||||
|
|
||||||
class ZEmail extends Model
|
class ZEmail extends Model
|
||||||
{
|
{
|
||||||
public static function check()
|
|
||||||
{
|
|
||||||
return ZEmail::createCustomEmail(username: 'sdcs', domain: 'e-pool.uk');
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function connectMailBox($imap = null): \Ddeboer\Imap\ConnectionInterface
|
public static function connectMailBox($imap = null): \Ddeboer\Imap\ConnectionInterface
|
||||||
{
|
{
|
||||||
if ($imap === null) {
|
if ($imap === null) {
|
||||||
@@ -39,6 +34,16 @@ class ZEmail extends Model
|
|||||||
if (config('app.beta_feature')) {
|
if (config('app.beta_feature')) {
|
||||||
return Message::getMessages($email);
|
return Message::getMessages($email);
|
||||||
}
|
}
|
||||||
|
if (config('app.force_db_mail')) {
|
||||||
|
return Email::parseEmail($email, $deleted);
|
||||||
|
}
|
||||||
|
if (config('app.fetch_from_db')) {
|
||||||
|
if (Email::mailToDBStatus()) {
|
||||||
|
return Email::parseEmail($email, $deleted);
|
||||||
|
} else {
|
||||||
|
return Message::fetchMessages($email, $type, $deleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
return Message::fetchMessages($email, $type, $deleted);
|
return Message::fetchMessages($email, $type, $deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Models\Blog;
|
||||||
|
use App\Models\Menu;
|
||||||
use DB;
|
use DB;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
@@ -20,12 +22,19 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
$settings = cache()->remember('app_settings', now()->addMinutes(1), function () {
|
$settings = cache()->remember('app_settings', now()->addHours(6), function () {
|
||||||
return (array) DB::table('settings')->find(1);
|
return (array) DB::table('settings')->find(1);
|
||||||
});
|
});
|
||||||
if ($settings) {
|
$menus = cache()->remember('app_menus', now()->addHours(6), function () {
|
||||||
config(['app.settings' => (array) $settings]);
|
return Menu::all();
|
||||||
}
|
});
|
||||||
|
|
||||||
|
$blogs = cache()->remember('app_blogs', now()->addHours(6), function () {
|
||||||
|
return Blog::where('is_published', 1)->get();
|
||||||
|
});
|
||||||
|
|
||||||
|
config(['app.settings' => (array) $settings]);
|
||||||
|
config(['app.menus' => $menus]);
|
||||||
|
config(['app.blogs' => $blogs]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
health: '/up',
|
health: '/up',
|
||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware) {
|
->withMiddleware(function (Middleware $middleware) {
|
||||||
//
|
$middleware->web(append: [
|
||||||
|
\App\Http\Middleware\Locale::class,
|
||||||
|
]);
|
||||||
})
|
})
|
||||||
->withExceptions(function (Exceptions $exceptions) {
|
->withExceptions(function (Exceptions $exceptions) {
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
"livewire/flux": "^2.1",
|
"livewire/flux": "^2.1",
|
||||||
"livewire/livewire": "^3.6"
|
"livewire/livewire": "^3.6",
|
||||||
|
"ext-imap": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"barryvdh/laravel-debugbar": "^3.15",
|
"barryvdh/laravel-debugbar": "^3.15",
|
||||||
|
|||||||
27
composer.lock
generated
27
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "8a5cd9a0ccf67c460d95ecb968192ef2",
|
"content-hash": "b4dcaf149eb8c0291c1de5ccd42c8f94",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "anourvalar/eloquent-serialize",
|
"name": "anourvalar/eloquent-serialize",
|
||||||
@@ -2102,16 +2102,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/framework",
|
"name": "laravel/framework",
|
||||||
"version": "v12.10.0",
|
"version": "v12.10.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/laravel/framework.git",
|
"url": "https://github.com/laravel/framework.git",
|
||||||
"reference": "be0d6f39e18dd28d29f5dd2819a6c02eba61b7e5"
|
"reference": "0f123cc857bc177abe4d417448d4f7164f71802a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/laravel/framework/zipball/be0d6f39e18dd28d29f5dd2819a6c02eba61b7e5",
|
"url": "https://api.github.com/repos/laravel/framework/zipball/0f123cc857bc177abe4d417448d4f7164f71802a",
|
||||||
"reference": "be0d6f39e18dd28d29f5dd2819a6c02eba61b7e5",
|
"reference": "0f123cc857bc177abe4d417448d4f7164f71802a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2313,7 +2313,7 @@
|
|||||||
"issues": "https://github.com/laravel/framework/issues",
|
"issues": "https://github.com/laravel/framework/issues",
|
||||||
"source": "https://github.com/laravel/framework"
|
"source": "https://github.com/laravel/framework"
|
||||||
},
|
},
|
||||||
"time": "2025-04-22T13:55:18+00:00"
|
"time": "2025-04-24T14:11:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/prompts",
|
"name": "laravel/prompts",
|
||||||
@@ -3145,16 +3145,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "livewire/flux",
|
"name": "livewire/flux",
|
||||||
"version": "v2.1.4",
|
"version": "v2.1.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/livewire/flux.git",
|
"url": "https://github.com/livewire/flux.git",
|
||||||
"reference": "a19709fc94f5a1b795ce24ad42662bd398c19371"
|
"reference": "e24f05be20fa1a0ca027a11c2eea763cc539c82e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/livewire/flux/zipball/a19709fc94f5a1b795ce24ad42662bd398c19371",
|
"url": "https://api.github.com/repos/livewire/flux/zipball/e24f05be20fa1a0ca027a11c2eea763cc539c82e",
|
||||||
"reference": "a19709fc94f5a1b795ce24ad42662bd398c19371",
|
"reference": "e24f05be20fa1a0ca027a11c2eea763cc539c82e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -3202,9 +3202,9 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/livewire/flux/issues",
|
"issues": "https://github.com/livewire/flux/issues",
|
||||||
"source": "https://github.com/livewire/flux/tree/v2.1.4"
|
"source": "https://github.com/livewire/flux/tree/v2.1.5"
|
||||||
},
|
},
|
||||||
"time": "2025-04-14T11:59:19+00:00"
|
"time": "2025-04-24T22:52:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "livewire/livewire",
|
"name": "livewire/livewire",
|
||||||
@@ -10929,7 +10929,8 @@
|
|||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.2"
|
"php": "^8.2",
|
||||||
|
"ext-imap": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ return [
|
|||||||
|
|
||||||
'zemail_log' => env('ENABLE_ZEMAIL_LOGS', false),
|
'zemail_log' => env('ENABLE_ZEMAIL_LOGS', false),
|
||||||
'beta_feature' => env('APP_BETA_FEATURE', false),
|
'beta_feature' => env('APP_BETA_FEATURE', false),
|
||||||
|
'fetch_from_db' => env('FETCH_FETCH_FOR_DB', false),
|
||||||
|
'force_db_mail' => env('FORCE_DB_MAIL', false),
|
||||||
|
'move_or_delete' => env('MOVE_OR_DELETE', null),
|
||||||
|
'auto_fetch_mail' => env('AUTO_FETCH_MAIL', false),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('emails', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('message_id')->unique()->index();
|
||||||
|
$table->string('subject')->nullable();
|
||||||
|
$table->string('from_name')->nullable();
|
||||||
|
$table->string('from_email');
|
||||||
|
$table->text('to');
|
||||||
|
$table->text('cc')->nullable();
|
||||||
|
$table->text('bcc')->nullable();
|
||||||
|
$table->dateTime('timestamp')->nullable();
|
||||||
|
$table->longText('body_text')->nullable();
|
||||||
|
$table->longText('body_html')->nullable();
|
||||||
|
$table->boolean('is_seen')->default(false);
|
||||||
|
$table->boolean('is_flagged')->default(false);
|
||||||
|
$table->unsignedBigInteger('size')->nullable();
|
||||||
|
$table->string('mailbox')->default('INBOX');
|
||||||
|
$table->longText('raw_headers')->nullable();
|
||||||
|
$table->longText('raw_body')->nullable();
|
||||||
|
$table->json('attachments')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('emails');
|
||||||
|
}
|
||||||
|
};
|
||||||
35
database/migrations/2025_04_27_120959_create_pages_table.php
Normal file
35
database/migrations/2025_04_27_120959_create_pages_table.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('pages', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('title');
|
||||||
|
$table->string('slug');
|
||||||
|
$table->longText('content')->nullable();
|
||||||
|
$table->string('parent')->nullable();
|
||||||
|
$table->longText('meta')->nullable();
|
||||||
|
$table->longText('custom_header')->nullable();
|
||||||
|
$table->string('page_image')->nullable();
|
||||||
|
$table->boolean('is_published')->default(true);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('pages');
|
||||||
|
}
|
||||||
|
};
|
||||||
31
database/migrations/2025_04_27_123300_create_menus_table.php
Normal file
31
database/migrations/2025_04_27_123300_create_menus_table.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('menus', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('url');
|
||||||
|
$table->boolean('new_tab');
|
||||||
|
$table->string('parent')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('menus');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('categories', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('slug');
|
||||||
|
$table->boolean('is_active');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('categories');
|
||||||
|
}
|
||||||
|
};
|
||||||
35
database/migrations/2025_04_27_133802_create_blogs_table.php
Normal file
35
database/migrations/2025_04_27_133802_create_blogs_table.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('blogs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('post');
|
||||||
|
$table->string('slug');
|
||||||
|
$table->longText('content')->nullable();
|
||||||
|
$table->longText('meta')->nullable();
|
||||||
|
$table->longText('custom_header')->nullable();
|
||||||
|
$table->string('post_image')->nullable();
|
||||||
|
$table->boolean('is_published')->default(true);
|
||||||
|
$table->foreignId('category_id')->constrained('categories')->cascadeOnDelete();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('blogs');
|
||||||
|
}
|
||||||
|
};
|
||||||
24
inCron.php
Normal file
24
inCron.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Adjust this path if your file location is different
|
||||||
|
require __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
// Bootstrap the Laravel application
|
||||||
|
$app = require_once __DIR__ . '/bootstrap/app.php';
|
||||||
|
|
||||||
|
// Make the Console Kernel instance
|
||||||
|
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Run the Artisan command 'ping'
|
||||||
|
$exitCode = $kernel->call('ping');
|
||||||
|
|
||||||
|
// Get the output of the command
|
||||||
|
$output = $kernel->output();
|
||||||
|
|
||||||
|
echo "Artisan command 'ping' executed successfully. Exit code: $exitCode\n";
|
||||||
|
echo "Output:\n$output";
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
echo "Error running Artisan command: " . $e->getMessage();
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 619 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
@@ -58,3 +58,10 @@
|
|||||||
.animate-progress {
|
.animate-progress {
|
||||||
animation: progress 4s linear forwards;
|
animation: progress 4s linear forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mailbox-min-height {
|
||||||
|
min-height: 60vh;
|
||||||
|
}
|
||||||
|
.magic-box {
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
if (window.Livewire && typeof window.Livewire.dispatch === 'function') {
|
if (window.Livewire && typeof window.Livewire.dispatch === 'function') {
|
||||||
setTimeout(() => {
|
|
||||||
Livewire.dispatch('getEmail');
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
document.addEventListener('closeModal', () => {
|
document.addEventListener('closeModal', () => {
|
||||||
document.querySelectorAll('dialog[data-modal]').forEach(dialog => {
|
document.querySelectorAll('dialog[data-modal]').forEach(dialog => {
|
||||||
if (typeof dialog.close === 'function') {
|
if (typeof dialog.close === 'function') {
|
||||||
dialog.close();
|
dialog.close();
|
||||||
console.log(`Closed dialog with data-modal="${dialog.getAttribute('data-modal')}"`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -55,15 +50,170 @@ toast.remove();
|
|||||||
}, 4000);
|
}, 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleDispatches(dispatches) {
|
|
||||||
dispatches.forEach(dispatch => {
|
|
||||||
if (dispatch.name === "showAlert") {
|
|
||||||
const params = dispatch.params[0];
|
|
||||||
showToast(params);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
window.addEventListener("showAlert", (event) => {
|
window.addEventListener("showAlert", (event) => {
|
||||||
const detail = event.detail[0];
|
const detail = event.detail[0];
|
||||||
showToast(detail);
|
showToast(detail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.addEventListener("copyEmail", (event) => {
|
||||||
|
const element = document.getElementById("copyEmail");
|
||||||
|
const copyText = document.getElementById('copyEmailText').innerText
|
||||||
|
if (element) {
|
||||||
|
const textToCopy = element.innerHTML;
|
||||||
|
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||||
|
const detail = { type: 'success', message: copyText};
|
||||||
|
showToast(detail);
|
||||||
|
}).catch(err => {
|
||||||
|
const detail = { type: 'error', message: 'Failed to copy email' };
|
||||||
|
showToast(detail);
|
||||||
|
console.error('Copy failed:', err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("downloadFile", function (event) {
|
||||||
|
const downloadId = event.detail?.download_id;
|
||||||
|
if (!downloadId) return;
|
||||||
|
|
||||||
|
const messageContainer = document.querySelector(`#message-${downloadId}`);
|
||||||
|
if (!messageContainer) return;
|
||||||
|
|
||||||
|
const textarea = messageContainer.querySelector("textarea");
|
||||||
|
if (!textarea) return;
|
||||||
|
|
||||||
|
const content = textarea.value;
|
||||||
|
const blob = new Blob([content], { type: "message/rfc822" });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = `email-${downloadId}.eml`;
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
link.remove();
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("printFile", function (event) {
|
||||||
|
const printId = event.detail?.print_id;
|
||||||
|
if (!printId) return;
|
||||||
|
|
||||||
|
const messageContainer = document.querySelector(`#message-${printId}`);
|
||||||
|
if (!messageContainer) return;
|
||||||
|
|
||||||
|
const textarea = messageContainer.querySelector("textarea");
|
||||||
|
if (!textarea) return;
|
||||||
|
|
||||||
|
const content = textarea.value;
|
||||||
|
|
||||||
|
const printWindow = window.open('', '', 'width=800,height=600');
|
||||||
|
if (!printWindow) return;
|
||||||
|
|
||||||
|
printWindow.document.write(`
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Email Print</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: sans-serif; padding: 20px; white-space: pre-wrap; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>${content.replace(/\n/g, '<br>')}</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
|
||||||
|
printWindow.document.close();
|
||||||
|
printWindow.focus();
|
||||||
|
printWindow.print();
|
||||||
|
printWindow.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
(function detectAdBlockReal() {
|
||||||
|
const bait = document.createElement('div');
|
||||||
|
bait.className = 'adsbygoogle ad-banner ad-unit';
|
||||||
|
bait.style.cssText = 'width: 1px; height: 1px; position: absolute; left: -9999px;';
|
||||||
|
document.body.appendChild(bait);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const baitBlocked =
|
||||||
|
!bait ||
|
||||||
|
bait.offsetParent === null ||
|
||||||
|
bait.offsetHeight === 0 ||
|
||||||
|
window.getComputedStyle(bait).getPropertyValue('display') === 'none' ||
|
||||||
|
window.getComputedStyle(bait).getPropertyValue('visibility') === 'hidden';
|
||||||
|
|
||||||
|
if (baitBlocked) {
|
||||||
|
const elementShow = document.getElementById('sidebar-magic');
|
||||||
|
elementShow.classList.remove('hidden');
|
||||||
|
window.adBlockDetected = true;
|
||||||
|
} else {
|
||||||
|
window.adBlockDetected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bait.remove();
|
||||||
|
}, 100);
|
||||||
|
})();
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
|
const syncElement = document.getElementById('gR7pT9xLwQ');
|
||||||
|
const syncValue = syncElement.getAttribute('sync');
|
||||||
|
|
||||||
|
if (!syncValue) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(async function () {
|
||||||
|
|
||||||
|
let requestCount = 0;
|
||||||
|
const maxRequests = 200;
|
||||||
|
|
||||||
|
let isRequestInProgress = false;
|
||||||
|
|
||||||
|
async function fetchStoreEmail() {
|
||||||
|
if (isRequestInProgress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isRequestInProgress = true;
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
task: 'sync',
|
||||||
|
type: 'email',
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const csrfToken = document.getElementById('gR7pT9xLwQ').innerText;
|
||||||
|
const response = await fetch('/sync', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-TOKEN': csrfToken,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
requestCount++;
|
||||||
|
|
||||||
|
if (requestCount >= maxRequests) {
|
||||||
|
clearInterval(fetchInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
isRequestInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchStoreEmail();
|
||||||
|
|
||||||
|
const fetchInterval = setInterval(fetchStoreEmail, 10000);
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
|||||||
54
resources/lang/ar.json
Normal file
54
resources/lang/ar.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "صندوق الوارد",
|
||||||
|
"You are signed in as:": "أنت مسجل دخولك كـ:",
|
||||||
|
"Get back to MailBox": "ارجع إلى صندوق البريد",
|
||||||
|
"Enter Username": "أدخل اسم المستخدم",
|
||||||
|
"Select Domain": "حدد المجال",
|
||||||
|
"Create": "إنشاء",
|
||||||
|
"Random": "عشوائي",
|
||||||
|
"Custom": "مخصص",
|
||||||
|
"Menu": "القائمة",
|
||||||
|
"Cancel": "إلغاء",
|
||||||
|
"Copy": "نسخة",
|
||||||
|
"Refresh": "تحديث",
|
||||||
|
"New": "جديد",
|
||||||
|
"Delete": "حذف",
|
||||||
|
"Download": "تنزيل",
|
||||||
|
"Fetching": "جلب",
|
||||||
|
"Empty Inbox": "علبة الوارد الفارغة",
|
||||||
|
"Error": "خطأ",
|
||||||
|
"Success": "النجاح",
|
||||||
|
"Close": "إغلاق",
|
||||||
|
"Email ID Copied to Clipboard": "تم نسخ معرف البريد الإلكتروني إلى الحافظة",
|
||||||
|
"Please enter Username": "الرجاء إدخال اسم المستخدم",
|
||||||
|
"Please Select a Domain": "الرجاء تحديد نطاق",
|
||||||
|
"Username not allowed": "اسم المستخدم غير مسموح به",
|
||||||
|
"Your Temporary Email Address": "عنوان بريدك الإلكتروني المؤقت",
|
||||||
|
"Attachments": "المرفقات",
|
||||||
|
"Blocked": "محظور",
|
||||||
|
"Emails from": "رسائل البريد الإلكتروني",
|
||||||
|
"are blocked by Admin": "يتم حظرها من قبل المشرف",
|
||||||
|
"No Messages": "لا توجد رسائل",
|
||||||
|
"Waiting for Incoming Messages": "انتظار الرسائل الواردة",
|
||||||
|
"Scan QR Code to access": "مسح رمز الاستجابة السريعة للوصول",
|
||||||
|
"Create your own Temp Mail": "قم بإنشاء بريد Temp الخاص بك",
|
||||||
|
"Your Temprorary Email": "بريدك الإلكتروني المؤقت",
|
||||||
|
"Enter a Username and Select the Domain": "أدخل اسم مستخدم وحدد المجال",
|
||||||
|
"Username length cannot be less than": "لا يمكن أن يكون طول اسم المستخدم أقل من",
|
||||||
|
"and greator than": "و أكبر من",
|
||||||
|
"Create a Random Email": "إنشاء بريد إلكتروني عشوائي",
|
||||||
|
"Sender": "مرسل",
|
||||||
|
"Subject": "موضوع",
|
||||||
|
"Time": "الوقت",
|
||||||
|
"Open": "افتح",
|
||||||
|
"Go Back to Inbox": "العودة إلى علبة الوارد",
|
||||||
|
"Date": "التاريخ",
|
||||||
|
"Copyright": "حق المؤلف",
|
||||||
|
"Ad Blocker Detected": "تم الكشف عن مانع الإعلانات",
|
||||||
|
"Disable the Ad Blocker to use ": "قم بتعطيل مانع الإعلانات لاستخدامه ",
|
||||||
|
"Your temporary email address is ready": "عنوان بريدك الإلكتروني المؤقت جاهز",
|
||||||
|
"You have reached daily limit of MAX ": "لقد وصلت إلى الحد اليومي لـ MAX ",
|
||||||
|
" temp mail": " بريد مؤقت",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "آسف! تم استخدام هذا البريد الإلكتروني بالفعل من قبل شخص آخر. يرجى تجربة عنوان بريد إلكتروني مختلف.",
|
||||||
|
"Invalid Captcha. Please try again": "كلمة التحقق غير صالحة. يرجى المحاولة مرة أخرى"
|
||||||
|
}
|
||||||
54
resources/lang/de.json
Normal file
54
resources/lang/de.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Posteingang",
|
||||||
|
"You are signed in as:": "Sie sind angemeldet als:",
|
||||||
|
"Get back to MailBox": "Geh zurück zu MailBox",
|
||||||
|
"Enter Username": "Benutzername eingeben",
|
||||||
|
"Select Domain": "Wählen Sie Domäne",
|
||||||
|
"Create": "Erstellen",
|
||||||
|
"Random": "Zufällig",
|
||||||
|
"Custom": "Brauch",
|
||||||
|
"Menu": "Speisekarte",
|
||||||
|
"Cancel": "Stornieren",
|
||||||
|
"Copy": "Kopie",
|
||||||
|
"Refresh": "Aktualisieren",
|
||||||
|
"New": "Neue",
|
||||||
|
"Delete": "löschen",
|
||||||
|
"Download": "Downloaden",
|
||||||
|
"Fetching": "Abrufen",
|
||||||
|
"Empty Inbox": "Leerer Posteingang",
|
||||||
|
"Error": "Fehler",
|
||||||
|
"Success": "Erfolgreich",
|
||||||
|
"Close": "Schliessen",
|
||||||
|
"Email ID Copied to Clipboard": "E-Mail-ID in die Zwischenablage kopiert",
|
||||||
|
"Please enter Username": "Bitte geben Sie Ihren Benutzernamen",
|
||||||
|
"Please Select a Domain": "Bitte wählen Sie eine Domain",
|
||||||
|
"Username not allowed": "Benutzername ist nicht erlaubt",
|
||||||
|
"Your Temporary Email Address": "Ihre temporäre E-Mail-Adresse",
|
||||||
|
"Attachments": "Anhänge",
|
||||||
|
"Blocked": "Blockiert",
|
||||||
|
"Emails from": "E-Mails von",
|
||||||
|
"are blocked by Admin": "werden von Admin blockiert",
|
||||||
|
"No Messages": "Keine Nachrichten",
|
||||||
|
"Waiting for Incoming Messages": "Warten auf eingehende Nachrichten",
|
||||||
|
"Scan QR Code to access": "Scannen Sie den QR-Code für den Zugriff",
|
||||||
|
"Create your own Temp Mail": "Erstellen Sie Ihre eigene Temp Mail",
|
||||||
|
"Your Temprorary Email": "Ihre temporäre E-Mail",
|
||||||
|
"Enter a Username and Select the Domain": "Geben Sie einen Benutzernamen ein und wählen Sie die Domain",
|
||||||
|
"Username length cannot be less than": "Die Länge des Benutzernamens darf nicht kleiner sein als",
|
||||||
|
"and greator than": "und größer als",
|
||||||
|
"Create a Random Email": "Erstellen Sie eine zufällige E-Mail",
|
||||||
|
"Sender": "Absender",
|
||||||
|
"Subject": "Subjekt",
|
||||||
|
"Time": "Zeit",
|
||||||
|
"Open": "Offen",
|
||||||
|
"Go Back to Inbox": "Gehe zurück zum Posteingang",
|
||||||
|
"Date": "Datum",
|
||||||
|
"Copyright": "Copyright",
|
||||||
|
"Ad Blocker Detected": "Werbeblocker erkannt",
|
||||||
|
"Disable the Ad Blocker to use ": "Deaktivieren Sie den zu verwendenden Werbeblocker ",
|
||||||
|
"Your temporary email address is ready": "Ihre temporäre E-Mail-Adresse ist bereit",
|
||||||
|
"You have reached daily limit of MAX ": "Sie haben das Tageslimit von MAX erreicht ",
|
||||||
|
" temp mail": " Temporäre E-Mail",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Entschuldigung! Diese E-Mail wurde bereits von jemand anderem verwendet. Bitte versuchen Sie es mit einer anderen E-Mail-Adresse.",
|
||||||
|
"Invalid Captcha. Please try again": "Ungültiges Captcha. Bitte versuche es erneut"
|
||||||
|
}
|
||||||
54
resources/lang/en.json
Normal file
54
resources/lang/en.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Inbox",
|
||||||
|
"You are signed in as:": "You are signed in as:",
|
||||||
|
"Get back to MailBox": "Get back to MailBox",
|
||||||
|
"Enter Username": "Enter Username",
|
||||||
|
"Select Domain": "Select Domain",
|
||||||
|
"Create": "Create",
|
||||||
|
"Random": "Random",
|
||||||
|
"Custom": "Custom",
|
||||||
|
"Menu": "Menu",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Copy": "Copy",
|
||||||
|
"Refresh": "Refresh",
|
||||||
|
"New": "New",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Download": "Download",
|
||||||
|
"Fetching": "Fetching",
|
||||||
|
"Empty Inbox": "Empty Inbox",
|
||||||
|
"Error": "Error",
|
||||||
|
"Success": "Success",
|
||||||
|
"Close": "Close",
|
||||||
|
"Email ID Copied to Clipboard": "Email ID Copied to Clipboard",
|
||||||
|
"Please enter Username": "Please enter Username",
|
||||||
|
"Please Select a Domain": "Please Select a Domain",
|
||||||
|
"Username not allowed": "Username not allowed",
|
||||||
|
"Your Temporary Email Address": "Your Temporary Email Address",
|
||||||
|
"Attachments": "Attachments",
|
||||||
|
"Blocked": "Blocked",
|
||||||
|
"Emails from": "Emails from",
|
||||||
|
"are blocked by Admin": "are blocked by Admin",
|
||||||
|
"No Messages": "No Messages",
|
||||||
|
"Waiting for Incoming Messages": "Waiting for Incoming Messages",
|
||||||
|
"Scan QR Code to access": "Scan QR Code to access",
|
||||||
|
"Create your own Temp Mail": "Create your own Temp Mail",
|
||||||
|
"Your Temprorary Email": "Your Temprorary Email",
|
||||||
|
"Enter a Username and Select the Domain": "Enter a Username and Select the Domain",
|
||||||
|
"Username length cannot be less than": "Username length cannot be less than",
|
||||||
|
"and greator than": "and greator than",
|
||||||
|
"Create a Random Email": "Create a Random Email",
|
||||||
|
"Sender": "Sender",
|
||||||
|
"Subject": "Subject",
|
||||||
|
"Time": "Time",
|
||||||
|
"Open": "Open",
|
||||||
|
"Go Back to Inbox": "Go Back to Inbox",
|
||||||
|
"Date": "Date",
|
||||||
|
"Copyright": "Copyright",
|
||||||
|
"Ad Blocker Detected": "Ad Blocker Detected",
|
||||||
|
"Disable the Ad Blocker to use ": "Disable the Ad Blocker to use ",
|
||||||
|
"Your temporary email address is ready": "Your temporary email address is ready",
|
||||||
|
"You have reached daily limit of MAX ": "You have reached daily limit of MAX ",
|
||||||
|
" temp mail": " temp mail",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Sorry! That email is already been used by someone else. Please try a different email address.",
|
||||||
|
"Invalid Captcha. Please try again": "Invalid Captcha. Please try again"
|
||||||
|
}
|
||||||
54
resources/lang/es.json
Normal file
54
resources/lang/es.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Bandeja de entrada",
|
||||||
|
"You are signed in as:": "Estás registrado como:",
|
||||||
|
"Get back to MailBox": "Regresar al buzón",
|
||||||
|
"Enter Username": "Introduce tu nombre",
|
||||||
|
"Select Domain": "Seleccionar dominio",
|
||||||
|
"Create": "Crear",
|
||||||
|
"Random": "aleatorio",
|
||||||
|
"Custom": "Personalizado",
|
||||||
|
"Menu": "Menú",
|
||||||
|
"Cancel": "Cancelar",
|
||||||
|
"Copy": "Copia",
|
||||||
|
"Refresh": "Actualizar",
|
||||||
|
"New": "Nuevo",
|
||||||
|
"Delete": "Borrar",
|
||||||
|
"Download": "Descargar",
|
||||||
|
"Fetching": "Atractivo",
|
||||||
|
"Empty Inbox": "Bandeja de entrada vacía",
|
||||||
|
"Error": "Error",
|
||||||
|
"Success": "Éxito",
|
||||||
|
"Close": "Cerrar",
|
||||||
|
"Email ID Copied to Clipboard": "ID de correo electrónico copiado en el portapapeles",
|
||||||
|
"Please enter Username": "Introduce tu nombre de usuario",
|
||||||
|
"Please Select a Domain": "Seleccione un dominio",
|
||||||
|
"Username not allowed": "Nombre de usuario no permitido",
|
||||||
|
"Your Temporary Email Address": "Su dirección de correo electrónico temporal",
|
||||||
|
"Attachments": "Archivos adjuntos",
|
||||||
|
"Blocked": "Bloqueado",
|
||||||
|
"Emails from": "Correos electrónicos de",
|
||||||
|
"are blocked by Admin": "están bloqueados por el administrador",
|
||||||
|
"No Messages": "Sin mensajes",
|
||||||
|
"Waiting for Incoming Messages": "Esperando mensajes entrantes",
|
||||||
|
"Scan QR Code to access": "Escanea el código QR para acceder",
|
||||||
|
"Create your own Temp Mail": "Crea tu propio correo temporal",
|
||||||
|
"Your Temprorary Email": "Tu correo electrónico temporal",
|
||||||
|
"Enter a Username and Select the Domain": "Ingrese un nombre de usuario y seleccione el dominio",
|
||||||
|
"Username length cannot be less than": "El nombre de usuario no puede ser inferior a",
|
||||||
|
"and greator than": "y mayor que",
|
||||||
|
"Create a Random Email": "Crear un correo electrónico aleatorio",
|
||||||
|
"Sender": "Remitente",
|
||||||
|
"Subject": "Asunto",
|
||||||
|
"Time": "Tiempo",
|
||||||
|
"Open": "Abierto",
|
||||||
|
"Go Back to Inbox": "Regresar a la bandeja de entrada",
|
||||||
|
"Date": "Fecha",
|
||||||
|
"Copyright": "derechos de autor",
|
||||||
|
"Ad Blocker Detected": "Bloqueador de anuncios detectado",
|
||||||
|
"Disable the Ad Blocker to use ": "Desactivar el bloqueador de anuncios para usar ",
|
||||||
|
"Your temporary email address is ready": "Tu dirección de correo electrónico temporal está lista",
|
||||||
|
"You have reached daily limit of MAX ": "Has alcanzado el límite diario de MAX ",
|
||||||
|
" temp mail": " correo temporal",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "¡Lo siento! Ese correo electrónico ya lo ha utilizado otra persona. Prueba con otra dirección de correo electrónico.",
|
||||||
|
"Invalid Captcha. Please try again": "Captcha no válido. Inténtalo de nuevo"
|
||||||
|
}
|
||||||
54
resources/lang/fr.json
Normal file
54
resources/lang/fr.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Boîte de réception",
|
||||||
|
"You are signed in as:": "Vous êtes connecté en tant que:",
|
||||||
|
"Get back to MailBox": "Revenir à la boîte aux lettres",
|
||||||
|
"Enter Username": "Entrez votre nom",
|
||||||
|
"Select Domain": "Sélectionner un domaine",
|
||||||
|
"Create": "Créer",
|
||||||
|
"Random": "Aléatoire",
|
||||||
|
"Custom": "Personnalisé",
|
||||||
|
"Menu": "Menu",
|
||||||
|
"Cancel": "Annuler",
|
||||||
|
"Copy": "Copier",
|
||||||
|
"Refresh": "Actualiser",
|
||||||
|
"New": "Nouveau",
|
||||||
|
"Delete": "Supprimer",
|
||||||
|
"Download": "Télécharger",
|
||||||
|
"Fetching": "Récupération",
|
||||||
|
"Empty Inbox": "Boîte de réception vide",
|
||||||
|
"Error": "Erreur",
|
||||||
|
"Success": "Le succès",
|
||||||
|
"Close": "Fermer",
|
||||||
|
"Email ID Copied to Clipboard": "ID d'e-mail copié dans le presse-papiers",
|
||||||
|
"Please enter Username": "Veuillez entrer votre nom d'utilisateur",
|
||||||
|
"Please Select a Domain": "Veuillez sélectionner un domaine",
|
||||||
|
"Username not allowed": "Nom d'utilisateur non autorisé",
|
||||||
|
"Your Temporary Email Address": "Votre adresse e-mail temporaire",
|
||||||
|
"Attachments": "Pièces jointes",
|
||||||
|
"Blocked": "Bloqué",
|
||||||
|
"Emails from": "E-mails de",
|
||||||
|
"are blocked by Admin": "sont bloqués par l'administrateur",
|
||||||
|
"No Messages": "Aucun message",
|
||||||
|
"Waiting for Incoming Messages": "En attente de messages entrants",
|
||||||
|
"Scan QR Code to access": "Scannez le code QR pour y accéder",
|
||||||
|
"Create your own Temp Mail": "Créez votre propre courrier temporaire",
|
||||||
|
"Your Temprorary Email": "Votre e-mail temporaire",
|
||||||
|
"Enter a Username and Select the Domain": "Entrez un nom d'utilisateur et sélectionnez le domaine",
|
||||||
|
"Username length cannot be less than": "La longueur du nom d'utilisateur ne peut être inférieure à",
|
||||||
|
"and greator than": "et plus grand que",
|
||||||
|
"Create a Random Email": "Créer un e-mail aléatoire",
|
||||||
|
"Sender": "L'expéditeur",
|
||||||
|
"Subject": "Objet",
|
||||||
|
"Time": "Heure",
|
||||||
|
"Open": "Ouvert",
|
||||||
|
"Go Back to Inbox": "Revenir à la boîte de réception",
|
||||||
|
"Date": "Date",
|
||||||
|
"Copyright": "Copyright",
|
||||||
|
"Ad Blocker Detected": "Bloqueur de publicité détecté",
|
||||||
|
"Disable the Ad Blocker to use ": "Désactiver le bloqueur de publicités pour utiliser ",
|
||||||
|
"Your temporary email address is ready": "Votre adresse e-mail temporaire est prête",
|
||||||
|
"You have reached daily limit of MAX ": "Vous avez atteint la limite quotidienne de MAX ",
|
||||||
|
" temp mail": " courrier temporaire",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Désolé ! Cette adresse e-mail a déjà été utilisée par quelqu'un d'autre. Veuillez essayer une autre adresse e-mail.",
|
||||||
|
"Invalid Captcha. Please try again": "Captcha non valide. Veuillez réessayer"
|
||||||
|
}
|
||||||
54
resources/lang/hi.json
Normal file
54
resources/lang/hi.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "इनबॉक्स",
|
||||||
|
"You are signed in as:": "आप साइन इन हैं जैसे:",
|
||||||
|
"Get back to MailBox": "MailBox पर वापस जाएं",
|
||||||
|
"Enter Username": "यूजरनेम डालें",
|
||||||
|
"Select Domain": "डोमेन चुनें",
|
||||||
|
"Create": "सृजन करना",
|
||||||
|
"Random": "रैंडम",
|
||||||
|
"Custom": "मनपसंद",
|
||||||
|
"Menu": "मेन्यू",
|
||||||
|
"Cancel": "रद्द करना",
|
||||||
|
"Copy": "नक़ल",
|
||||||
|
"Refresh": "रिफ्रेश",
|
||||||
|
"New": "नवीन व",
|
||||||
|
"Delete": "मिटाएँ",
|
||||||
|
"Download": "डाऊलोड",
|
||||||
|
"Fetching": "ला रहा है",
|
||||||
|
"Empty Inbox": "खाली इनबॉक्स",
|
||||||
|
"Error": "एरर",
|
||||||
|
"Success": "सक्सेस",
|
||||||
|
"Close": "बन्द करें",
|
||||||
|
"Email ID Copied to Clipboard": "क्लिपबोर्ड में कॉपी की गई ईमेल आईडी",
|
||||||
|
"Please enter Username": "कृपया यूजरनेम डालें",
|
||||||
|
"Please Select a Domain": "कृपया एक डोमेन चुनें",
|
||||||
|
"Username not allowed": "उपयोगकर्ता नाम की अनुमति नहीं है",
|
||||||
|
"Your Temporary Email Address": "आपका अस्थाई ईमेल पता",
|
||||||
|
"Attachments": "अटैचमेंट",
|
||||||
|
"Blocked": "अवरोधित",
|
||||||
|
"Emails from": "से ईमेल",
|
||||||
|
"are blocked by Admin": "व्यवस्थापक द्वारा अवरोधित हैं",
|
||||||
|
"No Messages": "कोई सन्देश नहीं",
|
||||||
|
"Waiting for Incoming Messages": "आने वाले संदेशों की प्रतीक्षा कर रहा है",
|
||||||
|
"Scan QR Code to access": "एक्सेस करने के लिए QR कोड स्कैन करें",
|
||||||
|
"Create your own Temp Mail": "अपना खुद का टेम्प मेल बनाएं",
|
||||||
|
"Your Temprorary Email": "आपका अस्थायी ईमेल",
|
||||||
|
"Enter a Username and Select the Domain": "एक उपयोगकर्ता नाम दर्ज करें और डोमेन चुनें",
|
||||||
|
"Username length cannot be less than": "उपयोगकर्ता नाम की लंबाई से कम नहीं हो सकती",
|
||||||
|
"and greator than": "और अधिक से अधिक",
|
||||||
|
"Create a Random Email": "रैंडम ईमेल बनाएँ",
|
||||||
|
"Sender": "प्रेषक",
|
||||||
|
"Subject": "विषय",
|
||||||
|
"Time": "टाइम",
|
||||||
|
"Open": "ओपन",
|
||||||
|
"Go Back to Inbox": "इनबॉक्स पर वापस जाएँ",
|
||||||
|
"Date": "दिनांक",
|
||||||
|
"Copyright": "कॉपीराइट",
|
||||||
|
"Ad Blocker Detected": "विज्ञापन अवरोधक का पता चला",
|
||||||
|
"Disable the Ad Blocker to use ": "उपयोग करने के लिए विज्ञापन अवरोधक को अक्षम करें ",
|
||||||
|
"Your temporary email address is ready": "आपका अस्थायी ईमेल पता तैयार है",
|
||||||
|
"You have reached daily limit of MAX ": "आप MAX की दैनिक सीमा तक पहुँच चुके हैं ",
|
||||||
|
" temp mail": " अस्थायी मेल",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "माफ़ करना! उस ईमेल का उपयोग पहले से ही किसी और द्वारा किया जा चुका है। कृपया एक अलग ईमेल पता आज़माएं।",
|
||||||
|
"Invalid Captcha. Please try again": "अमान्य कैप्चा। कृपया फिर से कोशिश करें"
|
||||||
|
}
|
||||||
54
resources/lang/id.json
Normal file
54
resources/lang/id.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Kotak Masuk",
|
||||||
|
"You are signed in as:": "Anda masuk sebagai:",
|
||||||
|
"Get back to MailBox": "Kembali Ke Kotak Surat",
|
||||||
|
"Enter Username": "Masukkan Nama Pengguna",
|
||||||
|
"Select Domain": "Pilih Domain",
|
||||||
|
"Create": "Buat",
|
||||||
|
"Random": "Acak",
|
||||||
|
"Custom": "kustom",
|
||||||
|
"Menu": "Menu",
|
||||||
|
"Cancel": "Batal",
|
||||||
|
"Copy": "Copy",
|
||||||
|
"Refresh": "Segarkan",
|
||||||
|
"New": "Baru",
|
||||||
|
"Delete": "Hapus",
|
||||||
|
"Download": "Unduh",
|
||||||
|
"Fetching": "Fetching",
|
||||||
|
"Empty Inbox": "Kotak Masuk Kosong",
|
||||||
|
"Error": "Error",
|
||||||
|
"Success": "Suksess",
|
||||||
|
"Close": "Tutup",
|
||||||
|
"Email ID Copied to Clipboard": "Salin Email ID Ke Papan Klip",
|
||||||
|
"Please enter Username": "Silahkan Masukkan Nama Pengguna",
|
||||||
|
"Please Select a Domain": "Silahkan Pilih Domain",
|
||||||
|
"Username not allowed": "Nama Pengguna Tidak Diizinkan",
|
||||||
|
"Your Temporary Email Address": "Alamat Email Sementara Anda",
|
||||||
|
"Attachments": "Attachments",
|
||||||
|
"Blocked": "Di Blokir",
|
||||||
|
"Emails from": "Emails Dari",
|
||||||
|
"are blocked by Admin": "Di Blokir Oleh Admin",
|
||||||
|
"No Messages": "Tidak Ada Pesan",
|
||||||
|
"Waiting for Incoming Messages": "Menunggu Email Masuk",
|
||||||
|
"Scan QR Code to access": "Scan QR Code Untuk Mengakses",
|
||||||
|
"Create your own Temp Mail": "Buat Email Sementara Anda",
|
||||||
|
"Your Temprorary Email": "Email Sementara Anda",
|
||||||
|
"Enter a Username and Select the Domain": "Masukkan Nama Pengguna Dan Pilih Nama Domain",
|
||||||
|
"Username length cannot be less than": "Panjang Nama Pengguna Tidak Boleh Kurang Dari",
|
||||||
|
"and greator than": "dan lebih besar dari",
|
||||||
|
"Create a Random Email": "Bikin Email Acak",
|
||||||
|
"Sender": "Pengirim",
|
||||||
|
"Subject": "Subjek",
|
||||||
|
"Time": "Waktu",
|
||||||
|
"Open": "Buka",
|
||||||
|
"Go Back to Inbox": "kembali Ke Kotak Masuk",
|
||||||
|
"Date": "Tanggal",
|
||||||
|
"Copyright": "Copyright",
|
||||||
|
"Ad Blocker Detected": "Ad Blocker Terdeteksi",
|
||||||
|
"Disable the Ad Blocker to use ": "Nonaktifkan Ad Blocker untuk Melanjutkan ",
|
||||||
|
"Your temporary email address is ready": "Alamat Email Sementara Anda Sudah SIAP",
|
||||||
|
"You have reached daily limit of MAX ": "Anda Sudah Mencapai Batas Maksimal",
|
||||||
|
" temp mail": " Email Sementara",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Maaf! Email Tersebut Sudah digunakan oleh user lain, Silahkan mencoba dengan alamat email lain.",
|
||||||
|
"Invalid Captcha. Please try again": "Invalid Captcha. Silahkan Coba Lagi"
|
||||||
|
}
|
||||||
54
resources/lang/no.json
Normal file
54
resources/lang/no.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Innboks",
|
||||||
|
"You are signed in as:": "Du er logget inn som:",
|
||||||
|
"Get back to MailBox": "Gå tilbake til innboks",
|
||||||
|
"Enter Username": "Fyll inn brukernavn",
|
||||||
|
"Select Domain": "Velg domene",
|
||||||
|
"Create": "Opprett",
|
||||||
|
"Random": "Random",
|
||||||
|
"Custom": "Tilpass",
|
||||||
|
"Menu": "Meny",
|
||||||
|
"Cancel": "Avbryt",
|
||||||
|
"Copy": "Kopier",
|
||||||
|
"Refresh": "Oppdater",
|
||||||
|
"New": "Ny",
|
||||||
|
"Delete": "Slett",
|
||||||
|
"Download": "Last ned",
|
||||||
|
"Fetching": "Mottar",
|
||||||
|
"Empty Inbox": "Tom Innboks",
|
||||||
|
"Error": "Feil",
|
||||||
|
"Success": "Suksess",
|
||||||
|
"Close": "Lukk",
|
||||||
|
"Email ID Copied to Clipboard": "E-post-adresse kopiert til utklippstavlen",
|
||||||
|
"Please enter Username": "Vennligst fyll inn brukernavn",
|
||||||
|
"Please Select a Domain": "Vennligst velg domene",
|
||||||
|
"Username not allowed": "Brukernavn ikke tillatt",
|
||||||
|
"Your Temporary Email Address": "Din Midlertidige E-postadresse",
|
||||||
|
"Attachments": "Vedlegg",
|
||||||
|
"Blocked": "Blokkert",
|
||||||
|
"Emails from": "E-post fra",
|
||||||
|
"are blocked by Admin": "er blokkert av Admin",
|
||||||
|
"No Messages": "Ingen Meldinger",
|
||||||
|
"Waiting for Incoming Messages": "Venter på innkommende meldinger",
|
||||||
|
"Scan QR Code to access": "Skann QR Kode for tilgang",
|
||||||
|
"Create your own Temp Mail": "Opprett din egen Midlertidige E-post",
|
||||||
|
"Your Temprorary Email": "Din Mindlertidige E-post",
|
||||||
|
"Enter a Username and Select the Domain": "Fyll inn brukernavn og velg domene",
|
||||||
|
"Username length cannot be less than": "Brukernavnet kan ikke inneholde mindre enn",
|
||||||
|
"and greator than": "og mer enn",
|
||||||
|
"Create a Random Email": "Opprett tilfeldig e-post",
|
||||||
|
"Sender": "Sendt fra",
|
||||||
|
"Subject": "Tittel",
|
||||||
|
"Time": "Tid",
|
||||||
|
"Open": "Åpne",
|
||||||
|
"Go Back to Inbox": "Gå tilbake til innboks",
|
||||||
|
"Date": "Dato",
|
||||||
|
"Copyright": "Copyright",
|
||||||
|
"Ad Blocker Detected": "Annonseblokkering oppdaget",
|
||||||
|
"Disable the Ad Blocker to use ": "Deaktiver annonseblokkeringen som skal brukes ",
|
||||||
|
"Your temporary email address is ready": "Din midlertidige e-postadresse er klar",
|
||||||
|
"You have reached daily limit of MAX ": "Du har nådd en daglig grense på MAX ",
|
||||||
|
" temp mail": " temp post",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Unnskyld! Den e-posten er allerede brukt av noen andre. Prøv en annen e-postadresse.",
|
||||||
|
"Invalid Captcha. Please try again": "Ugyldig Captcha. Vennligst prøv på nytt"
|
||||||
|
}
|
||||||
54
resources/lang/pl.json
Normal file
54
resources/lang/pl.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Skrzynka odbiorcza",
|
||||||
|
"You are signed in as:": "Jesteś zalogowany jako:",
|
||||||
|
"Get back to MailBox": "Wróć do skrzynki pocztowej",
|
||||||
|
"Enter Username": "Wprowadź nazwę użytkownika",
|
||||||
|
"Select Domain": "Wybierz domenę",
|
||||||
|
"Create": "Stwórz",
|
||||||
|
"Random": "losowe",
|
||||||
|
"Custom": "Niestandardowe",
|
||||||
|
"Menu": "Menu",
|
||||||
|
"Cancel": "Anuluj",
|
||||||
|
"Copy": "Kopiuj",
|
||||||
|
"Refresh": "Odśwież",
|
||||||
|
"New": "Nowość",
|
||||||
|
"Delete": "Usuń",
|
||||||
|
"Download": "Pobierz",
|
||||||
|
"Fetching": "Pobieranie",
|
||||||
|
"Empty Inbox": "Puste Skrzynka",
|
||||||
|
"Error": "Błąd",
|
||||||
|
"Success": "Sukces",
|
||||||
|
"Close": "Zamknij",
|
||||||
|
"Email ID Copied to Clipboard": "Identyfikator e-mail skopiowany do schowka",
|
||||||
|
"Please enter Username": "Podaj nazwę użytkownika",
|
||||||
|
"Please Select a Domain": "Wybierz domenę",
|
||||||
|
"Username not allowed": "Nazwa użytkownika niedozwolona",
|
||||||
|
"Your Temporary Email Address": "Twój tymczasowy adres e-mail",
|
||||||
|
"Attachments": "Załączniki",
|
||||||
|
"Blocked": "Blokowane",
|
||||||
|
"Emails from": "E-maile od",
|
||||||
|
"are blocked by Admin": "są blokowane przez administratora",
|
||||||
|
"No Messages": "Brak wiadomości",
|
||||||
|
"Waiting for Incoming Messages": "Oczekiwanie na wiadomości przychodzących",
|
||||||
|
"Scan QR Code to access": "Zeskanuj kod QR, aby uzyskać dostęp",
|
||||||
|
"Create your own Temp Mail": "Stwórz własną pocztę tymczasową",
|
||||||
|
"Your Temprorary Email": "Twój Temprorary Email",
|
||||||
|
"Enter a Username and Select the Domain": "Wprowadź nazwę użytkownika i wybierz domenę",
|
||||||
|
"Username length cannot be less than": "Długość nazwy użytkownika nie może być mniejsza niż",
|
||||||
|
"and greator than": "i greator niż",
|
||||||
|
"Create a Random Email": "Utwórz losową wiadomość e-mail",
|
||||||
|
"Sender": "Nadawca",
|
||||||
|
"Subject": "Temat",
|
||||||
|
"Time": "Czas",
|
||||||
|
"Open": "Otwórz",
|
||||||
|
"Go Back to Inbox": "Wróć do skrzynki odbiorczej",
|
||||||
|
"Date": "Data",
|
||||||
|
"Copyright": "Prawo autorskie",
|
||||||
|
"Ad Blocker Detected": "Wykryto blokowanie reklam",
|
||||||
|
"Disable the Ad Blocker to use ": "Wyłącz bloker reklam w celu użycia ",
|
||||||
|
"Your temporary email address is ready": "Twój tymczasowy adres e-mail jest gotowy",
|
||||||
|
"You have reached daily limit of MAX ": "Osiągnąłeś dzienny limit MAX ",
|
||||||
|
" temp mail": " tymczasowa poczta",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Przepraszam! Ten e-mail jest już używany przez kogoś innego. Wypróbuj inny adres e-mail.",
|
||||||
|
"Invalid Captcha. Please try again": "Nieprawidłowy Captcha. Proszę spróbować ponownie"
|
||||||
|
}
|
||||||
54
resources/lang/ru.json
Normal file
54
resources/lang/ru.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Входящие",
|
||||||
|
"You are signed in as:": "Вы вошли как:",
|
||||||
|
"Get back to MailBox": "Вернитесь в Mailbox",
|
||||||
|
"Enter Username": "Введите имя пользователя",
|
||||||
|
"Select Domain": "Выберите домен",
|
||||||
|
"Create": "Создайте",
|
||||||
|
"Random": "Случайный",
|
||||||
|
"Custom": "Пользовательский",
|
||||||
|
"Menu": "меню",
|
||||||
|
"Cancel": "Отмена",
|
||||||
|
"Copy": "Копировать",
|
||||||
|
"Refresh": "Обновить",
|
||||||
|
"New": "Новый",
|
||||||
|
"Delete": "Удалить",
|
||||||
|
"Download": "Загрузить",
|
||||||
|
"Fetching": "Выбивка",
|
||||||
|
"Empty Inbox": "Пустой почтовый ящик",
|
||||||
|
"Error": "ошибка",
|
||||||
|
"Success": "Успех",
|
||||||
|
"Close": "Закрыть",
|
||||||
|
"Email ID Copied to Clipboard": "Идентификатор электронной почты скопирован в буфер обмена",
|
||||||
|
"Please enter Username": "Пожалуйста, введите имя пользователя",
|
||||||
|
"Please Select a Domain": "Пожалуйста, выберите домен",
|
||||||
|
"Username not allowed": "Имя пользователя не разрешено",
|
||||||
|
"Your Temporary Email Address": "Ваш временный адрес электронной почты",
|
||||||
|
"Attachments": "Вложения",
|
||||||
|
"Blocked": "Заблокировано",
|
||||||
|
"Emails from": "Письма от",
|
||||||
|
"are blocked by Admin": "заблокированы администратором",
|
||||||
|
"No Messages": "Нет сообщений",
|
||||||
|
"Waiting for Incoming Messages": "Ожидание входящих сообщений",
|
||||||
|
"Scan QR Code to access": "Отсканируйте QR-код для доступа",
|
||||||
|
"Create your own Temp Mail": "Создайте свою собственную Temp Mail",
|
||||||
|
"Your Temprorary Email": "Ваш временный адрес электронной почты",
|
||||||
|
"Enter a Username and Select the Domain": "Введите имя пользователя и выберите домен",
|
||||||
|
"Username length cannot be less than": "Длина имени пользователя не может быть меньше",
|
||||||
|
"and greator than": "и больше, чем",
|
||||||
|
"Create a Random Email": "Создайте случайное письмо",
|
||||||
|
"Sender": "Отправитель",
|
||||||
|
"Subject": "Тема",
|
||||||
|
"Time": "Время",
|
||||||
|
"Open": "Открыть",
|
||||||
|
"Go Back to Inbox": "Вернуться в папку «Входящие»",
|
||||||
|
"Date": "Дата",
|
||||||
|
"Copyright": "авторское",
|
||||||
|
"Ad Blocker Detected": "Обнаружен блокировщик рекламы",
|
||||||
|
"Disable the Ad Blocker to use ": "Отключите блокировщик рекламы для использования ",
|
||||||
|
"Your temporary email address is ready": "Ваш временный адрес электронной почты готов",
|
||||||
|
"You have reached daily limit of MAX ": "Вы достигли суточного лимита MAX ",
|
||||||
|
" temp mail": " временная почта",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Извините! Этим письмом уже воспользовался кто-то другой. Пожалуйста, укажите другой адрес электронной почты.",
|
||||||
|
"Invalid Captcha. Please try again": "Неверная капча. Пожалуйста, попробуйте еще раз"
|
||||||
|
}
|
||||||
54
resources/lang/tr.json
Normal file
54
resources/lang/tr.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Gelen Kutusu",
|
||||||
|
"You are signed in as:": "Oturum açtığınız kişi:",
|
||||||
|
"Get back to MailBox": "MailBox'a geri dön",
|
||||||
|
"Enter Username": "Kullanıcı Adı Girin",
|
||||||
|
"Select Domain": "Alan Adı Seç",
|
||||||
|
"Create": "Oluştur",
|
||||||
|
"Random": "Rastgele",
|
||||||
|
"Custom": "Özel",
|
||||||
|
"Menu": "Menü",
|
||||||
|
"Cancel": "İptal",
|
||||||
|
"Copy": "Kopya",
|
||||||
|
"Refresh": "Yenile",
|
||||||
|
"New": "Yeni",
|
||||||
|
"Delete": "Sil",
|
||||||
|
"Download": "İndir",
|
||||||
|
"Fetching": "Gedirme",
|
||||||
|
"Empty Inbox": "Boş Gelen Kutusu",
|
||||||
|
"Error": "Hata",
|
||||||
|
"Success": "Başarı",
|
||||||
|
"Close": "Kapat",
|
||||||
|
"Email ID Copied to Clipboard": "E-posta Kimliği Panoya Kopyalandı",
|
||||||
|
"Please enter Username": "Lütfen Kullanıcı Adı girin",
|
||||||
|
"Please Select a Domain": "Lütfen Bir Alan Adı Seçiniz",
|
||||||
|
"Username not allowed": "Kullanıcı adı izin verilmiyor",
|
||||||
|
"Your Temporary Email Address": "Geçici E-posta Adresiniz",
|
||||||
|
"Attachments": "Ekler",
|
||||||
|
"Blocked": "Engellendi",
|
||||||
|
"Emails from": "E-postalar",
|
||||||
|
"are blocked by Admin": "Admin tarafından engellendi",
|
||||||
|
"No Messages": "Mesaj Yok",
|
||||||
|
"Waiting for Incoming Messages": "Gelen Mesajları Bekleme",
|
||||||
|
"Scan QR Code to access": "Erişim için QR Kodunu tarayın",
|
||||||
|
"Create your own Temp Mail": "Kendi Temp Mail'inizi Oluşturun",
|
||||||
|
"Your Temprorary Email": "Geçici E-postanız",
|
||||||
|
"Enter a Username and Select the Domain": "Bir Kullanıcı Adı Girin ve Etki Alanını Seçin",
|
||||||
|
"Username length cannot be less than": "Kullanıcı adı uzunluğu",
|
||||||
|
"and greator than": "ve greator",
|
||||||
|
"Create a Random Email": "Rastgele E-posta Oluşturma",
|
||||||
|
"Sender": "Gönderen",
|
||||||
|
"Subject": "Konu",
|
||||||
|
"Time": "Zaman",
|
||||||
|
"Open": "Aç",
|
||||||
|
"Go Back to Inbox": "Gelen Kutusuna Geri Dön",
|
||||||
|
"Date": "Tarih",
|
||||||
|
"Copyright": "Telif hakkı",
|
||||||
|
"Ad Blocker Detected": "Reklam Engelleyici Algılandı",
|
||||||
|
"Disable the Ad Blocker to use ": "Kullanmak için Reklam Engelleyiciyi devre dışı bırakın ",
|
||||||
|
"Your temporary email address is ready": "Geçici e-posta adresiniz hazır",
|
||||||
|
"You have reached daily limit of MAX ": "Günlük MAX sınırına ulaştınız ",
|
||||||
|
" temp mail": " geçici posta",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Üzgünüm! Bu e-posta zaten başka biri tarafından kullanılmış. Lütfen farklı bir e-posta adresi deneyin.",
|
||||||
|
"Invalid Captcha. Please try again": "Geçersiz Captcha. Lütfen tekrar deneyin"
|
||||||
|
}
|
||||||
54
resources/lang/vi.json
Normal file
54
resources/lang/vi.json
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"Inbox": "Hộp thư đến",
|
||||||
|
"You are signed in as:": "Bạn đã đăng nhập dưới tên:",
|
||||||
|
"Get back to MailBox": "Quay lại Mailbox",
|
||||||
|
"Enter Username": "Nhập tên người dùng",
|
||||||
|
"Select Domain": "Chọn tên miền",
|
||||||
|
"Create": "Tạo",
|
||||||
|
"Random": "Ngẫu nhiên",
|
||||||
|
"Custom": "Tùy chỉnh",
|
||||||
|
"Menu": "Menu",
|
||||||
|
"Cancel": "Hủy",
|
||||||
|
"Copy": "Sao chép",
|
||||||
|
"Refresh": "Làm mới",
|
||||||
|
"New": "Mới",
|
||||||
|
"Delete": "Xoá",
|
||||||
|
"Download": "Tải xuống",
|
||||||
|
"Fetching": "Lấy",
|
||||||
|
"Empty Inbox": "Hộp thư đến trống",
|
||||||
|
"Error": "Lỗi",
|
||||||
|
"Success": "Thành công",
|
||||||
|
"Close": "Đóng",
|
||||||
|
"Email ID Copied to Clipboard": "Email ID được sao chép vào bảng tạm",
|
||||||
|
"Please enter Username": "Vui lòng nhập tên người dùng",
|
||||||
|
"Please Select a Domain": "Vui lòng chọn một tên miền",
|
||||||
|
"Username not allowed": "Tên người dùng không được phép",
|
||||||
|
"Your Temporary Email Address": "Địa chỉ email tạm thời của bạn",
|
||||||
|
"Attachments": "Phần đính kèm",
|
||||||
|
"Blocked": "Bị chặn",
|
||||||
|
"Emails from": "Email từ",
|
||||||
|
"are blocked by Admin": "bị chặn bởi Admin",
|
||||||
|
"No Messages": "Không có tin nhắn",
|
||||||
|
"Waiting for Incoming Messages": "Đang chờ tin nhắn đến",
|
||||||
|
"Scan QR Code to access": "Quét mã QR để truy cập",
|
||||||
|
"Create your own Temp Mail": "Tạo Thư tạm thời của riêng bạn",
|
||||||
|
"Your Temprorary Email": "Email tạm thời của bạn",
|
||||||
|
"Enter a Username and Select the Domain": "Nhập tên người dùng và chọn tên miền",
|
||||||
|
"Username length cannot be less than": "Độ dài tên người dùng không thể nhỏ hơn",
|
||||||
|
"and greator than": "và greator hơn",
|
||||||
|
"Create a Random Email": "Tạo Email Ngẫu nhiên",
|
||||||
|
"Sender": "Người gửi",
|
||||||
|
"Subject": "Subject",
|
||||||
|
"Time": "Thời gian",
|
||||||
|
"Open": "Mở",
|
||||||
|
"Go Back to Inbox": "Quay lại Hộp thư đến",
|
||||||
|
"Date": "Ngày",
|
||||||
|
"Copyright": "Bản quyền",
|
||||||
|
"Ad Blocker Detected": "Đã phát hiện Quảng cáo Blocker",
|
||||||
|
"Disable the Ad Blocker to use ": "Tắt Trình chặn quảng cáo để sử dụng ",
|
||||||
|
"Your temporary email address is ready": "Địa chỉ email tạm thời của bạn đã sẵn sàng",
|
||||||
|
"You have reached daily limit of MAX ": "Bạn đã đạt đến giới hạn hàng ngày của MAX ",
|
||||||
|
" temp mail": " thư tạm thời",
|
||||||
|
"Sorry! That email is already been used by someone else. Please try a different email address.": "Xin lỗi! Email đó đã được người khác sử dụng. Vui lòng thử một địa chỉ email khác.",
|
||||||
|
"Invalid Captcha. Please try again": "Captcha không hợp lệ. Vui lòng thử lại"
|
||||||
|
}
|
||||||
@@ -2,67 +2,118 @@
|
|||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<title>{{ $title ?? 'Page Title' }}</title>
|
<title>@yield('title', config('app.settings.app_title'))</title>
|
||||||
|
<meta name="description" content="@yield('description', config('app.settings.app_description'))">
|
||||||
|
<meta name="keywords" content="@yield('keywords', config('app.settings.app_keyword'))">
|
||||||
|
@forelse (json_decode(config('app.settings.app_meta')) as $key => $value)
|
||||||
|
@if ($value)
|
||||||
|
<meta name="{{ $key }}" content="{{ $value }}">
|
||||||
|
@endif
|
||||||
|
@empty
|
||||||
|
@endforelse
|
||||||
|
|
||||||
|
@yield('metas')
|
||||||
|
|
||||||
@if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot')))
|
@if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot')))
|
||||||
@vite(['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/js/boil.js'])
|
@vite(['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/js/boil.js'])
|
||||||
@endif
|
@endif
|
||||||
<link rel="icon" type="image/png" href="{{ asset('images/logo.webp') }}">
|
<link rel="icon" type="image/png" href="{{ asset('images/logo.webp') }}">
|
||||||
@fluxAppearance
|
@fluxAppearance
|
||||||
|
{!! config('app.settings.app_header') !!}
|
||||||
|
@yield('custom_header')
|
||||||
</head>
|
</head>
|
||||||
<body class="min-h-screen bg-white dark:bg-zinc-800">
|
<body class="min-h-screen bg-white dark:bg-zinc-800">
|
||||||
<flux:sidebar sticky stashable class="bg-zinc-50 dark:bg-zinc-900 border-r rtl:border-r-0 rtl:border-l border-zinc-200 dark:border-zinc-700">
|
<flux:sidebar sticky stashable class="bg-zinc-50 dark:bg-zinc-900 border-r rtl:border-r-0 rtl:border-l border-zinc-200 dark:border-zinc-700">
|
||||||
<flux:sidebar.toggle class="lg:hidden" icon="x-mark" />
|
<flux:sidebar.toggle class="lg:hidden" icon="x-mark" />
|
||||||
<div class="flex items-center px-2 py-2 cursor-pointer" onclick="window.location.href='{{ route('home') }}'">
|
<a class="flex items-center px-2 py-2 cursor-pointer" href="{{ route('home') }}">
|
||||||
<img src="{{ asset('images/zemail-logo-light.webp') }}" class="dark:hidden" alt="logo"/>
|
<img src="{{ asset('images/zemail-logo-light.webp') }}" class="dark:hidden" alt="logo"/>
|
||||||
<img src="{{ asset('images/zemail-logo-dark.webp') }}" class="hidden dark:flex" alt="logo"/>
|
<img src="{{ asset('images/zemail-logo-dark.webp') }}" class="hidden dark:flex" alt="logo"/>
|
||||||
|
</a>
|
||||||
</div>
|
|
||||||
|
|
||||||
<flux:navlist variant="outline">
|
<flux:navlist variant="outline">
|
||||||
<flux:button class="cursor-pointer inbox-btn" variant="filled" icon="inbox" x-on:click="$dispatch('getEmail')">Inbox</flux:button>
|
<flux:button class="cursor-pointer inbox-btn" variant="filled" icon="inbox" x-on:click="window.location.href = '{{ route('mailbox') }}'">{{ __('Inbox') }}</flux:button>
|
||||||
<flux:button class="mt-2 cursor-pointer" variant="filled" icon="refresh-cw" x-on:click="$dispatch('fetchMessages')">Refresh</flux:button>
|
<button type="button" class="relative items-center font-medium justify-center gap-2 whitespace-nowrap disabled:opacity-75 dark:disabled:opacity-75 disabled:cursor-default disabled:pointer-events-none h-10 text-sm rounded-lg px-4 inline-flex bg-zinc-800/5 hover:bg-zinc-800/10 dark:bg-white/10 dark:hover:bg-white/20 text-zinc-800 dark:text-white [[data-flux-button-group]_&]:border-e [:is([data-flux-button-group]>&:last-child,_[data-flux-button-group]_:last-child>&)]:border-e-0 [[data-flux-button-group]_&]:border-zinc-200/80 dark:[[data-flux-button-group]_&]:border-zinc-900/50 mt-2 cursor-pointer" data-flux-button="data-flux-button" data-flux-group-target="data-flux-group-target" x-on:click="Livewire.dispatch('fetchMessages'); document.getElementById('refresh-icon').classList.add('animate-spin')">
|
||||||
|
<svg id="refresh-icon" class="shrink-0 [:where(&)]:size-4" data-flux-icon="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" data-slot="icon">
|
||||||
|
<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
|
||||||
|
<path d="M21 3v5h-5"></path>
|
||||||
|
<path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path>
|
||||||
|
<path d="M8 16H3v5"></path>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{{ __('Refresh') }}
|
||||||
|
</button>
|
||||||
</flux:navlist>
|
</flux:navlist>
|
||||||
<img src="https://placehold.co/300x250?font=roboto" alt="sideAds" />
|
<div id="sidebar-magic" class="items-center border-1 dark:border-zinc-800 border-zinc-200 hidden">
|
||||||
|
<p class="px-6 py-4 text-sm dark:bg-zinc-900 bg-zinc-100 dark:text-white accent-zinc-700">Support us by disabling ad blockеrs on our site 🙏</p>
|
||||||
|
</div>
|
||||||
|
<div class="magic-box">
|
||||||
|
{!! json_decode(config('app.settings.ads_settings'))->one !!}
|
||||||
|
</div>
|
||||||
<flux:spacer />
|
<flux:spacer />
|
||||||
<flux:navlist variant="outline">
|
<flux:navlist variant="outline">
|
||||||
<flux:navlist.item href="#">API</flux:navlist.item>
|
@if(config('app.menus'))
|
||||||
<flux:navlist.item href="#">FAQ</flux:navlist.item>
|
@foreach(config('app.menus') as $menu)
|
||||||
<flux:navlist.item href="#">Privacy</flux:navlist.item>
|
<a href="{{ $menu->url }}" class="h-10 lg:h-8 relative flex items-center gap-3 rounded-lg py-0 text-start w-full px-3 my-px text-zinc-500 dark:text-white/80 data-current:text-(--color-accent-content) hover:data-current:text-(--color-accent-content) data-current:bg-white dark:data-current:bg-white/[7%] data-current:border data-current:border-zinc-200 dark:data-current:border-transparent hover:text-zinc-800 dark:hover:text-white dark:hover:bg-white/[7%] hover:bg-zinc-800/5 border border-transparent" data-flux-navlist-item="data-flux-navlist-item" @if ($menu->new_tab == 1) target="_blank" @endif>
|
||||||
<flux:navlist.item href="#">Feedback</flux:navlist.item>
|
<div class="flex-1 text-sm font-medium leading-none whitespace-nowrap [[data-nav-footer]_&]:hidden [[data-nav-sidebar]_[data-nav-footer]_&]:block" data-content="">{{ $menu->name }}</div>
|
||||||
<flux:navlist.item href="#">Contacts</flux:navlist.item>
|
</a>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
<flux:separator variant="subtle" />
|
<flux:separator variant="subtle" />
|
||||||
</flux:navlist>
|
</flux:navlist>
|
||||||
<p>© {{ config('app.settings.app_name') }}</p>
|
<p class="text-sm font-medium dark:text-white accent-zinc-700">© 2020–{{ date('Y') }} – All Rights Reserved {{ config('app.settings.app_name') }} | Coded with ♥️</p>
|
||||||
</flux:sidebar>
|
</flux:sidebar>
|
||||||
|
|
||||||
<flux:header sticky container class="bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700">
|
<flux:header sticky container class="bg-zinc-50 dark:bg-zinc-900 border-b border-zinc-200 dark:border-zinc-700">
|
||||||
<flux:sidebar.toggle class="lg:hidden" icon="bars-3" inset="left" />
|
<div class="flex items-center w-full gap-4">
|
||||||
|
<div class="flex items-center gap-2 flex-grow overflow-hidden">
|
||||||
|
<flux:sidebar.toggle class="lg:hidden" icon="bars-3-bottom-left" inset="left" />
|
||||||
<flux:separator vertical class="lg:hidden lg:mx-0 mx-3" />
|
<flux:separator vertical class="lg:hidden lg:mx-0 mx-3" />
|
||||||
<flux:icon.mail variant="mini"/>
|
<flux:icon.mail variant="mini"/>
|
||||||
|
<div class="min-w-0 overflow-hidden">
|
||||||
<livewire:frontend.email type="header"/>
|
<livewire:frontend.email type="header"/>
|
||||||
<flux:spacer />
|
</div>
|
||||||
<flux:navbar class="me-4">
|
</div>
|
||||||
|
<div class="flex items-center gap-2 flex-shrink-0">
|
||||||
|
<flux:navbar>
|
||||||
|
<flux:dropdown position="top" align="start">
|
||||||
<flux:tooltip content="Language">
|
<flux:tooltip content="Language">
|
||||||
<flux:button x-data x-on:click="" icon="language" variant="subtle" aria-label="Language" />
|
<flux:button x-data x-on:click="" icon="language" variant="subtle" aria-label="Language" />
|
||||||
</flux:tooltip>
|
</flux:tooltip>
|
||||||
|
<flux:menu>
|
||||||
|
<span>
|
||||||
|
@foreach(config('app.locales') as $item => $language)
|
||||||
|
<span x-on:click="window.location.href ='{{ route('locale', $language) }}'" role="menuitem" class="cursor-pointer group dark:hover:bg-zinc-600/75 dark:hover:text-gray-300 dark:focus:bg-zinc-600/75 dark:focus:text-gray-300 flex items-center px-4 py-2 dark:text-gray-400 text-gray-700 hover:text-gray-900 focus:text-gray-900 text-sm leading-5 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none truncate">{{ config('app.locales_text')[$item] }}</span>
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
</flux:menu>
|
||||||
|
</flux:dropdown>
|
||||||
|
|
||||||
<flux:tooltip content="Switch Theme">
|
<flux:tooltip content="Switch Theme">
|
||||||
<flux:button x-data x-on:click="$flux.dark = ! $flux.dark" icon="moon" variant="subtle" aria-label="Toggle dark mode" />
|
<flux:button x-on:click="$flux.dark = ! $flux.dark" icon="sun" variant="subtle" aria-label="Toggle dark mode">
|
||||||
|
{{-- <flux:icon.sun x-show="$flux.appearance === 'dark'" variant="mini" />--}}
|
||||||
|
{{-- <flux:icon.moon x-show="$flux.appearance === 'light'" variant="mini" />--}}
|
||||||
|
{{-- <flux:icon.computer-desktop x-show="$flux.appearance === 'system'" variant="mini" />--}}
|
||||||
|
</flux:button>
|
||||||
</flux:tooltip>
|
</flux:tooltip>
|
||||||
<flux:dropdown position="top" align="start">
|
<flux:dropdown position="top" align="start">
|
||||||
|
<flux:tooltip content="Account">
|
||||||
<flux:button icon="circle-user-round" variant="subtle" aria-label="Account" />
|
<flux:button icon="circle-user-round" variant="subtle" aria-label="Account" />
|
||||||
|
</flux:tooltip>
|
||||||
<flux:menu>
|
<flux:menu>
|
||||||
<flux:text class="p-1">You are signed in as:</flux:text>
|
<flux:text class="p-1">{{ __('You are signed in as:') }}</flux:text>
|
||||||
<div wire:ignore>
|
<div wire:ignore>
|
||||||
<livewire:frontend.email />
|
<livewire:frontend.email />
|
||||||
</div>
|
</div>
|
||||||
<flux:menu.separator />
|
<flux:menu.separator />
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<flux:modal.trigger name="create-account">
|
<flux:modal.trigger name="create-account">
|
||||||
<flux:button class="p-1 w-full" variant="outline" icon="mail-plus" style="">Create Account</flux:button>
|
<flux:button class="p-1 w-full" variant="outline" icon="mail-plus" style="">{{ __('New') }}</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
<flux:modal.trigger name="delete-account">
|
<flux:modal.trigger name="delete-account">
|
||||||
<flux:tooltip content="Delete Account">
|
<flux:tooltip content="{{ __('Delete') }}">
|
||||||
<flux:button class="ml-1 p-1" icon="trash" variant="outline" style="color:#F14743;"></flux:button>
|
<flux:button class="ml-1 p-1" icon="trash" variant="outline" style="color:#F14743;"></flux:button>
|
||||||
</flux:tooltip>
|
</flux:tooltip>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
@@ -70,9 +121,8 @@
|
|||||||
</flux:menu>
|
</flux:menu>
|
||||||
</flux:dropdown>
|
</flux:dropdown>
|
||||||
</flux:navbar>
|
</flux:navbar>
|
||||||
|
</div>
|
||||||
</flux:header>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<flux:modal name="create-account" class="md:w-96">
|
<flux:modal name="create-account" class="md:w-96">
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
@@ -80,9 +130,7 @@
|
|||||||
<flux:heading size="lg">Generate Your Temporary Email</flux:heading>
|
<flux:heading size="lg">Generate Your Temporary Email</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<livewire:frontend.action action="customEmail" />
|
<livewire:frontend.action action="customEmail" />
|
||||||
|
|
||||||
<flux:separator text="or" />
|
<flux:separator text="or" />
|
||||||
|
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
@@ -114,14 +162,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</flux:modal>
|
</flux:modal>
|
||||||
|
</flux:header>
|
||||||
|
|
||||||
<flux:main class="dark:bg-gray-900 bg-gray-100">
|
<flux:main class="dark:bg-gray-900 bg-gray-100">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
|
<div class="magic-box mt-3">
|
||||||
|
{!! json_decode(config('app.settings.ads_settings'))->two !!}
|
||||||
|
</div>
|
||||||
</flux:main>
|
</flux:main>
|
||||||
<!-- Toast Container -->
|
<!-- Toast Container -->
|
||||||
|
|
||||||
<div id="toast-container" class="fixed top-5 left-1/2 transform -translate-x-1/2 z-50 space-y-4"></div>
|
<div id="toast-container" class="fixed top-5 left-1/2 transform -translate-x-1/2 z-50 space-y-4"></div>
|
||||||
|
<p class="ionize hidden" id="gR7pT9xLwQ" sync="{{ config('app.auto_fetch_mail') }}">{{ csrf_token() }}</p>
|
||||||
|
<p class="hidden" id="copyEmailText">{{ __('Email ID Copied to Clipboard') }}</p>
|
||||||
@fluxScripts
|
@fluxScripts
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const email = '{{ App\Models\ZEmail::getEmail(true) }}';
|
||||||
|
const add_mail_in_title = "{{ json_decode(config('app.settings.configuration_settings'))->add_mail_in_title ? 'yes' : 'no' }}"
|
||||||
|
if(add_mail_in_title === 'yes') {
|
||||||
|
document.title += ` - ${email}`;
|
||||||
|
}
|
||||||
|
Livewire.dispatch('updateEmail');
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
document.addEventListener('stopLoader', () => {
|
||||||
|
document.querySelectorAll('#refresh-icon').forEach(el => {
|
||||||
|
setTimeout(() => {
|
||||||
|
el.classList.remove('animate-spin');
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let counter = parseInt({{ json_decode(config('app.settings.configuration_settings'))->fetch_seconds }});
|
||||||
|
setInterval(() => {
|
||||||
|
if (counter === 0 && document.getElementById('imap-error') === null && !document.hidden) {
|
||||||
|
document.querySelectorAll('#refresh-icon').forEach(el => {
|
||||||
|
el.classList.add('animate-spin');
|
||||||
|
});
|
||||||
|
Livewire.dispatch('fetchMessages');
|
||||||
|
counter = parseInt({{ json_decode(config('app.settings.configuration_settings'))->fetch_seconds }});
|
||||||
|
}
|
||||||
|
counter--;
|
||||||
|
if(document.hidden) {
|
||||||
|
counter = 1;
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{!! config('app.settings.app_footer') !!}
|
||||||
|
@yield('custom_header')
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
31
resources/views/livewire/blog.blade.php
Normal file
31
resources/views/livewire/blog.blade.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
@section('title'){{ $postDetail->post }} | {{ config('app.settings.app_name') }} Blog @endsection
|
||||||
|
@section('metas')
|
||||||
|
@forelse ($postDetail->meta as $key => $value)
|
||||||
|
@if ($value)
|
||||||
|
<meta name="{{ $key }}" content="{{ $value }}">
|
||||||
|
@endif
|
||||||
|
@empty
|
||||||
|
@endforelse
|
||||||
|
@endsection
|
||||||
|
@section('custom_header')
|
||||||
|
@if(!empty($postDetail->custom_header))
|
||||||
|
{!! $postDetail->custom_header !!}
|
||||||
|
@endif
|
||||||
|
@endsection
|
||||||
|
<main>
|
||||||
|
<flux:heading class="mb-3 truncate" size="xl" level="1">{{ $postDetail->post }}</flux:heading>
|
||||||
|
<div class="mb-3"></div>
|
||||||
|
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 items-center p-1">
|
||||||
|
<span class="w-full">
|
||||||
|
<img class="min-w-full px-4 pt-4 sm:pt-6 sm:px-6 rounded-tl-4xl rounded-tr-4xl rounded-bl-3xl rounded-br-3xl" src="{{ asset('storage/'.$postDetail->post_image) }}" alt="{{ $postDetail->post }}" />
|
||||||
|
</span>
|
||||||
|
<div class="magic-box my-2 px-4 sm:px-6 min-w-full flex flex-col items-center overflow-auto">
|
||||||
|
{!! json_decode(config('app.settings.ads_settings'))->two !!}
|
||||||
|
</div>
|
||||||
|
<div class="flex w-full items-center justify-center px-4 py-2 sm:px-6">
|
||||||
|
<flux:text>{!! $postDetail->content !!}</flux:text>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
<div class="-mx-2">
|
|
||||||
<nav class="flex items-center">
|
|
||||||
<flux:icon.chevron-left variant="mini"/>
|
|
||||||
<flux:text>Back</flux:text>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="mt-2 md:flex md:items-center md:justify-between">
|
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<h2 class="dark:text-gray-300 text-gray-900 text-2xl font-bold leading-7 sm:truncate">
|
|
||||||
Resend Verification Email
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-shrink-0 mt-4 overflow-y-auto md:ml-4 md:mt-0 gap-2">
|
|
||||||
<flux:button iconVariant="mini" iconLeading="download">Download</flux:button>
|
|
||||||
<flux:button iconVariant="mini" iconLeading="file">Source</flux:button>
|
|
||||||
<flux:button iconVariant="mini" iconLeading="printer">Print</flux:button>
|
|
||||||
<flux:button iconVariant="mini" iconLeading="trash">Delete</flux:button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-4 px-4 py-5 bg-white border-b border-gray-200 dark:border-gray-900 shadow overflow-hidden sm:px-6 sm:rounded-md">
|
|
||||||
<div class="flex flex-wrap items-center justify-between -ml-4 -mt-4 sm:flex-nowrap">
|
|
||||||
<div class="ml-4 mt-4">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<img src="{{ asset('images/user.webp') }}" class="size-12" alt="inbox-logo" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-4">
|
|
||||||
<div class="text-gray-700 text-lg font-medium leading-6">
|
|
||||||
Fake-IT
|
|
||||||
<span class="text-gray-700 text-sm font-normal leading-5">register@receivefreesms.co.uk</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mt-2 text-gray-500 text-sm leading-5">
|
|
||||||
<svg fill="currentColor" viewBox="0 0 20 20" class="flex-shrink-0 mr-1.5 w-5 h-5 text-gray-400">
|
|
||||||
<path fill-rule="evenodd" d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
<span class="truncate"><a href="mailto:czxcc@oakon.com"
|
|
||||||
class="ml-1">czxcc@oakon.com;</a></span></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-shrink-0 ml-4 mt-4">
|
|
||||||
<time datetime="2025-04-24T10:11:55+00:00" class="text-gray-500 truncate">
|
|
||||||
16 minutes ago
|
|
||||||
</time>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-4 py-5 sm:px-6">
|
|
||||||
<iframe src="https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ?si=fAMHSQ_S73NGoCMX" class="w-full iframe-min-height">
|
|
||||||
|
|
||||||
</iframe>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<span>
|
<span>
|
||||||
@if($action == "random")
|
@if($action == "random")
|
||||||
<flux:button wire:click="random()" class="cursor-pointer w-full btn-primary" type="submit" variant="filled">Random Email</flux:button>
|
<flux:button wire:click="random()" class="cursor-pointer w-full btn-primary" type="submit" variant="filled">{{ __('Random') }} Email</flux:button>
|
||||||
@elseif($action == "gmail")
|
@elseif($action == "gmail")
|
||||||
<flux:button wire:click="gmail()" class="cursor-pointer w-full ml-2 btn-warning" type="submit" variant="filled">Disposable Gmail</flux:button>
|
<flux:button wire:click="gmail()" class="cursor-pointer w-full ml-2 btn-warning" type="submit" variant="filled">Disposable Gmail</flux:button>
|
||||||
@elseif($action == "delete")
|
@elseif($action == "delete")
|
||||||
<flux:button wire:click="deleteEmail()" class="cursor-pointer" type="submit" variant="danger">Delete account</flux:button>
|
<flux:button wire:click="deleteEmail()" class="cursor-pointer" type="submit" variant="danger">{{ __('Delete') }}</flux:button>
|
||||||
@elseif($action == "customEmail")
|
@elseif($action == "customEmail")
|
||||||
<div>
|
<div>
|
||||||
<form wire:submit.prevent="create" method="post">
|
<form wire:submit.prevent="create" method="post">
|
||||||
@@ -14,10 +14,10 @@
|
|||||||
<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 mr-1.5">
|
<div class="shrink-0 text-base text-gray-500 select-none sm:text-sm/6 mr-1.5">
|
||||||
<flux:icon.mail variant="mini"/>
|
<flux:icon.mail variant="mini"/>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" name="username" id="username" wire:model.defer="username" class="block min-w-0 grow py-2 pr-3 pl-1 text-base dark:text-white text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6" placeholder="Enter Username">
|
<input type="text" name="username" id="username" autocomplete="false" wire:model.defer="username" class="block min-w-0 grow py-2 pr-3 pl-1 text-base dark:text-white text-gray-900 placeholder:text-gray-400 focus:outline-none sm:text-sm/6" placeholder="{{ __('Enter Username') }}">
|
||||||
<div class="grid shrink-0 grid-cols-1 focus-within:relative">
|
<div class="grid shrink-0 grid-cols-1 focus-within:relative">
|
||||||
<select id="domain" name="domain" aria-label="Domain" wire:model="domain" class="col-start-1 row-start-1 w-full appearance-none rounded-md py-1.5 pr-7 pl-3 text-base text-gray-500 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 dark:focus:outline-white focus:outline-zinc-900 sm:text-sm/6">
|
<select id="domain" name="domain" aria-label="Domain" wire:model="domain" class="col-start-1 row-start-1 w-full appearance-none rounded-md py-1.5 pr-7 pl-3 text-base text-gray-500 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 dark:focus:outline-white focus:outline-zinc-900 sm:text-sm/6">
|
||||||
<option class="dark:bg-zinc-700 dark:text-white bg-zinc-100 accent-gray-700" selected>Choose a domain</option>
|
<option class="dark:bg-zinc-700 dark:text-white bg-zinc-100 accent-gray-700" selected>{{ __('Select Domain') }}</option>
|
||||||
@foreach(array_reverse($domains) as $domain)
|
@foreach(array_reverse($domains) as $domain)
|
||||||
<option x-on:click="$refs.domain.value = '{{ $domain }}'; $wire.setDomain('{{ $domain }}')" class="dark:bg-zinc-700 dark:text-white bg-zinc-100 accent-gray-700">{{ $domain }}</option>
|
<option x-on:click="$refs.domain.value = '{{ $domain }}'; $wire.setDomain('{{ $domain }}')" class="dark:bg-zinc-700 dark:text-white bg-zinc-100 accent-gray-700">{{ $domain }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex mt-6">
|
<div class="flex my-6">
|
||||||
<div class="flex w-full">
|
<div class="flex w-full">
|
||||||
<flux:button x-on:click="$dispatch('closeModal')" class="w-1/2" type="submit" variant="outline">Cancel</flux:button>
|
<flux:button x-on:click="$dispatch('closeModal')" class="w-1/2 cursor-pointer" variant="outline">{{ __('Cancel') }}</flux:button>
|
||||||
<flux:button class="ml-2 w-1/2 btn-success" type="submit" variant="primary">Create Account</flux:button>
|
<flux:button class="ml-2 w-1/2 btn-success cursor-pointer" type="submit" variant="primary">{{ __('Create') }}</flux:button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<div>
|
|
||||||
{{-- Success is as dangerous as failure. --}}
|
|
||||||
</div>
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
<div class="inbox-list cursor-pointer" x-on:click="" data-message-id="{{ $message['id'] }}">
|
|
||||||
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 text-left">
|
|
||||||
<div class="flex items-center px-4 py-4 sm:px-6">
|
|
||||||
<div class="flex flex-1 items-center min-w-0">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<span class="relative inline-block">
|
|
||||||
<img src="{{ asset('images/user.webp') }}" class="size-12" alt="inbox-logo" />
|
|
||||||
<span class="shadow-solid absolute bottom-0 right-0 block w-3 h-3 dark:text-gray-500 text-white bg-amber-300 dark:bg-amber-400 rounded-full"></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 px-4 min-w-0 md:grid md:gap-4 md:grid-cols-2">
|
|
||||||
<div>
|
|
||||||
<div class="dark:text-accent text-accent-content text-sm font-medium leading-5 truncate">
|
|
||||||
{{ $message['sender_name'] }}
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mt-2 dark:text-gray-400 text-gray-500 text-sm leading-5">
|
|
||||||
<svg fill="currentColor" viewBox="0 0 20 20"
|
|
||||||
class="flex-shrink-0 mr-1.5 w-5 h-5 text-gray-400">
|
|
||||||
<path fill-rule="evenodd"
|
|
||||||
d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"
|
|
||||||
clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
<span class="truncate">{{ $message['sender_email'] }}</span></div>
|
|
||||||
</div>
|
|
||||||
<div class="hidden md:block">
|
|
||||||
<div>
|
|
||||||
<div class="dark:text-gray-300 text-gray-900 text-sm leading-5 truncate">
|
|
||||||
{{ $message['subject'] }}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex items-center mt-2 text-gray-400 dark:text-gray-400 text-sm leading-5 truncate">
|
|
||||||
{{ Str::limit($message['contentText'], 100) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg fill="currentColor" viewBox="0 0 20 20" class="w-5 h-5 text-gray-400">
|
|
||||||
<path fill-rule="evenodd"
|
|
||||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
|
||||||
clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<span>
|
<span>
|
||||||
@if($type === "header")<p class="px-2 text-sm cursor-pointer truncate">{{ $email ?? __('...') }}</p>
|
@if($type === "header")
|
||||||
|
<p class="truncate whitespace-nowrap overflow-hidden text-ellipsis px-2 text-sm font-medium cursor-pointer" id="copyEmail" x-on:click="$dispatch('copyEmail')">{{ $email ?? __('...') }}</p>
|
||||||
@else<flux:text class="p-1" variant="subtle">{{ $email ?? __('...') }}</flux:text>
|
@else<flux:text class="p-1" variant="subtle">{{ $email ?? __('...') }}</flux:text>
|
||||||
@if($list)
|
@if($list)
|
||||||
@foreach(array_reverse($emails) as $email_list_item)
|
@foreach(array_reverse($emails) as $email_list_item)
|
||||||
|
|||||||
@@ -1,9 +1,176 @@
|
|||||||
<span>
|
@section('description'){{ config('app.settings.app_description') }}@endsection
|
||||||
|
@section('keywords'){{ config('app.settings.app_keyword') }}@endsection
|
||||||
|
<div x-data="{ show: false, id: 0 }">
|
||||||
@if($messages)
|
@if($messages)
|
||||||
@foreach(array_reverse($messages) as $message)
|
<div class="mailbox">
|
||||||
<livewire:frontend.components.mail :message="$message" />
|
<div x-show="!show" class="list">
|
||||||
@endforeach
|
<flux:heading class="mb-3" size="xl" level="1">Inbox</flux:heading>
|
||||||
@else
|
<div class="mb-3"></div>
|
||||||
<flux:text>{{ $initial ? __('Empty Inbox') : __('Fetching') . '...' }}</flux:text>
|
@foreach(array_reverse($messages) as $i => $message)
|
||||||
|
@if($i % 5 == 0 && json_decode(config('app.settings.ads_settings'))->five)
|
||||||
|
|
||||||
|
@endif
|
||||||
|
<div class="inbox-list cursor-pointer" x-on:click="show = true; id = {{ $message['id'] }};" data-id="{{ $message['id'] }}">
|
||||||
|
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 text-left">
|
||||||
|
<div class="flex items-center px-4 py-4 sm:px-6">
|
||||||
|
<div class="flex flex-1 items-center min-w-0">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<span class="relative inline-block">
|
||||||
|
{{-- <img src="{{ asset('images/user.webp') }}" class="size-12" alt="inbox-logo" />--}}
|
||||||
|
<span class="{{ $message['sender_photo']['dark'] }} {{ $message['sender_photo']['light'] }} inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle size-11 text-[22px] transition">
|
||||||
|
<span id="sender-logo" class="font-medium leading-none text-gray-100 dark:text-gray-300 dark:group-hover:text-gray-200 group-hover:text-gray-700 truncate">{{ strtoupper(substr($message['sender_name'] ?: $message['sender_email'], 0, 1) ) }}</span>
|
||||||
|
</span>
|
||||||
|
@if(!$message['is_seen'])
|
||||||
|
<span class="shadow-solid absolute bottom-0 right-0 block w-3 h-3 dark:text-gray-500 text-white bg-amber-300 dark:bg-amber-400 rounded-full"></span>
|
||||||
@endif
|
@endif
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1 px-4 min-w-0 md:grid md:gap-4 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<div class="dark:text-accent text-accent-content text-sm font-medium leading-5 truncate">
|
||||||
|
{{ $message['sender_name'] }}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-2 dark:text-gray-400 text-gray-500 text-sm leading-5">
|
||||||
|
<svg fill="currentColor" viewBox="0 0 20 20"
|
||||||
|
class="flex-shrink-0 mr-1.5 w-5 h-5 text-gray-400">
|
||||||
|
<path fill-rule="evenodd"
|
||||||
|
d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"
|
||||||
|
clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="truncate">{{ $message['sender_email'] }}</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="hidden md:block">
|
||||||
|
<div>
|
||||||
|
<div class="dark:text-gray-300 text-gray-900 text-sm leading-5 truncate">
|
||||||
|
{{ $message['subject'] }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex items-center mt-2 text-gray-400 dark:text-gray-400 text-sm leading-5 truncate">
|
||||||
|
{{ Str::limit($message['contentText'], 100) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<svg fill="currentColor" viewBox="0 0 20 20" class="w-5 h-5 text-gray-400">
|
||||||
|
<path fill-rule="evenodd"
|
||||||
|
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||||
|
clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
<div x-show="show" class="message">
|
||||||
|
@foreach(array_reverse($messages) as $message)
|
||||||
|
<div x-show="id === {{ $message['id'] }}" id="message-{{ $message['id'] }}">
|
||||||
|
<textarea class="hidden">To: {{ $this->email ?? "" }} From: "{{ $message['sender_name'] }}" <{{ $message['sender_email'] }}> Subject: {{ $message['subject'] }} Date: {{ $message['date'] }} Content-Type: text/html {{ $message['content'] }}</textarea>
|
||||||
|
<span>
|
||||||
|
<div class="-mx-2">
|
||||||
|
<nav class="flex items-center cursor-pointer" x-on:click="show = false">
|
||||||
|
<flux:icon.chevron-left variant="mini"/>
|
||||||
|
<flux:text>{{ __('Get back to MailBox') }}</flux:text>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="mt-2 md:flex md:items-center md:justify-between">
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<h2 class="dark:text-gray-300 text-gray-900 text-2xl font-bold leading-7 sm:truncate">
|
||||||
|
{{ $message['subject'] }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-shrink-0 mt-4 overflow-y-auto md:ml-4 md:mt-0 gap-2">
|
||||||
|
<flux:button iconVariant="mini" iconLeading="download" x-on:click="$dispatch('downloadFile', { download_id: {{ $message['id'] }} })" class="cursor-pointer">Download</flux:button>
|
||||||
|
{{-- <flux:button iconVariant="mini" iconLeading="file">Source</flux:button>--}}
|
||||||
|
<flux:button iconVariant="mini" iconLeading="printer" x-on:click="$dispatch('printFile', { print_id: {{ $message['id'] }} })" class="cursor-pointer">Print</flux:button>
|
||||||
|
<flux:button iconVariant="mini" iconLeading="trash" x-on:click="show = false; id = 0; document.querySelector(`[data-id='{{ $message['id'] }}']`).remove()" wire:click="delete({{ $message['id'] }})" class="cursor-pointer" style="color: #F14743;">{{ __('Delete') }}</flux:button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4 px-4 py-5 bg-white border-b border-gray-200 dark:border-gray-900 shadow overflow-hidden sm:px-6 sm:rounded-md">
|
||||||
|
<div class="flex flex-wrap items-center justify-between -ml-4 -mt-4 sm:flex-nowrap">
|
||||||
|
<div class="ml-4 mt-4">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex-shrink-0">
|
||||||
|
<span class="{{ $message['sender_photo']['dark'] }} {{ $message['sender_photo']['light'] }} inline-flex items-center justify-center shrink-0 select-none overflow-hidden rounded-full align-middle size-11 text-[22px] transition">
|
||||||
|
<span id="sender-logo" class="font-medium leading-none text-gray-100 dark:text-gray-300 dark:group-hover:text-gray-200 group-hover:text-gray-700 truncate">{{ strtoupper(substr($message['sender_name'] ?: $message['sender_email'], 0, 1) ) }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<div class="text-gray-700 text-lg font-medium leading-6">
|
||||||
|
{{ $message['sender_name'] }}
|
||||||
|
<span class="text-gray-700 text-sm font-normal leading-5">{{ $message['sender_email'] }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mt-2 text-gray-500 text-sm leading-5">
|
||||||
|
<svg fill="currentColor" viewBox="0 0 20 20" class="flex-shrink-0 mr-1.5 w-5 h-5 text-gray-400">
|
||||||
|
<path fill-rule="evenodd" d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z" clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="truncate"><a href="mailto:{{ $message['sender_email'] }}"
|
||||||
|
class="ml-1">{{ $email ?? "" }};</a></span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-shrink-0 ml-4 mt-4">
|
||||||
|
<time datetime="2025-04-24T10:11:55+00:00" class="text-gray-500 truncate">
|
||||||
|
{{ $message['datediff'] }}
|
||||||
|
</time>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="magic-box mt-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="px-4 py-5 sm:px-6">
|
||||||
|
<iframe srcdoc="{{ $message['content'] }}" class="w-full iframe-min-height">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
<div class="magic-box mt-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@if (count($message['attachments']) > 0)
|
||||||
|
<div class="grid grid-cols-1 mt-2 text-sm leading-5 text-gray-900 lg:grid-cols-4 md:grid-cols-3 sm:grid-cols-2">
|
||||||
|
@foreach ($message['attachments'] as $attachment)
|
||||||
|
<button class="mb-2 mr-2 border border-gray-200 rounded-md text-sm leading-5 hover:text-gray-500 cursor-pointer" onclick="window.open('{{ $attachment['url'] }}', '_blank')">
|
||||||
|
<div class="py-3 pl-3 pr-4">
|
||||||
|
<div class="flex flex-1 items-center">
|
||||||
|
<svg class="h-5 w-5 flex-shrink-0 text-gray-400" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M8 4a3 3 0 00-3 3v4a5 5 0 0010 0V7a1 1 0 112 0v4a7 7 0 11-14 0V7a5 5 0 0110 0v4a3 3 0 11-6 0V7a1 1 0 012 0v4a1 1 0 102 0V7a3 3 0 00-3-3z" clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="ml-2 flex-1 truncate">{{ $attachment['file'] }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<flux:heading class="mb-3" size="xl" level="1">Inbox</flux:heading>
|
||||||
|
<div class="mb-3"></div>
|
||||||
|
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 items-center">
|
||||||
|
<div class="flex mailbox-min-height w-full items-center justify-center px-4 py-4 sm:px-6">
|
||||||
|
<div class="waitingBox flex flex-col items-center relative -space-y-4">
|
||||||
|
<div class="absolute -mt-4 inset-0 flex justify-center items-center animate-spin duration-2000">
|
||||||
|
<flux:icon.refresh-cw variant="mini" style="color: #ffffdf" />
|
||||||
|
</div>
|
||||||
|
<svg width="120" height="124" viewBox="0 0 92 87" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M26 54.37V38.9C26.003 37.125 26.9469 35.4846 28.48 34.59L43.48 25.84C45.027 24.9468 46.933 24.9468 48.48 25.84L63.48 34.59C65.0285 35.4745 65.9887 37.1167 66 38.9V54.37C66 57.1314 63.7614 59.37 61 59.37H31C28.2386 59.37 26 57.1314 26 54.37Z" fill="#8C92A5"></path>
|
||||||
|
<path d="M46 47.7L26.68 36.39C26.2325 37.1579 25.9978 38.0312 26 38.92V54.37C26 57.1314 28.2386 59.37 31 59.37H61C63.7614 59.37 66 57.1314 66 54.37V38.9C66.0022 38.0112 65.7675 37.1379 65.32 36.37L46 47.7Z" fill="#CDCDD8"></path>
|
||||||
|
<path d="M27.8999 58.27C28.7796 58.9758 29.8721 59.3634 30.9999 59.37H60.9999C63.7613 59.37 65.9999 57.1314 65.9999 54.37V38.9C65.9992 38.0287 65.768 37.1731 65.3299 36.42L27.8999 58.27Z" fill="#E5E5F0"></path>
|
||||||
|
</svg>
|
||||||
|
<flux:text>{{ $initial ? __('Empty Inbox') : __('Fetching') }}</flux:text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="magic-box mt-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,110 @@
|
|||||||
<div>
|
@section('description'){{ config('app.settings.app_description') }}@endsection
|
||||||
<flux:heading class="mb-3" size="xl" level="1">Inbox</flux:heading>
|
@section('keywords'){{ config('app.settings.app_keyword') }}@endsection
|
||||||
<div class="mb-3"></div>
|
<div class="container">
|
||||||
<livewire:frontend.mailbox />
|
<div class="flex justify-center items-center py-3">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-full overflow-hidden rounded-[16px]">
|
||||||
|
<div class="relative rounded-[15px] p-6">
|
||||||
|
<div class="space-y-2 w-full flex flex-col items-center text-center">
|
||||||
|
<div id="hero-section" class="relative self-center" >
|
||||||
|
<svg class="h-56 w-56" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1035 832" >
|
||||||
|
<path opacity=".1" d="M601 95c-66-2-129-20-189-39S291 15 227 4c-42-6-90-7-123 11S61 64 55 93c-4 21-6 44 5 64 8 14 23 26 33 39 34 47 10 105-28 150-17 22-37 42-51 65s-19 49-8 72c12 23 40 40 70 53 61 24 133 31 203 35 156 9 313 5 469 1 57-1 115-2 172-10 32-4 64-10 87-26 29-20 36-54 17-80-33-42-123-52-146-98-13-25 0-52 19-76 39-49 105-93 108-149 2-39-29-78-78-97-51-19-122-17-160 15-39 33-107 46-166 44ZM514.5 831.6c160.604 0 290.8-13.118 290.8-29.3 0-16.182-130.196-29.3-290.8-29.3s-290.8 13.118-290.8 29.3c0 16.182 130.196 29.3 290.8 29.3Z" fill="#F14743" style="transform: translate3d(0px, 11.4579px, 0px);"></path><path d="M249 799s-13-73-61-109c-20-15-35-36-42-60l-5-34" stroke="#535461" stroke-width="2" stroke-miterlimit="10" style="transform: translate3d(0px, 10.8015px, 0px);"></path>
|
||||||
|
<path d="M111 573c4 8 30 24 30 24s4-30 0-37c-4-8-14-12-23-8s-11 14-7 21Zm-3 55c8 5 39 4 39 4s-14-26-22-31-18-2-22 5-3 18 5 22Zm39 74c10 0 37-16 37-16s-27-16-36-16-17 7-17 16 7 16 16 16Zm43 49c9 2 39-9 39-9s-23-20-33-22-17 4-19 13 4 17 13 18Zm-10-132c-3 8-28 27-28 27s-7-29-3-38 12-12 21-9 13 12 10 20Zm49 59c-5 7-35 17-35 17s3-30 9-36c6-7 16-9 23-3 7 4 9 14 4 21l-1 1Zm40 63c-4 7-31 23-31 23s-3-30 2-38 14-11 22-7 12 14 7 22Z" fill="#F14743" style="transform: translate3d(0px, 8.66419px, 0px);"></path><path opacity=".25" d="M111 573c4 8 30 24 30 24s4-30 0-37c-4-8-14-12-23-8s-11 14-7 21Zm-3 55c8 5 39 4 39 4s-14-26-22-31-18-2-22 5-3 18 5 22Zm39 74c10 0 37-16 37-16s-27-16-36-16-17 7-17 16 7 16 16 16Zm43 49c9 2 39-9 39-9s-23-20-33-22-17 4-19 13 4 17 13 18Zm-10-132c-3 8-28 27-28 27s-7-29-3-38 12-12 21-9 13 12 10 20Zm49 59c-5 7-35 17-35 17s3-30 9-36c6-7 16-9 23-3 7 4 9 14 4 21l-1 1Zm40 63c-4 7-31 23-31 23s-3-30 2-38 14-11 22-7 12 14 7 22Z" fill="#000" style="transform: translate3d(0px, 9.40631px, 0px);"></path>
|
||||||
|
<path d="M247 797s20-72-9-123c-11-22-16-46-12-70 2-12 5-23 10-34" stroke="#535461" stroke-width="2" stroke-miterlimit="10" style="transform: translate3d(0px, 10.1179px, 0px);"></path>
|
||||||
|
<path d="M218 538c0 9 18 33 18 33s16-25 15-34-8-16-17-15-16 7-16 16Zm-26 49c5 7 34 19 34 19s-1-30-7-37c-5-7-15-9-23-4a15.005 15.005 0 0 0-6.919 10.106A14.99 14.99 0 0 0 192 587Zm4 83c9 3 40-1 40-1s-17-25-26-28-18 0-22 7 0 18 8 22Zm18 61c8 5 39 7 39 7s-12-28-20-33-18-3-23 4-4 17 3 22h1Zm47-124c-6 6-37 13-37 13s7-29 13-35c7-7 17-7 24-1 6 6 7 15 1 22l-1 1Zm21 72c-9 4-40 2-40 2s15-26 23-30 19-1 23 6c5 8 2 18-6 22Zm9 73c-7 5-39 9-39 9s11-29 18-34 18-4 24 3a15 15 0 0 1-3 22Z" fill="#F14743" style="transform: translate3d(0px, 7.94676px, 0px);"></path><path d="M579 214 317 384l171 308c1 3 4 5 7 6l155 37c5 2 11-1 13-6l77-160 84-112-199-236a35 35 0 0 0-46-7Z" fill="#DCDFED" style="transform: translate3d(0px, 5.38356px, 0px);"></path>
|
||||||
|
<path opacity=".1" d="m827 459-1 1-49 65-1 2-33 44-66 136-2 4-9 19c-2 5-8 8-13 7l-155-38c-3-1-6-3-8-6l-15-27-2-4-107-194-1-2-45-81 5-3 41-27h1l87-56 5-4 122-79c15-10 35-7 46 7l91 107 4 5 67 78v1l33 39 4 5 1 1Z" fill="#000" style="transform: translate3d(0px, 5.97558px, 0px);"></path>
|
||||||
|
<path opacity=".1" d="m786 412-8 56-2 17-2 36v3l-7 188a11.999 11.999 0 0 1-14 11l-78-17h-1l-200-45-4-1-110-24 3-169v-6l1-51v-57l87-56 6-3c80 8 187 24 259 35l4 5 66 78Z" fill="#000" ></path>
|
||||||
|
<path d="m795 346-9 66-9 60-2 17-2 36-7 191a11.999 11.999 0 0 1-14 11l-79-17-200-45-114-25 3-175 1-51 1-60v-62c19-1 50 1 87 5a5591.76 5591.76 0 0 1 344 49Z" fill="#F14743" ></path>
|
||||||
|
<path opacity=".1" d="m820 452-43 20-215 106-199-164-41-33-5 3 45 81-3 175 114 25 15 27c1 3 4 5 7 6l155 37c5 2 11-1 13-6l10-19 78 17c7 2 13-2 15-9v-2l7-191 50-67v-1l-3-5Z" fill="#000" style="transform: translate3d(0px, 6.60105px, 0px);"></path>
|
||||||
|
<path d="m317 384-18 305c0 6 4 11 9 13l474 105a11.994 11.994 0 0 0 9.442-2.391A11.997 11.997 0 0 0 796 796l28-339-262 129-245-202Z" fill="#DCDFED" style="transform: translate3d(0px, 7.25494px, 0px);"></path><path opacity=".1" d="m303 696 246-151c7-5 17-3 23 3l220 257c1 1 1 0 0 0L303 696c-2 1-2 0 0 0Z" fill="#000" style="transform: translate3d(0px, 4.28594px, 0px);"></path>
|
||||||
|
<path d="m304 696 244-147c8-5 18-3 24 4l218 251v3l-2 1-483-107-2-3 1-2Z" fill="#E3E5F1" style="transform: translate3d(0px, 4.81912px, 0px);"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<h1 class="text-2xl leading-9 tracking-tight text-gray-900 sm:text-2xl sm:leading-10 dark:text-gray-300" >Temp Mail</h1>
|
||||||
|
<span class="text-center text-gray-700 lg:max-w-2xl dark:text-gray-400 text-lg">Protect your personal email address from spam, bots, phishing, and other online abuse with our free temporary disposable anonymous email service. No commitments, no risks—just secure, instant access to a temp email address.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center items-center mt-4">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 p-1">
|
||||||
|
<!-- Card 1 -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-96 overflow-hidden rounded-[16px] dark:bg-zinc-800 bg-zinc-200 p-[1px] hover:bg-gradient-to-r hover:from-zinc-600 hover:via-zinc-800 hover:to-zinc-700">
|
||||||
|
<div class="group-hover:animate-spin-slow invisible absolute -top-40 -bottom-40 left-10 right-10 bg-gradient-to-r from-transparent via-gray-600 to-transparent group-hover:visible"></div>
|
||||||
|
<div class="relative rounded-[15px] dark:bg-zinc-900 bg-zinc-100 dark:text-white text-accent-content p-6">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<flux:icon.shield-check/>
|
||||||
|
<p class="text-lg font-semibold dark:text-white text-accent-content">Secure Temporary Email</p>
|
||||||
|
<p class="font-md text-slate-500">
|
||||||
|
Any temp mail that you create on our website is valid for as long we support that domain. Just to ensure that our email inbox is clean we delete emails every 24 hours to ensure reliable usability to every user.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card 2 -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-96 overflow-hidden rounded-[16px] dark:bg-zinc-800 bg-zinc-200 p-[1px] hover:bg-gradient-to-r hover:from-zinc-700 hover:via-zinc-800 hover:to-zinc-700">
|
||||||
|
<div class="group-hover:animate-spin-slow invisible absolute -top-40 -bottom-40 left-10 right-10 bg-gradient-to-r from-transparent via-gray-600 to-transparent group-hover:visible"></div>
|
||||||
|
<div class="relative rounded-[15px] dark:bg-zinc-900 bg-zinc-100 dark:text-white text-accent-content p-6">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<flux:icon.user />
|
||||||
|
<p class="text-lg font-semibold dark:text-white text-accent-content">Instant Disposable Email</p>
|
||||||
|
<p class="font-md text-slate-500">
|
||||||
|
It is also known by names like : tempmail, 10minutemail, throwaway email, fake-mail or trash-mail, gmailnator.com, emailnator.com. Your temp email address is ready for use instantly, putting you in control effortlessly.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card 3 -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-96 overflow-hidden rounded-[16px] dark:bg-zinc-800 bg-zinc-200 p-[1px] hover:bg-gradient-to-r hover:from-zinc-700 hover:via-zinc-800 hover:to-zinc-600">
|
||||||
|
<div class="group-hover:animate-spin-slow invisible absolute -top-40 -bottom-40 left-10 right-10 bg-gradient-to-r from-transparent via-gray-600 to-transparent group-hover:visible"></div>
|
||||||
|
<div class="relative rounded-[15px] dark:bg-zinc-900 bg-zinc-100 dark:text-white text-accent-content p-6">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<flux:icon.clock />
|
||||||
|
<p class="text-lg font-semibold dark:text-white text-accent-content">Fast and Anonymous Email Service</p>
|
||||||
|
<p class="font-md text-slate-500">Experience fast message delivery without delays or restrictions. Zemail.me provides user with disposable gmail emails that can be used to avoid future spam and irrelevant marketing emails.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-10 mb-3 w-full lg:max-w-2xl dark:text-white text-accent-content justify-self-center text-center text-xl" size="xl">
|
||||||
|
<p>----- Popular Articles -----</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3"></div>
|
||||||
|
<div class="flex justify-center items-center py-3">
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 p-1">
|
||||||
|
|
||||||
|
@foreach(config('app.blogs') as $blog)
|
||||||
|
<a href="{{ route('blog', $blog->slug) }}">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-96 overflow-hidden rounded-[16px] dark:bg-zinc-800 bg-zinc-200 p-[1px] ease-in-out hover:bg-gradient-to-r hover:from-zinc-600 hover:via-zinc-800 hover:to-zinc-700">
|
||||||
|
<div class="group-hover:animate-spin-slow invisible absolute -top-40 -bottom-40 left-10 right-10 bg-gradient-to-r from-transparent via-gray-600 to-transparent group-hover:visible"></div>
|
||||||
|
<div class="relative rounded-[15px] dark:bg-zinc-900 bg-zinc-100 dark:text-white text-accent-content p-6">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<p class="font-md text-slate-500">
|
||||||
|
<img src="{{ asset('storage/'.$blog->post_image) }}" class="card-img-top" alt="{{ $blog->slug }}">
|
||||||
|
</p>
|
||||||
|
<p class="text-lg font-semibold dark:text-white text-accent-content truncate">{{ $blog->post }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
<div class="inbox-list cursor-pointer" x-on:click="">
|
|
||||||
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 text-left">
|
|
||||||
<div class="flex items-center px-4 py-4 sm:px-6">
|
|
||||||
<div class="flex flex-1 items-center min-w-0">
|
|
||||||
<div class="flex-shrink-0">
|
|
||||||
<span class="relative inline-block">
|
|
||||||
<img src="{{ asset('images/user.webp') }}" class="size-12" alt="inbox-logo" />
|
|
||||||
<span class="shadow-solid absolute bottom-0 right-0 block w-3 h-3 dark:text-gray-500 text-white bg-amber-300 dark:bg-amber-400 rounded-full"></span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex-1 px-4 min-w-0 md:grid md:gap-4 md:grid-cols-2">
|
|
||||||
<div>
|
|
||||||
<div class="dark:text-accent text-accent-content text-sm font-medium leading-5 truncate">
|
|
||||||
Fake-IT
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mt-2 dark:text-gray-400 text-gray-500 text-sm leading-5">
|
|
||||||
<svg fill="currentColor" viewBox="0 0 20 20"
|
|
||||||
class="flex-shrink-0 mr-1.5 w-5 h-5 text-gray-400">
|
|
||||||
<path fill-rule="evenodd"
|
|
||||||
d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884zM18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"
|
|
||||||
clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
<span class="truncate">register@receivefreesms.co.uk</span></div>
|
|
||||||
</div>
|
|
||||||
<div class="hidden md:block">
|
|
||||||
<div>
|
|
||||||
<div class="dark:text-gray-300 text-gray-900 text-sm leading-5 truncate">
|
|
||||||
Resend Verification Email
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="flex items-center mt-2 text-gray-400 dark:text-gray-400 text-sm leading-5 truncate">
|
|
||||||
Hi czxcc, Welcome on board, to complete your registration process. Please verify
|
|
||||||
your email by visting following link in your…
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<svg fill="currentColor" viewBox="0 0 20 20" class="w-5 h-5 text-gray-400">
|
|
||||||
<path fill-rule="evenodd"
|
|
||||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
|
||||||
clip-rule="evenodd"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
29
resources/views/livewire/list-blog.blade.php
Normal file
29
resources/views/livewire/list-blog.blade.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
@section('title'){{ config('app.settings.app_name') }} Blog - Your Guide to the Latest Trends @endsection
|
||||||
|
<main>
|
||||||
|
<flux:heading class="mb-3 truncate" size="xl" level="1">Latest Articles</flux:heading>
|
||||||
|
<div class="mb-3"></div>
|
||||||
|
<div class="flex justify-center items-center py-3">
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 p-1">
|
||||||
|
|
||||||
|
@foreach(config('app.blogs') as $i => $blog)
|
||||||
|
<a href="{{ route('blog', $blog->slug) }}">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="group relative mx-auto w-96 overflow-hidden rounded-[16px] dark:bg-zinc-800 bg-zinc-200 p-[1px] ease-in-out hover:bg-gradient-to-r hover:from-zinc-600 hover:via-zinc-800 hover:to-zinc-700">
|
||||||
|
<div class="group-hover:animate-spin-slow invisible absolute -top-40 -bottom-40 left-10 right-10 bg-gradient-to-r from-transparent via-gray-600 to-transparent group-hover:visible"></div>
|
||||||
|
<div class="relative rounded-[15px] dark:bg-zinc-900 bg-zinc-100 dark:text-white text-accent-content p-6">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<p class="font-md text-slate-500">
|
||||||
|
<img src="{{ asset('storage/'.$blog->post_image) }}" class="card-img-top" alt="{{ $blog->slug }}">
|
||||||
|
</p>
|
||||||
|
<p class="text-lg font-semibold dark:text-white text-accent-content truncate">{{ $blog->post }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
34
resources/views/livewire/page.blade.php
Normal file
34
resources/views/livewire/page.blade.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
@section('title'){{ $page->title }} | {{ config('app.settings.app_name') }}@endsection
|
||||||
|
|
||||||
|
@section('metas')
|
||||||
|
@forelse ($page->meta as $key => $value)
|
||||||
|
@if ($value)
|
||||||
|
|
||||||
|
@if ($key == "description")
|
||||||
|
@section('description'){{ $value }}@endsection
|
||||||
|
@elseif($key == "keywords")
|
||||||
|
@section('keywords'){{ $value }}@endsection
|
||||||
|
@else
|
||||||
|
<meta name="{{ $key }}" content="{{ $value }}">
|
||||||
|
@endif
|
||||||
|
@endif
|
||||||
|
@empty
|
||||||
|
@endforelse
|
||||||
|
@endsection
|
||||||
|
@section('custom_header')
|
||||||
|
@if(!empty($page->custom_header))
|
||||||
|
{!! $page->custom_header !!}
|
||||||
|
@endif
|
||||||
|
@endsection
|
||||||
|
<div>
|
||||||
|
<flux:heading class="mb-3 truncate" size="xl" level="1">{{ $page->title }}</flux:heading>
|
||||||
|
<div class="mb-3"></div>
|
||||||
|
<div class="block rounded-lg bg-white shadow-md dark:bg-zinc-700 items-center p-1">
|
||||||
|
<div class="flex w-full items-center justify-center px-4 py-4 sm:px-6">
|
||||||
|
<flux:text>{!! $page->content !!}</flux:text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="magic-box mt-3">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,8 +1,33 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Email;
|
||||||
use Illuminate\Foundation\Inspiring;
|
use Illuminate\Foundation\Inspiring;
|
||||||
use Illuminate\Support\Facades\Artisan;
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
|
||||||
Artisan::command('inspire', function () {
|
Artisan::command('inspire', function () {
|
||||||
$this->comment(Inspiring::quote());
|
$this->comment(Inspiring::quote());
|
||||||
})->purpose('Display an inspiring quote');
|
})->purpose('Display an inspiring quote');
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
Email::fetchProcessStoreEmail();
|
||||||
|
})->everyMinute();
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
Email::deleteBulkAttachments();
|
||||||
|
})->daily();
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
Email::deleteBulkMailboxes();
|
||||||
|
})->everyMinute();
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
Email::deleteMessagesFromDB();
|
||||||
|
})->everyTwoHours();
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
\App\Models\Log::deleteLogsFromDB();
|
||||||
|
})->everyThreeHours();
|
||||||
|
|
||||||
|
Schedule::call(function () {
|
||||||
|
Email::cleanMailbox();
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,21 +1,38 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\AppController;
|
use App\Http\Controllers\AppController;
|
||||||
use App\Livewire\Email;
|
use App\Http\Middleware\CheckPageSlug;
|
||||||
use App\Livewire\EmailInbox;
|
use App\Livewire\Blog;
|
||||||
|
use App\Livewire\Frontend\Mailbox;
|
||||||
use App\Livewire\Home;
|
use App\Livewire\Home;
|
||||||
use App\Models\ZEmail;
|
use App\Livewire\ListBlog;
|
||||||
|
use App\Livewire\Page;
|
||||||
|
|
||||||
|
use App\Models\Email;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', Home::class)->name('home');
|
Route::get('/', Home::class)->name('home');
|
||||||
Route::get('/mailbox', Email::class)->name('mailbox');
|
Route::get('/mailbox', Mailbox::class)->name('mailbox');
|
||||||
|
Route::get('/mailbox/{email?}', [AppController::class, 'mailbox'])->name('mailboxFromURL');
|
||||||
|
|
||||||
Route::get('/msg/{email?}/', function ($email) {
|
Route::get('/switch/{email}', [AppController::class, 'switch'])->name('switch');
|
||||||
$responses = [
|
Route::get('/delete/{email?}', [AppController::class, 'delete'])->name('delete');
|
||||||
'to' => ZEmail::getMessages($email, 'to', []),
|
|
||||||
'cc' => ZEmail::getMessages($email, 'cc', [])
|
Route::get('locale/{locale}', [AppController::class, 'locale'])->name('locale');
|
||||||
];
|
Route::get('/blog', ListBlog::class)->name('list-blog');
|
||||||
$messages = array_merge($responses['to']['data'], $responses['cc']['data']);
|
Route::get('/blog/{slug}', Blog::class)->name('blog');
|
||||||
$notifications = array_merge($responses['to']['notifications'], $responses['cc']['notifications']);
|
|
||||||
return $messages;
|
Route::post('/sync', function (Request $request) {
|
||||||
})->name('test');
|
try {
|
||||||
|
|
||||||
|
if (config('app.auto_fetch_mail')) {
|
||||||
|
Email::fetchProcessStoreEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
\Log::error($e->getMessage());
|
||||||
|
}
|
||||||
|
return response()->noContent();
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::get('{slug}', Page::class)->where('slug', '.*')->name('page')->middleware(CheckPageSlug::class);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import tailwindcss from '@tailwindcss/vite';
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
laravel({
|
laravel({
|
||||||
input: ['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/css/boil.js'],
|
input: ['resources/css/app.css', 'resources/css/boil.css', 'resources/js/app.js', 'resources/js/boil.js'],
|
||||||
refresh: true,
|
refresh: true,
|
||||||
}),
|
}),
|
||||||
tailwindcss(),
|
tailwindcss(),
|
||||||
|
|||||||
988
zsql/zemailnator.sql
Normal file
988
zsql/zemailnator.sql
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user