99 Commits

Author SHA1 Message Date
Frank John Begornia
d4a6028599 chore: remove SSH Keys Setup guide to enhance security practices 2026-04-16 23:21:45 +08:00
Frank John Begornia
4888f93eac feat(teamstore): add league/conference sub-sub-category pill filter (hi-five-franchise-store only) 2026-04-16 23:19:19 +08:00
Frank John Begornia
49921a26a9 Add centering guidelines script and update script references in designer view
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 3m7s
2026-04-02 03:33:19 +08:00
Frank John Begornia
3b6e0ec447 Refactor image handling in PrintPatternController and TemplatesController to use MinIO for improved storage management 2026-04-02 03:31:08 +08:00
Frank John Begornia
c16203110b Refactor image URLs to use MinIO storage for improved asset management
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m39s
2026-04-02 03:04:49 +08:00
Frank John Begornia
60fcf08cbc Enhance TestEmailController and view to include CSRF token and improve form security
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 1m51s
2026-02-26 23:12:00 +08:00
Frank John Begornia
701a433174 Update exception handling in Handler and TestEmailController for improved error reporting
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 1m51s
2026-02-26 22:58:28 +08:00
Frank John Begornia
47b354d8b7 Add TestEmailController and views for sending test emails
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m51s
2026-02-26 22:46:14 +08:00
Frank John Begornia
dfdb48920d Add SSH keys setup guide and update configurations for secure key management
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 4m31s
2026-02-23 02:01:12 +08:00
Frank John Begornia
3dac8ee685 Fix image path for PayPal button in cart view
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m1s
2026-01-07 01:42:43 +08:00
Frank John Begornia
09974721f3 Update DesignerController and site_config for MinIO integration and URL adjustments
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m23s
2026-01-07 01:28:47 +08:00
Frank John Begornia
8215ad8337 Refactor image URLs to use MinIO storage across various views and controllers
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m16s
2026-01-07 01:10:15 +08:00
Frank John Begornia
368ac50729 Add MinIO configuration and update image URLs in MainController
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 1m57s
2026-01-06 15:34:02 +08:00
Frank John Begornia
8f094ee89c Use MinIO for sports category images
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 1m56s
2026-01-06 15:27:17 +08:00
Frank John Begornia
0551cb078f Add MinIO S3 storage integration
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m9s
- Add minio disk configuration in filesystems.php
- Create helper functions for MinIO URLs (minio_url, minio_image_url)
- Update composer.json with AWS SDK (for future S3 support)
- Add MinIO env vars to docker-compose.local.yml
- Add .env examples for MinIO configuration
2026-01-06 15:20:15 +08:00
Frank John Begornia
26620fc043 Update README.md to reflect project details and installation instructions
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m1s
2026-01-05 23:15:14 +08:00
Frank John Begornia
f10d6daa6f Update APP_URL and Traefik rules for production environment 2026-01-05 23:13:37 +08:00
Frank John Begornia
ab0d370225 Remove commented-out sales chart section from user dashboard
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m0s
2025-12-31 02:20:31 +08:00
Frank John Begornia
ee7b52feb2 Update AppServiceProvider to force HTTPS and configure APP_URL in app.php
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m1s
2025-12-31 02:10:31 +08:00
Frank John Begornia
4cb77e9312 Remove '/public' prefix from asset paths for consistency across views
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m4s
2025-12-31 02:04:33 +08:00
Frank John Begornia
43e66c7ac4 Refactor asset paths to remove '/public' prefix for consistency across views
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 1m57s
2025-12-31 01:53:42 +08:00
Frank John Begornia
685a49cf57 Remove unnecessary environment setup and optimization steps from Dockerfile
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m13s
2025-12-31 01:24:12 +08:00
Frank John Begornia
f6617f6d70 Fix Traefik certresolver value in production Docker Compose configuration
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m5s
2025-12-31 01:10:07 +08:00
Frank John Begornia
7c6108e0a7 Update production environment URLs and Traefik rules for dev-crew.crewsportswear.app
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m9s
2025-12-31 00:56:31 +08:00
Frank John Begornia
b8aa48a0bb Update deployment directory path in workflow configuration
All checks were successful
Deploy Production (crewsportswear.com) / deploy (push) Successful in 2m14s
2025-12-31 00:33:22 +08:00
Frank John Begornia
8fc0b1076a Add Docker and deployment configurations for development and production environments
Some checks failed
Deploy Production (crewsportswear.com) / deploy (push) Failing after 5m18s
2025-12-31 00:23:44 +08:00
franknstayn
71e1fca6fe updated 2023-08-24 21:55:06 +08:00
franknstayn
8dc23e4e67 exempt sf spartans tax 2021-12-23 18:08:57 +08:00
franknstayn
729d0e72e6 added voucher validation 2021-12-03 18:00:27 +08:00
franknstayn
0b8856d3a0 update store item view 2021-11-26 19:31:40 +08:00
franknstayn
6aa0587a69 update store item view 2021-11-26 19:29:59 +08:00
franknstayn
08c274f5bd updated checkout flow 2021-11-03 21:30:42 +08:00
franknstayn
148df27117 update navbar 2021-09-25 18:32:49 +08:00
franknstayn
e552037e2c update navbar 2021-09-25 18:30:03 +08:00
franknstayn
7011b28542 update navbar 2021-09-25 18:28:40 +08:00
franknstayn
2ac9cb6420 update navbar 2021-09-25 18:20:22 +08:00
franknstayn
9c403b7207 update creds 2021-09-15 20:48:31 +08:00
franknstayn
11960d6bad update email creds 2021-09-15 20:41:07 +08:00
franknstayn
25f80cb16f update email creds 2021-09-15 20:20:31 +08:00
franknstayn
72773a517a update email 2021-09-15 20:02:51 +08:00
franknstayn
d1f5d38480 update description label 2021-09-07 19:41:04 +08:00
franknstayn
f5f1693f55 update store please read text 2021-09-03 21:35:45 +08:00
franknstayn
39165cc7f9 update store please read text 2021-09-03 21:35:24 +08:00
franknstayn
20b4e06ee7 updated delete function for delete item 2021-07-17 15:32:49 +08:00
Frank John Begornia
18e11ac3d0 added shipping fee for dgs 2021-03-20 14:36:46 +08:00
Frank John Begornia
0013b2a025 fixed reports date range 2021-02-08 04:07:29 +08:00
Frank John Begornia
acf9c2e931 updated apis 2021-02-04 19:45:27 +08:00
Frank John Begornia
c144810352 update reports display 2021-01-23 19:52:17 +08:00
Frank John Begornia
b1ed52f7a6 update report 2021-01-23 19:49:15 +08:00
Frank John Begornia
70b250a64e fixed order report 2020-12-19 19:49:03 +08:00
Frank John Begornia
1eb7e6632f fixed order report 2020-12-19 19:46:36 +08:00
Frank John Begornia
98e7652e6b added status 2020-12-12 19:53:30 +08:00
Frank John Begornia
852593ecfb added new api 2020-12-11 21:47:36 +08:00
Frank John Begornia
43de35a66c added order status 2020-11-28 18:13:43 +08:00
Frank John Begornia
ad57e218af change image url 2020-11-27 16:24:57 +08:00
Frank John Begornia
d2a20c4831 added api for tracking 2020-11-27 02:43:26 +08:00
franknstayn
36ad67a37a added bucket hat sizes 2020-11-26 12:32:29 -06:00
franknstayn
6c55194c9a edit please read on lasc store 2020-11-17 18:50:50 +08:00
franknstayn
77ee1b9ccc update crewsportswear 2020-10-24 21:27:04 +08:00
franknstayn
6cc68cd56b added announcement 2020-10-17 23:16:25 +08:00
franknstayn
3e328b83a4 added 0 2020-10-17 23:14:52 +08:00
franknstayn
d82832043c added announcement 2020-10-17 22:17:25 +08:00
franknstayn
da89856e95 added stat 2020-09-29 19:40:42 +08:00
franknstayn
bf88584dcd update 2020-09-29 01:05:01 -05:00
franknstayn
3eb4078d19 update payment details record 2020-08-10 23:20:55 +08:00
franknstayn
5918eded8c add shipping cost 2020-08-10 22:41:40 +08:00
franknstayn
02361ca64e updates 2020-08-09 13:21:41 -05:00
franknstayn
1ca40ce1d7 updates 2020-08-01 03:06:48 -05:00
franknstayn
59e52125f7 fix teamstore password 2020-07-11 19:31:35 +08:00
franknstayn
bb139cb0df updated 2020-07-11 02:57:12 -05:00
franknstayn
bca94e54cc added new form for store item 2020-03-19 22:37:08 +08:00
franknstayn
e57209bc64 update 3_14_2020 2020-03-14 01:17:24 -05:00
franknstayn
5eeefa5587 fix tax exemption 2020-02-28 21:07:05 +08:00
franknstayn
80094cfdf0 Merge branch 'master' of github.com:franknstayn/crewsportswear
Conflicts:
	app/Http/Controllers/paypal/PaypalController.php
2020-02-28 07:02:30 -06:00
franknstayn
587819be9a exempt jjed phl intax 2020-02-28 06:58:41 -06:00
franknstayn
67b52fcc1a Merge branch 'master' of https://github.com/franknstayn/crewsportswear 2020-02-28 20:54:33 +08:00
franknstayn
f7b402fe7a exempt nlp in tax 2020-02-28 20:53:29 +08:00
franknstayn
8408695473 uncomment RewriteRule 2020-02-25 12:29:23 +08:00
franknstayn
99f89a968b removed JAC 2020-02-25 12:21:10 +08:00
franknstayn
3f96f82090 add jac 2020-02-25 12:06:28 +08:00
franknstayn
942af1f0a8 added contact us page 2020-02-25 11:53:26 +08:00
franknstayn
4610fb526b changed sizes display 2020-02-08 20:37:02 +08:00
franknstayn
c29936f6b9 Merge pull request #9 from franknstayn/additional_form
Additional form
2020-02-08 16:40:18 +08:00
franknstayn
7c12b0e2bf add form in user page 2020-02-07 01:14:27 +08:00
franknstayn
a5dab36a14 additional forms 2020-02-07 01:10:31 +08:00
franknstayn
55f135f66c Merge pull request #8 from franknstayn/local_dev
added delete function on store item
2020-01-25 20:12:43 +08:00
franknstayn
6631690f93 Merge branch 'master' of github.com:franknstayn/crewsportswear 2020-01-25 04:47:06 -06:00
franknstayn
dd26b1dd4b added user for tax exemption 2020-01-25 04:45:58 -06:00
franknstayn
155bc2ce53 Merge pull request #7 from franknstayn/local_dev
Local dev
2020-01-25 18:43:25 +08:00
franknstayn
ef81f0bf25 Merge branch 'local_dev' of github.com:franknstayn/crewsportswear 2020-01-10 07:32:59 -06:00
franknstayn
bf078c82bf Merge pull request #6 from franknstayn/local_dev
rename number to name
2019-12-04 18:49:08 +08:00
franknstayn
2e29677b90 Merge pull request #5 from franknstayn/local_dev
Local dev
2019-12-04 18:44:41 +08:00
franknstayn
03ea4e84a2 Merge pull request #4 from franknstayn/local_dev
added "size" column on download report in csv and excel
2019-11-15 21:05:31 +08:00
franknstayn
3f8c116293 Merge pull request #3 from franknstayn/local_dev
Local dev
2019-11-14 19:45:29 +08:00
franknstayn
9bf1a888a6 Merge branch 'master' of github.com:franknstayn/crewsportswear 2019-11-11 04:44:45 -06:00
franknstayn
542f2c64e0 update from live 11_11_2019 2019-11-11 04:44:08 -06:00
franknstayn
1d4c9a5445 Merge pull request #2 from franknstayn/local_dev
added column in store order reports in store owner
2019-11-11 18:42:11 +08:00
franknstayn
3698312664 fixed broken link on cart page. 2019-11-06 07:26:02 -06:00
franknstayn
a9145ea484 Merge pull request #1 from franknstayn/local_dev
Local dev by frank
2019-11-06 20:29:09 +08:00
34 changed files with 814 additions and 273 deletions

26
.env.local Normal file
View File

@@ -0,0 +1,26 @@
# Local Development Configuration
# Copy to .env.local and fill in your values.
# ── MinIO credentials ─────────────────────────────────────────────────────────
MINIO_KEY=your_minio_root_user
MINIO_SECRET=your_minio_root_password
# ── SSH tunnel (remote DB) ────────────────────────────────────────────────────
# Only needed when starting with --profile ssh-db.
# NOTE: no inline comments allowed after values — Docker reads them literally.
SSH_HOST=136.114.183.15
SSH_PORT=22
SSH_USER=webmaster
# Must be an absolute path — Docker Compose does NOT expand ~
SSH_KEY_PATH=/Users/webmaster/.ssh/id_ed25519_crew_webmaster
SSH_DB_REMOTE_HOST=127.0.0.1
SSH_DB_REMOTE_PORT=3306
# Tell the app to route DB traffic through the tunnel container:
DB_HOST=db-tunnel
DB_PORT=3306
DB_DATABASE=custom_designs
DB_USERNAME=root
DB_PASSWORD=VeryStrongRootPass2025!

View File

@@ -1,6 +1,26 @@
# Local Development MinIO Configuration
# Copy to .env.local and update with your MinIO credentials
# Local Development Configuration
# Copy to .env.local and fill in your values.
# MinIO credentials (get from your production server)
# ── MinIO credentials ─────────────────────────────────────────────────────────
MINIO_KEY=your_minio_root_user
MINIO_SECRET=your_minio_root_password
# ── SSH tunnel (remote DB) ────────────────────────────────────────────────────
# Only needed when starting with --profile ssh-db.
# IMPORTANT: no inline comments after values — Docker Compose reads them literally.
# IMPORTANT: SSH_KEY_PATH must be an absolute path — ~ is NOT expanded by Docker Compose.
#
SSH_HOST=your.server.ip.or.hostname
SSH_PORT=22
SSH_USER=root
SSH_KEY_PATH=/absolute/path/to/your/private/key
#
SSH_DB_REMOTE_HOST=127.0.0.1 # DB host as seen from the SSH server
SSH_DB_REMOTE_PORT=3306 # DB port as seen from the SSH server
#
# Tell the app to route DB traffic through the tunnel container:
DB_HOST=db-tunnel
DB_PORT=3306
DB_DATABASE=your_remote_db_name
DB_USERNAME=your_remote_db_user
DB_PASSWORD=your_remote_db_password

11
.gitignore vendored
View File

@@ -1,3 +1,14 @@
/vendor
/node_modules
.env
# SSH Keys - Never commit private keys
*.ppk
*.pem
*.key
id_rsa
id_dsa
id_ecdsa
id_ed25519
_key/
.ssh/

17
Makefile Normal file
View File

@@ -0,0 +1,17 @@
COMPOSE_LOCAL = docker compose -f docker-compose.local.yml
# ── Local stack (local MariaDB) ───────────────────────────────────────────────
up:
$(COMPOSE_LOCAL) up --build
down:
$(COMPOSE_LOCAL) down
# ── Local stack with SSH tunnel to remote DB ──────────────────────────────────
up-ssh:
$(COMPOSE_LOCAL) --env-file .env.local --profile ssh-db up --build
down-ssh:
$(COMPOSE_LOCAL) --env-file .env.local --profile ssh-db down
.PHONY: up down up-ssh down-ssh

View File

@@ -1,126 +0,0 @@
# Laravel 5.0 → 11 Upgrade Progress
## Current State (Baseline)
- **Laravel Version**: 5.0.*
- **PHP Version**: 5.6.40 (container), 7.0 (production Dockerfile)
- **Database**: MySQL via PDO
- **Branch**: feature/laravel-upgrade
## Dependencies Audit
### Core Dependencies
-`laravel/framework`: 5.0.* → Need to upgrade incrementally
-`webpatser/laravel-uuid`: ^2.0 → Compatible through Laravel 8
- ⚠️ `netshell/paypal`: dev-master → May need replacement (outdated)
- ⚠️ `guzzlehttp/guzzle`: ~5.0 → Need to upgrade to ^7.0
-`google/recaptcha`: ~1.1 → Still maintained
- ⚠️ `spatie/laravel-analytics`: ^1.4 → Need to upgrade to ^5.0
-`league/flysystem-sftp`: ^1.0 → Upgrade to ^3.0 for Laravel 9+
-`aws/aws-sdk-php`: ~3.0 → Compatible
### Custom Middleware Found
- `CheckTeamStorePassword` - Custom team store authentication
- `IsAdmin` - Admin role check
- `IsUser` - Normal user role check
- `isAuthorized` - Custom authorization
- `Cors` - CORS handling
### Custom Code Patterns Detected
-`app/helpers.php` - Auto-loaded helper functions (minio_url, minio_image_url)
- ✅ Routes in `app/Http/routes.php` (Laravel 5.0 pattern)
- ⚠️ Controllers echoing HTML directly (needs refactoring)
- ⚠️ Boolean stored as strings ("TRUE"/"FALSE" in database)
## Upgrade Path
### Phase 1: Laravel 5.0 → 5.1 (Week 1)
- [ ] Update composer.json
- [ ] Test route compatibility
- [ ] Verify middleware still works
- [ ] Test authentication flow
### Phase 2: Laravel 5.1 → 5.5 LTS (Week 2)
- [ ] Move routes to `routes/web.php`
- [ ] Update exception handler
- [ ] Test all database queries
- [ ] Update validation rules
### Phase 3: PHP 7.0 → 7.4 & Laravel 5.5 → 6.x (Week 3)
- [ ] Update Dockerfile to PHP 7.4
- [ ] Remove mcrypt dependencies (if any encrypted data)
- [ ] Add string/array helpers package
- [ ] Test file uploads
### Phase 4: Laravel 6.x → 8.x (Week 4)
- [ ] Update factory syntax
- [ ] Test rate limiting
- [ ] Verify queue jobs
### Phase 5: PHP 8.0 & Laravel 8.x → 9.x (Week 5)
- [ ] Update Dockerfile to PHP 8.0
- [ ] Update Flysystem to v3 (affects MinIO config)
- [ ] Test query builder changes
### Phase 6: Laravel 9.x → 10.x (Week 6)
- [ ] Update to PHP 8.1
- [ ] Add type declarations where needed
- [ ] Test invokable validation rules
### Phase 7: Laravel 10.x → 11.x (Week 7)
- [ ] Update to PHP 8.2
- [ ] Test new application skeleton
- [ ] Verify all functionality
## Breaking Changes to Watch
### Database
- Boolean fields stored as strings ("TRUE"/"FALSE") - Need migration
- Direct DB facade usage throughout codebase
### Routes
- Controller array syntax in routes will be removed
- Need to update to standard controller@method or invokable
### Middleware
- Middleware signature changes in later versions
- CSRF token handling updates
### Views
- Blade syntax mostly compatible
- PHP in controllers (<?php echo) needs refactoring
### External Services
- PayPal integration (netshell/paypal) may need complete rewrite
- Google Analytics package needs major upgrade
- Screenshot Node.js service should remain compatible
## Rollback Plan
- Keep master branch untouched
- Tag current state: `git tag v5.0-baseline`
- Can revert entire branch if needed
- Parallel testing environment on port 8090
## Testing Checklist (After Each Upgrade)
- [ ] Homepage loads
- [ ] User registration/login works
- [ ] Sports category pages render
- [ ] Designer tool loads
- [ ] Pattern/clipart selection works
- [ ] Cart functionality
- [ ] Team store pages
- [ ] PayPal checkout flow
- [ ] Admin panel access
- [ ] Image serving from MinIO
- [ ] Screenshot generation service
- [ ] File uploads work
## Notes
- Current Composer version 1.x - may need to use `composer self-update --1` during transition
- AWS SDK already at 3.0, compatible with all Laravel versions
- Helper functions (minio_url) should remain compatible
- Fabric.js designer tool is front-end only, won't be affected
## Completed Steps
1. ✅ Created feature branch
2. ✅ Documented current state
3. ⏳ Ready to start first upgrade

View File

@@ -22,8 +22,11 @@ class Handler extends ExceptionHandler {
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
public function report($e)
{
if (!$e instanceof Exception) {
$e = new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
}
return parent::report($e);
}
@@ -31,11 +34,14 @@ class Handler extends ExceptionHandler {
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @param mixed $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
public function render($request, $e)
{
if (!$e instanceof Exception) {
$e = new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
}
return parent::render($request, $e);
}

View File

@@ -5,6 +5,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Request1;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Models\PrintPatternModel;
use App\Models\SizesModel;
@@ -46,7 +47,7 @@ class PrintPatternController extends Controller {
$NewImageName = $templateSize.'.'.$imageExt;
$thumbnail = "uniform-templates/".$templatecode."/".$templateType."/SIZES/" . $NewImageName;
$thumbnail = "uploads/images/uniform-templates/".$templatecode."/".$templateType."/SIZES/" . $NewImageName;
$data = array(
'TemplateCode' => $templatecode,
@@ -58,9 +59,7 @@ class PrintPatternController extends Controller {
$i = $m->insertPrintPattern($data);
//var_dump($data);
if($i){
$r = $request->file('preview_print_template')->move(
base_path() . "/public/images/uniform-templates/".$templatecode."/".$templateType."/SIZES/", $NewImageName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templatecode.'/'.$templateType.'/SIZES/'.$NewImageName, file_get_contents($request->file('preview_print_template')->getRealPath()));
echo '<div class="alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-check"></i> Success!</h4>

View File

@@ -4,6 +4,7 @@ use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use App\Models\TemplatesModel;
use App\Models\SportsModel;
use App\Models\PrintPatternModel;
@@ -48,7 +49,7 @@ class TemplatesController extends Controller {
<h3><?php echo $row->TemplateName ?></h3>
</div>
<div class="sports-border">
<a href=""><img src="<?php echo url('public') . "/" . $row->Thumbnail ?>" alt="Sports" height="400px;" class="img img-responsive product-center" /></a>
<a href=""><img src="<?php echo minio_url($row->Thumbnail) ?>" alt="Sports" height="400px;" class="img img-responsive product-center" /></a>
<div class="sport-edit-btn">
<a href="<?php echo url('admin/templates') . "/edit/" . $row->TemplateCode . "/" ?>" class="btn btn-primary btn-block"><i class="fa fa-edit"></i> Edit</a>
</div>
@@ -129,15 +130,13 @@ class TemplatesController extends Controller {
if($i){
$request->file('tempateImage')->move(
base_path() . '/public/images/templates/thumbnail', $NewImageName
);
Storage::disk('minio')->put('images/templates/thumbnail/' . $NewImageName, file_get_contents($request->file('tempateImage')->getRealPath()));
//for front jersey
if(!empty($request->file('svgJerseyFront')->getClientOriginalName())){
$svgName = $request->file('svgJerseyFront')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
//var_dump($svgThumbnail);
$Templatedata = array(
'TemplateCode' => $templateCode,
@@ -149,16 +148,14 @@ class TemplatesController extends Controller {
$i = $m->insertTempaltePaths($Templatedata);
if($i){
$request->file('svgJerseyFront')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgJerseyFront')->getRealPath()));
}
}
if(!empty($request->file('svgJerseyBack')->getClientOriginalName())){
$svgName = $request->file('svgJerseyBack')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'TemplateCode' => $templateCode,
@@ -170,16 +167,14 @@ class TemplatesController extends Controller {
$i = $m->insertTempaltePaths($Templatedata);
if($i){
$request->file('svgJerseyBack')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgJerseyBack')->getRealPath()));
}
}
if(!empty($request->file('svgShortRight')->getClientOriginalName())){
$svgName = $request->file('svgShortRight')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'TemplateCode' => $templateCode,
@@ -191,16 +186,14 @@ class TemplatesController extends Controller {
$i = $m->insertTempaltePaths($Templatedata);
if($i){
$request->file('svgShortRight')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgShortRight')->getRealPath()));
}
}
if(!empty($request->file('svgShortLeft')->getClientOriginalName())){
$svgName = $request->file('svgShortLeft')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'TemplateCode' => $templateCode,
@@ -212,9 +205,7 @@ class TemplatesController extends Controller {
$i = $m->insertTempaltePaths($Templatedata);
if($i){
$request->file('svgShortLeft')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgShortLeft')->getRealPath()));
}
}
@@ -270,9 +261,7 @@ class TemplatesController extends Controller {
'PatternId' => $getSkins
);
$request->file('tempateImage')->move(
base_path() . '/public/images/templates/thumbnail', $NewImageName
);
Storage::disk('minio')->put('images/templates/thumbnail/' . $NewImageName, file_get_contents($request->file('tempateImage')->getRealPath()));
}else{
@@ -298,7 +287,7 @@ class TemplatesController extends Controller {
//echo 'meron jerset front';
$svgName = $request->file('svgJerseyFront')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'Type' => 'Jersey',
@@ -308,9 +297,7 @@ class TemplatesController extends Controller {
$i = $m->updateTemplatePaths($Templatedata, $post['id_svgJerseyFront']);
if($i){
$request->file('svgJerseyFront')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgJerseyFront')->getRealPath()));
//echo 'image move success';
}
}
@@ -318,7 +305,7 @@ class TemplatesController extends Controller {
if (array_key_exists('svgJerseyBack', $post)) {
$svgName = $request->file('svgJerseyBack')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'Type' => 'Jersey',
@@ -327,16 +314,13 @@ class TemplatesController extends Controller {
);
$i = $m->updateTemplatePaths($Templatedata, $post['id_svgJerseyBack']);
if($i){
$request->file('svgJerseyBack')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgJerseyBack')->getRealPath()));
}
}
if (array_key_exists('svgShortRight', $post)) {
$svgName = $request->file('svgShortRight')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'Type' => 'Shorts',
@@ -346,15 +330,13 @@ class TemplatesController extends Controller {
$i = $m->updateTemplatePaths($Templatedata, $post['id_svgShortRight']);
if($i){
$request->file('svgShortRight')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgShortRight')->getRealPath()));
}
}
if (array_key_exists('svgShortLeft', $post)) {
$svgName = $request->file('svgShortLeft')->getClientOriginalName();
$svgThumbnail = "uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$svgThumbnail = "uploads/images/uniform-templates/".$templateCode."/DISPLAY/".$svgName;
$Templatedata = array(
'Type' => 'Shorts',
@@ -364,9 +346,7 @@ class TemplatesController extends Controller {
$i = $m->updateTemplatePaths($Templatedata, $post['id_svgShortLeft']);
if($i){
$request->file('svgShortLeft')->move(
base_path() . '/public/images/uniform-templates/'.$templateCode. '/DISPLAY' , $svgName
);
Storage::disk('minio')->put('uploads/images/uniform-templates/'.$templateCode.'/DISPLAY/'.$svgName, file_get_contents($request->file('svgShortLeft')->getRealPath()));
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
class TestEmailController extends Controller
{
public function show()
{
return view('test-email', ['token' => csrf_token()]);
}
public function send(Request $request)
{
$this->validate($request, [
'recipient' => 'required|email',
]);
$recipient = $request->input('recipient');
$config = [
'driver' => config('mail.driver'),
'host' => config('mail.host'),
'port' => config('mail.port'),
'username' => config('mail.username'),
'encryption' => config('mail.encryption'),
];
try {
Mail::send('emails.test', ['config' => $config, 'recipient' => $recipient], function ($message) use ($recipient) {
$message->from('no-reply@crewsportswear.com', 'CREW Sportswear');
$message->to($recipient)->subject('CREW Sportswear — Test Email');
});
$status = 'success';
$message = 'Test email sent successfully to ' . $recipient . '.';
} catch (\Throwable $e) {
$status = 'danger';
$message = 'Failed to send email: ' . $e->getMessage();
}
return redirect()->back()->with('status', $status)->with('message', $message);
}
}

View File

@@ -41,6 +41,10 @@ Route::get('cart', ['as' => 'cart', 'uses' => 'teamstore\TeamStoreController@car
Route::get('/checkout', 'teamstore\TeamStoreController@checkout');
Route::get('/mail', 'teamstore\TeamStoreController@mail');
// Test email page
Route::get('/test-email', 'TestEmailController@show');
Route::post('/test-email/send', 'TestEmailController@send');
Route::get('/designer/{templateid}', 'designer\DesignerController@index');
Route::get('/designer/preview/{designCode}', 'designer\DesignerController@getDesign');

View File

@@ -77,7 +77,7 @@ return [
'port' => 22,
'username' => 'root',
'password' => '',
'privateKey' => '/var/www/html/_key/instance2/root.ppk',
'privateKey' => '/var/keys/root.ppk',
'root' => '/var/www/html/images',
'timeout' => 10
],

View File

@@ -18,6 +18,7 @@ return [
'prod_private_server_ip' => env('https://crewsportswear.app', 'https://crewsportswear.app'),
'images_url' => env('https://crewsportswear.app:5955', 'https://crewsportswear.app:5955'),
'minio_url' => env('MINIO_URL', 'https://minio.crewsportswear.app/crewsportswear'),
'uploads' => env('https://crewsportswear.com/uploads/images/', 'https://crewsportswear.com/uploads/images/'), // local

View File

@@ -31,6 +31,7 @@ services:
volumes:
- ./storage:/var/www/html/storage
- ./public/uploads:/var/www/html/public/uploads
- /var/crew-keys:/var/keys:ro
labels:
- "traefik.enable=true"
# Development environment (dev.crewsportswear.app)

View File

@@ -1,3 +1,19 @@
# ─────────────────────────────────────────────────────────────────────────────
# Local development stack
#
# Default (local MariaDB):
# docker compose -f docker-compose.local.yml up --build
#
# Remote DB via SSH private-key tunnel:
# 1. Set SSH_HOST, SSH_USER, SSH_KEY_PATH, SSH_DB_REMOTE_HOST,
# SSH_DB_REMOTE_PORT (and DB_* creds) in .env.local
# 2. docker compose -f docker-compose.local.yml --profile ssh-db up --build
# The app will talk to db-tunnel (port 3306) instead of the local db.
#
# App: http://localhost:8082
# phpMyAdmin: http://localhost:8083
# ─────────────────────────────────────────────────────────────────────────────
services:
db:
image: mariadb:10.6
@@ -29,11 +45,7 @@ services:
- APP_DEBUG=true
- APP_URL=http://localhost:8082
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=crewsportswear
- DB_USERNAME=crewsportswear
- DB_PASSWORD=secret
- DB_PORT=${DB_PORT:-3306}
- PROD_PRIVATE=http://localhost:8082
- IMAGES_URL=http://localhost:8082
- UPLOAD_URL=http://localhost:8082/uploads/
@@ -56,15 +68,65 @@ services:
- MINIO_REGION=us-east-1
- MINIO_USE_PATH_STYLE=false
- MINIO_URL=https://minio.crewsportswear.app
# DB_HOST defaults to local container; set to db-tunnel in .env.local for SSH mode
- DB_HOST=${DB_HOST:-db}
- DB_DATABASE=${DB_DATABASE:-crewsportswear}
- DB_USERNAME=${DB_USERNAME:-crewsportswear}
- DB_PASSWORD=${DB_PASSWORD:-secret}
env_file:
- path: .env.local
required: false
volumes:
- ./:/var/www/html
- ./storage:/var/www/html/storage
- ./public/uploads:/var/www/html/public/uploads
# Keep the vendor/ directory from the image — prevents the bind-mount
# from wiping out the composer install done during docker build.
- vendor_local:/var/www/html/vendor
depends_on:
- db
networks:
- crewsportswear-local
# ── SSH tunnel to a remote database ────────────────────────────────────────
# Activated only with: --profile ssh-db
# Requires SSH_HOST, SSH_USER, SSH_KEY_PATH (and optionally SSH_PORT,
# SSH_DB_REMOTE_HOST, SSH_DB_REMOTE_PORT) set in .env.local.
db-tunnel:
profiles:
- ssh-db
image: alpine:3.19
container_name: crewsportswear_db_tunnel
restart: unless-stopped
environment:
- SSH_HOST=${SSH_HOST}
- SSH_PORT=${SSH_PORT:-22}
- SSH_USER=${SSH_USER:-root}
- SSH_DB_REMOTE_HOST=${SSH_DB_REMOTE_HOST:-127.0.0.1}
- SSH_DB_REMOTE_PORT=${SSH_DB_REMOTE_PORT:-3306}
volumes:
# Mount your private key read-only; path configured in .env.local
- ${SSH_KEY_PATH:-~/.ssh/id_rsa}:/ssh/id_rsa:ro
command:
- sh
- -c
- |
apk add --no-cache openssh-client
cp /ssh/id_rsa /tmp/id_rsa
chmod 600 /tmp/id_rsa
echo "Starting SSH tunnel to $$SSH_HOST..."
exec ssh -N \
-o StrictHostKeyChecking=no \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
-i /tmp/id_rsa \
-L "0.0.0.0:3306:$$SSH_DB_REMOTE_HOST:$$SSH_DB_REMOTE_PORT" \
-p "$$SSH_PORT" \
"$$SSH_USER@$$SSH_HOST"
networks:
- crewsportswear-local
phpmyadmin:
image: arm64v8/phpmyadmin
platform: linux/arm64
@@ -87,3 +149,4 @@ networks:
volumes:
db_data:
vendor_local:

View File

@@ -31,6 +31,7 @@ services:
volumes:
- ./storage:/var/www/html/storage
- ./public/uploads:/var/www/html/public/uploads
- /var/crew-keys:/var/keys:ro
labels:
- "traefik.enable=true"
# Production environment (crewsportswear.com) - Uses paid SSL certificate

View File

@@ -13,5 +13,11 @@ mkdir -p bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache
chmod -R 775 storage bootstrap/cache
# Install/update Composer dependencies if vendor is missing or composer.json changed
if [ ! -f vendor/autoload.php ]; then
echo "vendor/autoload.php not found — running composer install..."
composer install --no-interaction --prefer-dist
fi
# Execute the main command
exec "$@"

View File

@@ -0,0 +1,90 @@
/**
* Augments canvas by assigning to `onObjectMove` and `onAfterRender`.
* This kind of sucks because other code using those methods will stop functioning.
* Need to fix it by replacing callbacks with pub/sub kind of subscription model.
* (or maybe use existing fabric.util.fire/observe (if it won't be too slow))
*/
function initCenteringGuidelines(canvas) {
var canvasWidth = canvas.getWidth(),
canvasHeight = canvas.getHeight(),
canvasWidthCenter = canvasWidth / 2,
canvasHeightCenter = canvasHeight / 2,
canvasWidthCenterMap = { },
canvasHeightCenterMap = { },
centerLineMargin = 4,
centerLineColor = 'rgba(255,0,241,0.5)',
centerLineWidth = 1,
ctx = canvas.getSelectionContext(),
viewportTransform;
for (var i = canvasWidthCenter - centerLineMargin, len = canvasWidthCenter + centerLineMargin; i <= len; i++) {
canvasWidthCenterMap[Math.round(i)] = true;
}
for (var i = canvasHeightCenter - centerLineMargin, len = canvasHeightCenter + centerLineMargin; i <= len; i++) {
canvasHeightCenterMap[Math.round(i)] = true;
}
function showVerticalCenterLine() {
showCenterLine(canvasWidthCenter + 0.5, 0, canvasWidthCenter + 0.5, canvasHeight);
}
function showHorizontalCenterLine() {
showCenterLine(0, canvasHeightCenter + 0.5, canvasWidth, canvasHeightCenter + 0.5);
}
function showCenterLine(x1, y1, x2, y2) {
ctx.save();
ctx.strokeStyle = centerLineColor;
ctx.lineWidth = centerLineWidth;
ctx.beginPath();
ctx.moveTo(x1 * viewportTransform[0], y1 * viewportTransform[3]);
ctx.lineTo(x2 * viewportTransform[0], y2 * viewportTransform[3]);
ctx.stroke();
ctx.restore();
}
var afterRenderActions = [],
isInVerticalCenter,
isInHorizontalCenter;
canvas.on('mouse:down', function () {
viewportTransform = canvas.viewportTransform;
});
canvas.on('object:moving', function(e) {
var object = e.target,
objectCenter = object.getCenterPoint(),
transform = canvas._currentTransform;
if (!transform) return;
isInVerticalCenter = Math.round(objectCenter.x) in canvasWidthCenterMap,
isInHorizontalCenter = Math.round(objectCenter.y) in canvasHeightCenterMap;
if (isInHorizontalCenter || isInVerticalCenter) {
object.setPositionByOrigin(new fabric.Point((isInVerticalCenter ? canvasWidthCenter : objectCenter.x), (isInHorizontalCenter ? canvasHeightCenter : objectCenter.y)), 'center', 'center');
}
});
canvas.on('before:render', function() {
if (canvas.contextTop) {
canvas.clearContext(canvas.contextTop);
}
});
canvas.on('after:render', function() {
if (isInVerticalCenter) {
showVerticalCenterLine();
}
if (isInHorizontalCenter) {
showHorizontalCenterLine();
}
});
canvas.on('mouse:up', function() {
// clear these values, to stop drawing guidelines once mouse is up
isInVerticalCenter = isInHorizontalCenter = null;
canvas.renderAll();
});
}

View File

@@ -886,8 +886,8 @@
<script src="{{asset('/designer/js/custom-script.js')}}"></script>
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>
<script src="{{asset('/designer/js/centering_guidelines.js')}}"></script>
<script src="{{asset('/designer/js/aligning_guidelines.js')}}"></script>
<script>
$(document).ready(function() {

View File

@@ -407,7 +407,7 @@
<td align="left" style="width: 180px;">
@foreach($img_thumb as $img)
@if($img->ProductId == $item->ProductId)
<img style="height: 200px; overflow: hidden; object-fit: contain;" src="{{ config('site_config.images_url') }}/{{ $img->Image }}">
<img style="height: 200px; overflow: hidden; object-fit: contain;" src="{{ minio_url('images/' . $img->Image) }}">
@endif
@endforeach
</td>

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Email CREW Sportswear</title>
</head>
<body style="font-family: Arial, sans-serif; color: #333; padding: 20px;">
<h2 style="color: #d9534f;">CREW Sportswear Test Email</h2>
<p>This is a test email to verify that the mail configuration is working correctly.</p>
<p>Sent to: <strong>{{ $recipient }}</strong></p>
<hr>
<p style="font-size: 12px; color: #777;">
<strong>Mail Config Used:</strong><br>
Driver: {{ $config['driver'] }}<br>
Host: {{ $config['host'] }}<br>
Port: {{ $config['port'] }}<br>
Username: {{ $config['username'] }}<br>
Encryption: {{ $config['encryption'] }}
</p>
<hr>
<p style="font-size: 12px; color: #aaa;">This is an automated test message from CREW Sportswear.</p>
</body>
</html>

View File

@@ -138,7 +138,7 @@
<div class="text-center">
@foreach($img_thumb as $img)
@if($img->ProductId == $item->ProductId)
<img class="previewImage" src="{{ config('site_config.images_url') }}/{{ $img->Image }}">
<img class="previewImage" src="{{ minio_url('images/' . $img->Image) }}">
@endif
@endforeach
</div>

View File

@@ -64,7 +64,7 @@
<table class="table">
<tr>
<td rowspan="2" class="text-center"><img class="previewImage" src="http://{{ config('site_config.images_url') }}/{{ $item->Image }} "></td>
<td rowspan="2" class="text-center"><img class="previewImage" src="{{ minio_url('images/' . $item->Image) }}"></td>
<td colspan="5">
<h4>{{ $item->ProductName }} {{ $itemOrder }} <br>Price: ${{ $item->Price }}</h4>
</td>

View File

@@ -127,6 +127,126 @@
overflow: hidden;
text-overflow: ellipsis;
}
/* ── Category nav ──────────────────────────────────────────────────────── */
.cat-nav {
background: #f8f8f8;
border-bottom: 2px solid #e0e0e0;
padding: 0;
margin-bottom: 24px;
}
.cat-nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
}
.cat-nav > ul > li {
position: relative;
}
.cat-nav > ul > li > a {
display: block;
padding: 14px 20px;
font-weight: 700;
font-size: 13px;
text-transform: uppercase;
color: #222;
text-decoration: none;
letter-spacing: .5px;
border-bottom: 3px solid transparent;
transition: border-color .2s, color .2s;
}
.cat-nav > ul > li > a:hover,
.cat-nav > ul > li > a.active {
color: #4B8E4B;
border-bottom-color: #4B8E4B;
}
/* sub-category dropdown */
.cat-nav .sub-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
min-width: 200px;
background: #fff;
border: 1px solid #ddd;
border-top: 3px solid #4B8E4B;
box-shadow: 0 4px 12px rgba(0,0,0,.12);
z-index: 999;
list-style: none;
margin: 0;
padding: 6px 0;
}
.cat-nav > ul > li:hover .sub-menu {
display: block;
}
.cat-nav .sub-menu li a {
display: block;
padding: 9px 18px;
font-size: 13px;
color: #333;
text-decoration: none;
white-space: nowrap;
}
.cat-nav .sub-menu li a:hover,
.cat-nav .sub-menu li a.active {
background: #f0f9f0;
color: #4B8E4B;
}
.cat-count {
display: inline-block;
background: #ddd;
border-radius: 10px;
font-size: 11px;
padding: 1px 7px;
margin-left: 4px;
vertical-align: middle;
}
/* ── League / conference pill filter (sub-sub-category) ─────────────────── */
.league-filter {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 10px 0 14px;
margin-bottom: 18px;
border-bottom: 1px solid #e8e8e8;
align-items: center;
}
.league-filter .lf-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
color: #888;
letter-spacing: .5px;
margin-right: 4px;
white-space: nowrap;
}
.league-filter a {
display: inline-block;
padding: 5px 14px;
border-radius: 20px;
background: #f0f0f0;
color: #333;
font-size: 12px;
font-weight: 600;
text-decoration: none;
white-space: nowrap;
border: 1px solid #ddd;
transition: background .2s, color .2s, border-color .2s;
}
.league-filter a:hover {
background: #e0f2e0;
color: #4B8E4B;
border-color: #4B8E4B;
}
.league-filter a.active {
background: #4B8E4B;
color: #fff;
border-color: #4B8E4B;
}
[v-cloak] { display: none; }
</style>
<div class="container">
@@ -150,80 +270,277 @@
<h2>FEATURED PRODUCTS</h2>
</div>
</div>
<div class="row">
{{-- ── Vue category + product grid ─────────────────────────────────────── --}}
<script>
window._tsProducts = {!! json_encode(
collect($product_array)
->where('PrivacyStatus', 'public')
->map(function($p) use ($thumbnails) {
$thumbList = isset($thumbnails) ? $thumbnails : [];
$thumb = collect($thumbList)->filter(function($t) use ($p) {
return $t['product_id'] == $p->Id;
})->first();
return [
'id' => $p->Id,
'name' => $p->ProductName,
'price' => $p->ProductPrice,
'url' => $p->ProductURL,
'img' => $thumb ? $thumb['thumb'] : 'product-image-placeholder.png',
'folder'=> $thumb ? $thumb['folder'] : '',
];
})->values()->toArray(),
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
) !!};
window._tsStore = {
url : {!! json_encode($store_array[0]->StoreUrl, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) !!},
currency : {!! json_encode($store_array[0]->StoreCurrency, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) !!},
minoBase : {!! json_encode(rtrim(config('filesystems.disks.minio.url', ''), '/') . '/' . env('MINIO_BUCKET', 'crewsportswear') . '/', JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) !!},
};
</script>
<div id="ts-app" v-cloak>
{{-- ── Category nav ── --}}
<nav class="cat-nav" v-if="categories.length > 0">
<ul>
<li>
<a href="#" :class="{active: activeCategory===null && activeSubCategory===null}"
@click.prevent="activeCategory=null; activeSubCategory=null">
All
<span class="cat-count">@{{ totalPublic }}</span>
</a>
</li>
<li v-for="cat in categories" :key="cat.name">
<a href="#"
:class="{active: activeCategory===cat.name}"
@click.prevent="selectCategory(cat.name)">
@{{ cat.name }}
<span class="cat-count">@{{ cat.count }}</span>
</a>
<ul class="sub-menu" v-if="cat.subs.length > 0">
<li v-for="sub in cat.subs" :key="sub.name">
<a href="#"
:class="{active: activeCategory===cat.name && activeSubCategory===sub.name}"
@click.prevent="selectSub(cat.name, sub.name)">
@{{ sub.name }}
<span class="cat-count">@{{ sub.count }}</span>
</a>
</li>
</ul>
</li>
</ul>
</nav>
{{-- ── League / conference pill filter ── --}}
<div class="league-filter" v-if="isLeagueStore && activeCategory !== null && leagues.length > 0">
<span class="lf-label">League / Conf:</span>
<a href="#"
:class="{active: activeLeague === null}"
@click.prevent="activeLeague = null">All</a>
<a href="#"
v-for="lg in leagues" :key="lg.name"
:class="{active: activeLeague === lg.name}"
@click.prevent="activeLeague = lg.name">
@{{ lg.name }}
<span class="cat-count">@{{ lg.count }}</span>
</a>
</div>
{{-- ── Announcements (kept outside loop) ── --}}
@if ($announcement->IsActive)
<div class="row">
<div class="col-md-12">
<div class="alert alert-info">
<p><b>Shop Announcements:</b></p>
{!! nl2br(e($announcement->Announcement)) !!}
</div>
</div>
</div>
</div>
@endif
@if($store_array[0]->Id == 174 || $store_array[0]->Id == 175 || $store_array[0]->Id == 178 || $store_array[0]->Id == 179 || $store_array[0]->Id == 177 || $store_array[0]->Id == 189 || $store_array[0]->Id == 176 || $store_array[0]->Id == 190 || $store_array[0]->Id == 191 || $store_array[0]->Id == 192 || $store_array[0]->Id == 194)
<div class="col-md-12">
<div class="alert alert-warning">
<p><b>Please read:</b></p>
1. All orders will be batch shipped to your school for pick up.<br>
2. Orders will be batch processed on a weekly basis, please allow 2-3 weeks for delivery.<br>
3. Masks and gaiters sold on Crew are not intended for medical use. Crew does not make any medical or health claims.<br>
4. Refunds and exchanges are not allowed due to the hygenic nature of the product.<br>
@if($store_array[0]->Id == 175)
5. $1 from every item sold will benefit the 2020-2021 Maine South Schoolwide Fundraiser.
@endif
</div>
</div>
@else
<div class="col-md-12">
<div class="alert alert-warning">
@if($store_array[0]->Id == 174 || $store_array[0]->Id == 175 || $store_array[0]->Id == 178 || $store_array[0]->Id == 179 || $store_array[0]->Id == 177 || $store_array[0]->Id == 189 || $store_array[0]->Id == 176 || $store_array[0]->Id == 190 || $store_array[0]->Id == 191 || $store_array[0]->Id == 192 || $store_array[0]->Id == 194)
<div class="row">
<div class="col-md-12">
<div class="alert alert-warning">
<p><b>Please read:</b></p>
1. Items purchased are made on demand. Orders will be shipped based on dates set by your store administrator.<br>
2. Store payments are processed through PayPal. A PayPal account is not required to make a purchase.<br>
@if($store_array[0]->Id == 222)
3. Orders will be batch processed on a monthly basis, please allow 4-6 weeks for delivery.<br>
@else
3. Orders will be batch processed on a weekly basis, please allow 2-3 weeks for delivery.<br>
1. All orders will be batch shipped to your school for pick up.<br>
2. Orders will be batch processed on a weekly basis, please allow 2-3 weeks for delivery.<br>
3. Masks and gaiters sold on Crew are not intended for medical use. Crew does not make any medical or health claims.<br>
4. Refunds and exchanges are not allowed due to the hygenic nature of the product.<br>
@if($store_array[0]->Id == 175)
5. $1 from every item sold will benefit the 2020-2021 Maine South Schoolwide Fundraiser.
@endif
4. We are currently only shipping to US locations. For international orders, please contact <b>orders@crewsportswear.com</b> if you'd like to place an order.<br>
5. Expect shipping delays due to COVID-19.<br>
6. All sales are final. No returns or exchanges will be accepted.<br><br>
<b>DISCLAIMER:</b> Masks and gaiters sold by Crew Sportswear are not intended for medical use. Crew Sportswear does not make any medical or health claims.
</div>
</div>
@endif
<!-- BEGIN PRODUCTS -->
@foreach($product_array as $i => $product)
@if($product->PrivacyStatus == "public")
@foreach($thumbnails as $t => $thumb)
@if($thumb['product_id'] == $product->Id)
@define $storeFolder = $thumb['folder']
@define $filename = $thumb['thumb']
@endif
@endforeach
<div class="col-md-3 col-sm-6">
<span class="thumbnail">
<a href="{{ url('teamstore') }}/{{ $store_array[0]->StoreUrl }}/product/{{ $product->ProductURL }}">
<img style="height: 201.84px;" src="{{ config('site_config.images_url') }}/{{ $filename }}" alt="{{ $product->ProductName }}" >
</a>
<h4 class="text-center product-name-holder">{{ $product->ProductName }}</h4>
<hr class="line">
<div class="row">
<div class="col-md-7 col-sm-7">
<p class="price">{{ $product->ProductPrice }} <small style="font-size: 15px;"> {{ $store_array[0]->StoreCurrency }}</small></p>
</div>
<div class="col-md-5 col-sm-5">
<a href="{{ url('teamstore') }}/{{ $store_array[0]->StoreUrl }}/product/{{ $product->ProductURL }}" class="btn btn-success right" > View Details</a>
</div>
</div>
</span>
</div>
@endif
@endforeach
<!-- END PRODUCTS -->
</div>
</div> <!-- cotainer -->
</div>
</div>
@endif
{{-- ── Product grid ── --}}
<div class="row">
<div class="col-md-12 text-center" v-if="filtered.length === 0">
<p style="margin:40px 0;color:#888;">No products found in this category.</p>
</div>
<div class="col-md-3 col-sm-6" v-for="p in filtered" :key="p.id">
<span class="thumbnail">
<a :href="productUrl(p)">
<img style="height:201.84px;" :src="imgUrl(p)" :alt="p.name">
</a>
<h4 class="text-center product-name-holder">@{{ p.name }}</h4>
<hr class="line">
<div class="row">
<div class="col-md-7 col-sm-7">
<p class="price">@{{ p.price }} <small style="font-size:15px;">@{{ store.currency }}</small></p>
</div>
<div class="col-md-5 col-sm-5">
<a :href="productUrl(p)" class="btn btn-success right">View Details</a>
</div>
</div>
</span>
</div>
</div>
</div>{{-- /ts-app --}}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script>
(function () {
// ── sport & item-type keyword maps ──────────────────────────────────
const SPORTS = [
'Basketball','Football','Soccer','Baseball','Softball',
'Volleyball','Hockey','Lacrosse','Wrestling','Tennis',
'Swimming','Track','Cross Country','Golf','Cheerleading',
'Dance','Rugby','Bowling','Gymnastics','Cycling',
];
const ITEMS = [
'Jersey','T-Shirt','Tee','Hoodie','Sweatshirt','Jacket',
'Shorts','Pants','Tank','Top','Pullover','Zip-Up',
'Hat','Cap','Beanie','Polo','Uniform','Warmup','Pinnie',
];
// ── league / conference keyword map ──────────────────────────────────
// Order matters: more specific phrases first
const LEAGUES = [
{ key: 'NBA', terms: ['nba'] },
{ key: 'NFL', terms: ['nfl'] },
{ key: 'MLB', terms: ['mlb'] },
{ key: 'NHL', terms: ['nhl'] },
{ key: 'MLS', terms: ['mls'] },
{ key: 'WNBA', terms: ['wnba'] },
{ key: 'Big Ten', terms: ['big ten','big10','big 10'] },
{ key: 'ACC', terms: ['acc'] },
{ key: 'SEC', terms: ['sec'] },
{ key: 'Big 12', terms: ['big 12','big12'] },
{ key: 'Pac-12', terms: ['pac-12','pac12','pac 12'] },
{ key: 'AAC', terms: ['aac'] },
{ key: 'CUSA', terms: ['cusa','c-usa'] },
{ key: 'MAC', terms: ['\bmac\b'] },
{ key: 'Sun Belt',terms: ['sun belt'] },
{ key: 'Mountain West', terms: ['mountain west','mwc'] },
];
function classify(name) {
const n = name.toLowerCase();
const sport = SPORTS.find(s => n.includes(s.toLowerCase())) || 'Other';
const item = ITEMS.find(i => n.includes(i.toLowerCase())) || 'Other';
let league = null;
for (const lg of LEAGUES) {
if (lg.terms.some(t => {
try { return new RegExp(t, 'i').test(n); } catch(e) { return n.includes(t); }
})) {
league = lg.key;
break;
}
}
return { sport, item, league };
}
const { createApp } = Vue;
const store = window._tsStore || { url:'', currency:'', minoBase:'' };
const allProducts = Array.isArray(window._tsProducts) ? window._tsProducts : [];
createApp({
data() {
return {
products : allProducts,
store : store,
activeCategory : null,
activeSubCategory: null,
activeLeague : null,
};
},
computed: {
totalPublic() {
return this.products.length;
},
isLeagueStore() {
return this.store.url === 'hi-five-franchise-store';
},
// Build [ { name:'Basketball', count:N, subs:[{name:'Jersey',count:N},...] }, ... ]
categories() {
const map = {};
this.products.forEach(p => {
const { sport, item } = classify(p.name);
if (!map[sport]) map[sport] = {};
map[sport][item] = (map[sport][item] || 0) + 1;
});
return Object.entries(map)
.sort((a,b) => a[0].localeCompare(b[0]))
.map(([name, subs]) => ({
name,
count: Object.values(subs).reduce((a,b) => a+b, 0),
subs: Object.entries(subs)
.sort((a,b) => a[0].localeCompare(b[0]))
.map(([s, count]) => ({ name: s, count }))
.filter(s => s.name !== 'Other' || Object.keys(subs).length === 1),
}));
},
// Available leagues for the currently active category (+ optional sub)
// Only computed for hi-five-franchise-store
leagues() {
if (!this.isLeagueStore) return [];
const map = {};
this.products.forEach(p => {
const { sport, item, league } = classify(p.name);
if (!league) return;
if (this.activeCategory && sport !== this.activeCategory) return;
if (this.activeSubCategory && item !== this.activeSubCategory) return;
map[league] = (map[league] || 0) + 1;
});
return Object.entries(map)
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([name, count]) => ({ name, count }));
},
filtered() {
if (!this.activeCategory && !this.activeLeague) return this.products;
return this.products.filter(p => {
const { sport, item, league } = classify(p.name);
if (this.activeCategory && sport !== this.activeCategory) return false;
if (this.activeSubCategory && item !== this.activeSubCategory) return false;
if (this.isLeagueStore && this.activeLeague && league !== this.activeLeague) return false;
return true;
});
},
},
methods: {
selectCategory(cat) {
this.activeCategory = cat;
this.activeSubCategory = null;
this.activeLeague = null;
},
selectSub(cat, sub) {
this.activeCategory = cat;
this.activeSubCategory = sub;
this.activeLeague = null;
},
productUrl(p) {
return '/teamstore/' + store.url + '/product/' + p.url;
},
imgUrl(p) {
return store.minoBase + 'images/' + p.img;
},
},
}).mount('#ts-app');
})();
</script>
</div>{{-- /container --}}
@endsection

View File

@@ -234,13 +234,13 @@
@if($thumbnail->ImageClass == 'active')
<div class="active item text-center" data-slide-number="{{ $i }}">
<span class="zoom img-zoom">
<img style="height:400px;" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image }}">
<img style="height:400px;" src="{{ minio_url('images/' . $thumbnail->Image) }}">
</span>
</div>
@else
<div class="item text-center" data-slide-number="{{ $i }}">
<span class="zoom img-zoom">
<img style="height:400px;" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image }}">
<img style="height:400px;" src="{{ minio_url('images/' . $thumbnail->Image) }}">
</span>
</div>
@endif
@@ -269,7 +269,7 @@
@foreach($thumbnails_array as $thumbnail)
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail {{ $thumbnail->ImageClass }}" id="carousel-selector-{{ $j }}">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image }}"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $thumbnail->Image) }}"/>
</a>
</li>
@define $j++

View File

@@ -0,0 +1,56 @@
@extends('layout.main')
@section('content')
<div class="row">
<div class="col-md-6 col-md-offset-3" style="margin-top: 40px; margin-bottom: 40px;">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><strong>Send Test Email</strong></h3>
</div>
<div class="panel-body">
@if (session('message'))
<div class="alert alert-{{ session('status') }} alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
{{ session('message') }}
</div>
@endif
<!-- Mail Config Info -->
<div class="well well-sm" style="font-size: 12px;">
<strong>Current Mail Config</strong><br>
Driver: <code>{{ config('mail.driver') ?: '(not set)' }}</code><br>
Host: <code>{{ config('mail.host') ?: '(not set)' }}</code><br>
Port: <code>{{ config('mail.port') ?: '(not set)' }}</code><br>
Username: <code>{{ config('mail.username') ?: '(not set)' }}</code><br>
Encryption: <code>{{ config('mail.encryption') ?: '(not set)' }}</code>
</div>
<form method="POST" action="{{ url('test-email/send') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="token" value="{{ $token }}">
<div class="form-group{{ $errors->has('recipient') ? ' has-error' : '' }}">
<label for="recipient">Recipient Email</label>
<input type="email"
name="recipient"
id="recipient"
class="form-control"
placeholder="you@example.com"
value="{{ old('recipient') }}"
required>
@if ($errors->has('recipient'))
<span class="help-block">{{ $errors->first('recipient') }}</span>
@endif
</div>
<button type="submit" class="btn btn-primary btn-block">
<i class="fa fa-envelope"></i> Send Test Email
</button>
</form>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -42,7 +42,7 @@
@foreach($array_client_designs as $row)
@foreach($array_template_paths as $key => $row1)
@if($key == 0)
<img src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
<img src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
@endif
@endforeach
@endforeach
@@ -56,7 +56,7 @@
@if($key == 0)
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail active">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}"/>
</a>
<!-- <p>Select Default Thumbnail:</p>
<div class="text-center">
@@ -66,7 +66,7 @@
@else
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-{{ strtolower($row1->Side) }}-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-' . strtolower($row1->Side) . '-thumbnail.png') }}"/>
</a>
<!-- <p>&nbsp;</p>
<div class="text-center">

View File

@@ -32,7 +32,7 @@
@foreach($array_client_designs as $row)
<div class="col-md-3 col-sm-6">
<span class="thumbnail">
<img src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png" alt="{{ $row->DesignName }}" >
<img src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}" alt="{{ $row->DesignName }}" >
<h4 class="design-name-holder">{{ $row->DesignName }}</h4>
<small>{{ date('F j, Y g:i a', strtotime($row->DateCreated)) }}</small>
<hr class="line">

View File

@@ -33,7 +33,7 @@
<div class="row">
<div class="col-md-2">
<div class="text-center">
<img class="previewImage" id="active_thumbnail" src="{{ config('site_config.images_url') . '/images/' . $array_thumbnail_display[0]->Image }}">
<img class="previewImage" id="active_thumbnail" src="{{ minio_url('images/' . $array_thumbnail_display[0]->Image) }}">
</div>
</div>
<div class="col-md-10">

View File

@@ -93,7 +93,7 @@
<div class="text-center">
@foreach($img_thumb as $img)
@if($img->ProductId == $item->ProductId)
<img class="previewImage" src="{{ config('site_config.images_url') }}/{{ $img->Image }}">
<img class="previewImage" src="{{ minio_url('images/' . $img->Image) }}">
@endif
@endforeach
</div>

View File

@@ -42,7 +42,7 @@
@foreach($array_client_designs as $row)
@foreach($array_template_paths as $key => $row1)
@if($key == 0)
<img src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
<img src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
@endif
@endforeach
@endforeach
@@ -56,7 +56,7 @@
@if($key == 0)
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail active">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}"/>
</a>
<!-- <p>Select Default Thumbnail:</p>
<div class="text-center">
@@ -66,7 +66,7 @@
@else
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-{{ strtolower($row1->Side) }}-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-' . strtolower($row1->Side) . '-thumbnail.png') }}"/>
</a>
<!-- <p>&nbsp;</p>
<div class="text-center">

View File

@@ -59,7 +59,7 @@
<div class="col-md-3 col-sm-6">
<div class="thumbnail" >
<a href="{{ url('user/store-items/item') }}/{{ $product->ProductURL }}">
<img style="height:200px" src="{{ config('site_config.images_url') }}/{{ $filename . '?t=' . time() }}" alt="{{ $product->ProductName }}" >
<img style="height:200px" src="{{ minio_url('images/' . $filename) . '?t=' . time() }}" alt="{{ $product->ProductName }}" >
</a>
<hr class="line">
<div class="pull-right">

View File

@@ -63,7 +63,7 @@
<div id="{{ 'order_number_' . $product->Id }}">
<div class="thumbnail" >
<a href="#">
<img style="height:200px" src="{{ config('site_config.images_url') }}/{{ $filename . '?t=' . time() }}" alt="{{ $product->ProductName }}" >
<img style="height:200px" src="{{ minio_url('images/' . $filename) . '?t=' . time() }}" alt="{{ $product->ProductName }}" >
</a>
<hr class="line">
<div class="pull-right">

View File

@@ -39,7 +39,7 @@
@foreach($array_client_designs as $row)
@foreach($array_template_paths as $key => $row1)
@if($key == 0)
<img src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
<img src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}" alt="{{ $row->DesignName }}" id="main-thumbnail" class="img img-responsive">
@endif
@endforeach
@endforeach
@@ -53,13 +53,13 @@
@if($key == 0)
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail active">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-front-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-front-thumbnail.png') }}"/>
</a>
</li>
@else
<li class="col-sm-3 col-xs-3">
<a class="thumbnail a_thumbnail">
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $row->DesignCode }}-{{ strtolower($row1->Side) }}-thumbnail.png"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $row->DesignCode . '-' . strtolower($row1->Side) . '-thumbnail.png') }}"/>
</a>
</li>
@endif

View File

@@ -36,7 +36,7 @@
<div class="col-md-12 text-center">
@foreach($thumbnails_array as $thumbnail)
@if($thumbnail->ImageClass == 'active')
<img style="height:400px" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image . '?t=' . time() }}" id="main-thumbnail">
<img style="height:400px" src="{{ minio_url('images/' . $thumbnail->Image) . '?t=' . time() }}" id="main-thumbnail">
@endif
@endforeach
</div>
@@ -58,7 +58,7 @@
<li class="col-sm-3 col-xs-4">
<a class="thumbnail a_thumbnail {{ $thumbnail->ImageClass }}" style="border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; margin-bottom: -28px;">
<!-- <span class="close">&times;</span> -->
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image . '?t=' . time() }}"/>
<img class="img img-responsive product-center image-thumbnails" style="height: 59.45px;" src="{{ minio_url('images/' . $thumbnail->Image) . '?t=' . time() }}"/>
</a>
<div class="funkyradio">
<div class="funkyradio-primary">
@@ -200,7 +200,7 @@
<tr id="{{ 'item-' . $thumbnail->Id }}">
<td class="text-center" style="width: 50px"><i class="fa fa-bars"></i></td>
<td><img class="img img-responsive product-center" style="height: 59.45px;" src="{{ config('site_config.images_url') }}/{{ $thumbnail->Image . '?t=' . time() }}"/></td>
<td><img class="img img-responsive product-center" style="height: 59.45px;" src="{{ minio_url('images/' . $thumbnail->Image) . '?t=' . time() }}"/></td>
<td class="text-center">
<!-- <button class="btn btn-default btn-xs btn-edit-clipart" data-id="#"><i class="fa fa-edit"></i></button> -->
<button class="btn btn-default btn-sm btn-delete-item-image" data-id="{{ $thumbnail->Id }}" data-filename="{{ $thumbnail->Image }}" title="Delete Image"><i class="fa fa-trash"></i></button>