-
Additional Team Members
- {options.additionalUsers.map((user, index) => (
-
+
+
Company Banner Options
+
+
Company Logo
+
- ))}
-
+
+ {options.displayCompanyLogo && (
+
+
+
+ The logo should be a PNG or JPEG file with a transparent or white background.
+
+
+ )}
+
+
+
Additional Team Members
+ {options.additionalUsers.map((user, index) => (
+
+ {
+ const newUsers = [...options.additionalUsers];
+ newUsers[index] = e.target.value;
+ setOptions({ ...options, additionalUsers: newUsers });
+ }}
+ placeholder={`Enter team member ${index + 1} username`}
+ className='input'
+ />
+
+
+ ))}
+
+
)}
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 7c87e1f7..15985761 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -1250,7 +1250,7 @@ select:focus {
}
.additional-users h4 {
- margin: 0 0 1rem 0;
+ margin: 0 0 1rem;
color: var(--text-contrast);
}
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index 6f3376a2..b24f8c96 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -121,8 +121,18 @@ export const generateImage = async (options) => {
}
// Rank Logo
+ let rankLogoBuffer;
+ console.log('Company Banner:', options.isCompanyBanner);
+ console.log('Company Logo URL:', options.companyLogoUrl);
+ if (options.isCompanyBanner && options.companyLogoUrl) {
+ if (!(await isValidImageType(options.companyLogoUrl))) {
+ throw new Error('Unsupported image type for company logo');
+ }
+ rankLogoBuffer = await loadImage(options.companyLogoUrl);
+ } else {
+ rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
+ }
try {
- const rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
const rankLogo = await loadImage(rankLogoBuffer);
rankLogoHeight = canvas.height * top_part * 1;
rankLogoWidth = (rankLogo.width / rankLogo.height) * rankLogoHeight; // Maintain aspect ratio
diff --git a/src/utils/trailblazerUtils.js b/src/utils/trailblazerUtils.js
index aa8d082d..d869ab40 100644
--- a/src/utils/trailblazerUtils.js
+++ b/src/utils/trailblazerUtils.js
@@ -13,10 +13,7 @@ function mergeTrailblazerData(trailblazerDataArray) {
trails: 0,
completedTrailCount: 0,
earnedPointsSum: 0,
- rank: {
- imageUrl:
- 'https://res.cloudinary.com/trailhead/image/upload/public-trailhead/assets/images/ranks/triple-star-ranger.png',
- },
+ rank: {},
learnerStatusLevels: [],
},
certificationsData: {
From b6ad4b051a753655cf86dc23c34df98bde02672a Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 20:10:24 +0200
Subject: [PATCH 09/17] fix(generateImage): adjust rank logo handling logic
---
src/utils/generateImage.js | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index b24f8c96..4df0ea5a 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -73,7 +73,7 @@ const isValidImageType = async (url) => {
export const generateImage = async (options) => {
// Options logging
- logOptions(options);
+ // logOptions(options);
// Warning
const warnings = [];
@@ -122,15 +122,13 @@ export const generateImage = async (options) => {
// Rank Logo
let rankLogoBuffer;
- console.log('Company Banner:', options.isCompanyBanner);
- console.log('Company Logo URL:', options.companyLogoUrl);
- if (options.isCompanyBanner && options.companyLogoUrl) {
+ if (!options.isCompanyBanner && options.companyLogoUrl) {
+ rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
+ } else if (options.displayCompanyLogo && options.companyLogoUrl) {
if (!(await isValidImageType(options.companyLogoUrl))) {
throw new Error('Unsupported image type for company logo');
}
rankLogoBuffer = await loadImage(options.companyLogoUrl);
- } else {
- rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
}
try {
const rankLogo = await loadImage(rankLogoBuffer);
From cea97fc26b498bd0659a385f9b7365c131923c3a Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 20:15:15 +0200
Subject: [PATCH 10/17] fix(generateImage): initialize rankLogoBuffer to null
and set default dimensions for missing rank logo
---
src/utils/generateImage.js | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index 4df0ea5a..97a1928e 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -121,7 +121,7 @@ export const generateImage = async (options) => {
}
// Rank Logo
- let rankLogoBuffer;
+ let rankLogoBuffer = null;
if (!options.isCompanyBanner && options.companyLogoUrl) {
rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
} else if (options.displayCompanyLogo && options.companyLogoUrl) {
@@ -129,20 +129,26 @@ export const generateImage = async (options) => {
throw new Error('Unsupported image type for company logo');
}
rankLogoBuffer = await loadImage(options.companyLogoUrl);
+ } else {
+ rankLogoWidth = 100;
+ rankLogoHeight = 40;
+ console.warn('No rank logo found, using default dimensions.');
}
- try {
- const rankLogo = await loadImage(rankLogoBuffer);
- rankLogoHeight = canvas.height * top_part * 1;
- rankLogoWidth = (rankLogo.width / rankLogo.height) * rankLogoHeight; // Maintain aspect ratio
- const rankLogoScalingFactor = 1.2;
- if (options.displayRankLogo) {
- ctx.drawImage(rankLogo, 0, 0, rankLogoWidth * rankLogoScalingFactor, rankLogoHeight * rankLogoScalingFactor);
+ if (rankLogoBuffer !== null) {
+ try {
+ const rankLogo = await loadImage(rankLogoBuffer);
+ rankLogoHeight = canvas.height * top_part * 1;
+ rankLogoWidth = (rankLogo.width / rankLogo.height) * rankLogoHeight; // Maintain aspect ratio
+ const rankLogoScalingFactor = 1.2;
+ if (options.displayRankLogo) {
+ ctx.drawImage(rankLogo, 0, 0, rankLogoWidth * rankLogoScalingFactor, rankLogoHeight * rankLogoScalingFactor);
+ }
+ } catch (error) {
+ rankLogoWidth = 100;
+ rankLogoHeight = 40;
+ console.error(`Error loading rank logo ${options.rankData.rank.imageUrl}:`, error);
+ warnings.push(`Error loading rank logo ${options.rankData.rank.imageUrl}: ${error.message}`);
}
- } catch (error) {
- rankLogoWidth = 180;
- rankLogoHeight = 40;
- console.error(`Error loading rank logo ${options.rankData.rank.imageUrl}:`, error);
- warnings.push(`Error loading rank logo ${options.rankData.rank.imageUrl}: ${error.message}`);
}
// Counters
From 84904684c6be3a8f28a4934fff971693bc0c5639 Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 20:16:07 +0200
Subject: [PATCH 11/17] fix(generateImage): set default dimensions for rank
logo and remove redundant width/height assignments
---
src/utils/generateImage.js | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index 97a1928e..858040d1 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -21,8 +21,8 @@ require('./fonts');
const top_part = 1 / 4;
const bottom_part = 3 / 4;
const right_part = 7 / 10;
-let rankLogoWidth;
-let rankLogoHeight;
+let rankLogoWidth = 120;
+let rankLogoHeight = 40;
const isValidImageType = async (url) => {
try {
@@ -129,10 +129,6 @@ export const generateImage = async (options) => {
throw new Error('Unsupported image type for company logo');
}
rankLogoBuffer = await loadImage(options.companyLogoUrl);
- } else {
- rankLogoWidth = 100;
- rankLogoHeight = 40;
- console.warn('No rank logo found, using default dimensions.');
}
if (rankLogoBuffer !== null) {
try {
@@ -144,8 +140,6 @@ export const generateImage = async (options) => {
ctx.drawImage(rankLogo, 0, 0, rankLogoWidth * rankLogoScalingFactor, rankLogoHeight * rankLogoScalingFactor);
}
} catch (error) {
- rankLogoWidth = 100;
- rankLogoHeight = 40;
console.error(`Error loading rank logo ${options.rankData.rank.imageUrl}:`, error);
warnings.push(`Error loading rank logo ${options.rankData.rank.imageUrl}: ${error.message}`);
}
From a73ace4bbe606d00db860b6beca4d30f13b7d7bd Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 23:07:02 +0200
Subject: [PATCH 12/17] feat(BannerForm): add company logo options with select
input for logo type and upload functionality
---
src/components/BannerForm.js | 51 +++++++++++++++++++++++++++++-------
1 file changed, 42 insertions(+), 9 deletions(-)
diff --git a/src/components/BannerForm.js b/src/components/BannerForm.js
index 05635b34..828cd7fc 100644
--- a/src/components/BannerForm.js
+++ b/src/components/BannerForm.js
@@ -68,7 +68,8 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
additionalUsers: [],
isCompanyBanner: false,
companyLogoUrl: '',
- displayCompanyLogo: false,
+ companyLogoKind: 'no',
+ companyLogoUploadUrl: '',
backgroundColor: '#5badd6',
backgroundImageUrl: '',
displayBadgeCount: true,
@@ -293,15 +294,18 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
Company Banner Options
Company Logo
-
Additional Team Members
From 9e0e04298d0ea14103e6d0aecaa98bb43bd1351a Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 23:29:33 +0200
Subject: [PATCH 13/17] fix(generateImage): improve company logo handling and
add logging for debugging
---
src/components/BannerForm.js | 4 +---
src/utils/generateImage.js | 7 +++++--
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/components/BannerForm.js b/src/components/BannerForm.js
index 828cd7fc..d8bb7f61 100644
--- a/src/components/BannerForm.js
+++ b/src/components/BannerForm.js
@@ -317,9 +317,7 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
className='input'
/>
-
- The logo should be a PNG or JPEG file with a transparent or white background.
-
+
)}
{options.companyLogoKind === 'upload' && (
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index 858040d1..d7e80133 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -122,9 +122,12 @@ export const generateImage = async (options) => {
// Rank Logo
let rankLogoBuffer = null;
- if (!options.isCompanyBanner && options.companyLogoUrl) {
+ console.log('companyLogoKind:', options.companyLogoKind);
+ console.log('Company Logo URL:', options.companyLogoUrl);
+ if (!options.isCompanyBanner) {
rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
- } else if (options.displayCompanyLogo && options.companyLogoUrl) {
+ } else if (options.isCompanyBanner && options.companyLogoKind != 'no' && options.companyLogoUrl) {
+ console.log('Loading company logo from URL:', options.companyLogoUrl);
if (!(await isValidImageType(options.companyLogoUrl))) {
throw new Error('Unsupported image type for company logo');
}
From f6d66d64e5395246171b0b8d6637435083dc4df8 Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 23:35:00 +0200
Subject: [PATCH 14/17] fix(BannerForm): enhance company logo handling with
file reader and update state management
---
src/components/BannerForm.js | 38 +++++++++++++++++++++---------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/src/components/BannerForm.js b/src/components/BannerForm.js
index d8bb7f61..ba6f3083 100644
--- a/src/components/BannerForm.js
+++ b/src/components/BannerForm.js
@@ -142,8 +142,27 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
handleCustomUrlChange(e.target.value, setOptions, setBackgroundImageUrlError);
};
- const handleImageChange = async (e) => {
- await handleFileChange(e.target.files[0], setBackgroundImageUrlError, setOptions, setUploadedFile);
+ const handleImageChange = async (e, isCompanyLogo = false) => {
+ if (isCompanyLogo) {
+ const file = e.target.files[0];
+ if (!file) return;
+
+ try {
+ const reader = new FileReader();
+ reader.onload = () => {
+ setOptions({
+ ...options,
+ companyLogoUrl: reader.result,
+ companyLogoUploadUrl: reader.result,
+ });
+ };
+ reader.readAsDataURL(file);
+ } catch (error) {
+ console.error('Error reading company logo file:', error);
+ }
+ } else {
+ await handleFileChange(e.target.files[0], setBackgroundImageUrlError, setOptions, setUploadedFile);
+ }
};
const handlePredefinedImage = (src) => {
@@ -327,20 +346,7 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
{
- await handleFileChange(
- e.target.files[0],
- null,
- (newOptions) => {
- setOptions({
- ...options,
- companyLogoUrl: newOptions.backgroundImageUrl,
- companyLogoUploadUrl: newOptions.backgroundImageUrl,
- });
- },
- null
- );
- }}
+ onChange={(e) => handleImageChange(e, true)}
className='input-file'
/>
From 2a08f087e18fba4f99343f5a8b59df363b83bf40 Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sat, 31 May 2025 23:37:18 +0200
Subject: [PATCH 15/17] feat(dataUtils): add logging for company options in
logOptions function
---
src/utils/dataUtils.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/utils/dataUtils.js b/src/utils/dataUtils.js
index 9673ef7c..ad89cb19 100644
--- a/src/utils/dataUtils.js
+++ b/src/utils/dataUtils.js
@@ -56,4 +56,9 @@ export const logOptions = (options) => {
certificationAlignment: options.certificationAlignment,
});
console.log('MVP Data:', options.mvpData);
+ console.log('Company Options:', {
+ isCompanyBanner: options.isCompanyBanner,
+ companyName: options.companyName,
+ companyLogoUrl: options.companyLogoUrl,
+ });
};
From e23c013580f0175d12935aafbeb0565fa7bcea6e Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sun, 1 Jun 2025 00:04:11 +0200
Subject: [PATCH 16/17] feat(BannerForm): add state for uploaded logo file and
display selected file info
---
src/components/BannerForm.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/components/BannerForm.js b/src/components/BannerForm.js
index ba6f3083..2035bb60 100644
--- a/src/components/BannerForm.js
+++ b/src/components/BannerForm.js
@@ -99,6 +99,7 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
displayAgentblazerRank: true,
});
const [uploadedFile, setUploadedFile] = useState(null);
+ const [uploadedLogoFile, setUploadedLogoFile] = useState(null);
const [showOptions, setShowOptions] = useState(false);
const [isGenerating, setIsGenerating] = useState(false);
const [usernameError, setUsernameError] = useState('');
@@ -155,6 +156,7 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
companyLogoUrl: reader.result,
companyLogoUploadUrl: reader.result,
});
+ setUploadedLogoFile(file);
};
reader.readAsDataURL(file);
} catch (error) {
@@ -320,8 +322,8 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
onChange={(e) => setOptions({ ...options, companyLogoKind: e.target.value })}
>
-
+
{options.companyLogoKind === 'url' && (
@@ -350,9 +352,8 @@ const BannerForm = ({ onSubmit, setMainError, onValidationError }) => {
className='input-file'
/>
-
- The logo should be a PNG or JPEG file with a transparent or white background.
-
+ {uploadedLogoFile &&
Selected file: {uploadedLogoFile.name}
}
+
)}
From 85e31be082d9c79ab4029149d6b824378ab3df23 Mon Sep 17 00:00:00 2001
From: Nathan Abondance <32196400+nabondance@users.noreply.github.com>
Date: Sun, 1 Jun 2025 00:14:03 +0200
Subject: [PATCH 17/17] fix(generateImage): remove console logs for company
logo handling
---
src/utils/generateImage.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/utils/generateImage.js b/src/utils/generateImage.js
index d7e80133..cc705d33 100644
--- a/src/utils/generateImage.js
+++ b/src/utils/generateImage.js
@@ -122,12 +122,9 @@ export const generateImage = async (options) => {
// Rank Logo
let rankLogoBuffer = null;
- console.log('companyLogoKind:', options.companyLogoKind);
- console.log('Company Logo URL:', options.companyLogoUrl);
if (!options.isCompanyBanner) {
rankLogoBuffer = await getImage(options.rankData.rank.imageUrl, 'ranks');
} else if (options.isCompanyBanner && options.companyLogoKind != 'no' && options.companyLogoUrl) {
- console.log('Loading company logo from URL:', options.companyLogoUrl);
if (!(await isValidImageType(options.companyLogoUrl))) {
throw new Error('Unsupported image type for company logo');
}