feat: initial commit - Band Management application

This commit is contained in:
2026-01-06 03:11:46 +01:00
commit 34e12e00b3
24543 changed files with 3991790 additions and 0 deletions

View File

@@ -0,0 +1,240 @@
const path = require('path');
const { src, dest, series, parallel } = require('gulp');
const sass = require('gulp-dart-sass');
const localSass = require('sass');
const autoprefixer = require('gulp-autoprefixer');
const exec = require('gulp-exec');
const gulpIf = require('gulp-if');
const sourcemaps = require('gulp-sourcemaps');
const browserSync = require('browser-sync').create();
const useref = require('gulp-useref');
const webpack = require('webpack');
const log = require('fancy-log');
const colors = require('ansi-colors');
const rename = require('gulp-rename');
module.exports = (conf, srcGlob) => {
// Build CSS
// -------------------------------------------------------------------------------
const buildCssTask = function (cb) {
return src(srcGlob('**/*.scss', '!**/_*.scss'))
.pipe(gulpIf(conf.sourcemaps, sourcemaps.init()))
.pipe(
// If sass is installed on your local machine, it will use command line to compile sass else it will use dart sass npm which 3 time slower
gulpIf(
localSass,
exec(
// If conf.minify == true, generate compressed style without sourcemap
gulpIf(
conf.minify,
`sass --load-path=node_modules/ scss:${conf.distPath}/css fonts:${conf.distPath}/fonts libs:${conf.distPath}/libs --style compressed --no-source-map`,
`sass --load-path=node_modules/ scss:${conf.distPath}/css fonts:${conf.distPath}/fonts libs:${conf.distPath}/libs --no-source-map`
),
function (err) {
cb(err);
}
),
sass
.sync({
includePaths: ['node_modules'], // Add this line to include node_modules
outputStyle: conf.minify ? 'compressed' : 'expanded'
})
.on('error', sass.logError)
)
)
.pipe(gulpIf(conf.sourcemaps, sourcemaps.write()))
.pipe(
rename(function (path) {
path.dirname = path.dirname.replace('scss', 'css');
})
)
.pipe(dest(conf.distPath))
.pipe(browserSync.stream());
};
// Autoprefix css
const buildAutoprefixCssTask = function (cb) {
return src(conf.distPath + '/css/**/*.css')
.pipe(
gulpIf(
conf.sourcemaps,
sourcemaps.init({
loadMaps: true
})
)
)
.pipe(autoprefixer())
.pipe(gulpIf(conf.sourcemaps, sourcemaps.write()))
.pipe(dest(conf.distPath + '/css'))
.pipe(browserSync.stream());
};
// Build JS
// -------------------------------------------------------------------------------
const buildJsTask = function (cb) {
setTimeout(function () {
webpack(require('../webpack.config'), (err, stats) => {
if (err) {
log(colors.gray('Webpack error:'), colors.red(err.stack || err));
if (err.details) log(colors.gray('Webpack error details:'), err.details);
return cb();
}
const info = stats.toJson();
if (stats.hasErrors()) {
info.errors.forEach(e => log(colors.gray('Webpack compilation error:'), colors.red(e)));
}
if (stats.hasWarnings()) {
info.warnings.forEach(w => log(colors.gray('Webpack compilation warning:'), colors.yellow(w)));
}
// Print log
log(
stats.toString({
colors: colors.enabled,
hash: false,
timings: false,
chunks: false,
chunkModules: false,
modules: false,
children: true,
version: true,
cached: false,
cachedAssets: false,
reasons: false,
source: false,
errorDetails: false
})
);
cb();
browserSync.reload();
});
}, 1);
};
// Build fonts
// -------------------------------------------------------------------------------
const FONT_TASKS = [
{
name: 'fontawesome',
path: 'node_modules/@fortawesome/fontawesome-free/webfonts/*'
},
{
name: 'flags',
path: 'node_modules/flag-icons/flags/**/*'
},
{
name: 'tabler',
path: 'node_modules/@tabler/icons/iconfont/fonts/*'
}
].reduce(function (tasks, font) {
const functionName = `buildFonts${font.name.replace(/^./, m => m.toUpperCase())}Task`;
const taskFunction = function () {
// return src(root(font.path))
return (
src(font.path)
// .pipe(dest(normalize(path.join(conf.distPath, 'fonts', font.name))))
.pipe(dest(path.join(conf.distPath, 'fonts', font.name)))
);
};
Object.defineProperty(taskFunction, 'name', {
value: functionName
});
return tasks.concat([taskFunction]);
}, []);
// Formula module requires KaTeX - Quill Editor
const KATEX_FONT_TASK = [
{
name: 'katex',
path: 'node_modules/katex/dist/fonts/*'
}
].reduce(function (tasks, font) {
const functionName = `buildFonts${font.name.replace(/^./, m => m.toUpperCase())}Task`;
const taskFunction = function () {
return src(font.path).pipe(dest(path.join(conf.distPath, '/libs/quill/fonts')));
};
Object.defineProperty(taskFunction, 'name', {
value: functionName
});
return tasks.concat([taskFunction]);
}, []);
const buildFontsTask = parallel(FONT_TASKS, KATEX_FONT_TASK);
// Copy
// -------------------------------------------------------------------------------
const buildCopyTask = function () {
return src(
srcGlob(
'**/*.png',
'**/*.gif',
'**/*.jpg',
'**/*.jpeg',
'**/*.svg',
'**/*.swf',
'**/*.eot',
'**/*.ttf',
'**/*.woff',
'**/*.woff2'
)
).pipe(dest(conf.distPath));
};
// Combine js vendor assets in single theme file using UseRef
// -------------------------------------------------------------------------------
const assetsBuildTasks = function () {
return src(`${conf.buildTemplatePath}/*.html`).pipe(useref()).pipe(dest(conf.buildTemplatePath));
};
// Iconify task
// -------------------------------------------------------------------------------
const buildIconifyTask = function (cb) {
// Create required directories without copying files
const fs = require('fs');
const directories = ['./fonts/iconify', './assets/vendor/fonts'];
directories.forEach(dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
});
const iconify = require('child_process').spawn('node', ['./fonts/iconify/iconify.js']);
iconify.stdout.on('data', data => {
console.log(data.toString());
});
iconify.stderr.on('data', data => {
console.error(data.toString());
});
iconify.on('close', code => {
cb();
});
};
const buildAllTask = series(buildCssTask, buildJsTask, buildFontsTask, buildCopyTask, buildIconifyTask);
// Exports
// ---------------------------------------------------------------------------
return {
css: series(buildCssTask, buildAutoprefixCssTask),
js: buildJsTask,
theme: assetsBuildTasks,
fonts: buildFontsTask,
copy: buildCopyTask,
iconify: buildIconifyTask,
all: buildAllTask
};
};

View File

@@ -0,0 +1,153 @@
const path = require('path');
const { src, dest, series } = require('gulp');
const purgecss = require('gulp-purgecss');
const replace = require('gulp-replace');
const useref = require('gulp-useref');
var uglify = require('gulp-uglify');
const fs = require('fs');
module.exports = conf => {
// Copy templatePath html files and assets to buildPath
// -------------------------------------------------------------------------------
const prodCopyHTMLTask = function () {
return src(`${templatePath}/*.html`).pipe(dest(`${buildPath}/`));
};
const prodCopyAssetsTask = function () {
return src('assets/**/*').pipe(dest(`${buildPath}/assets/`));
};
// Rename assets path
// -------------------------------------------------------------------------------
const prodRenameTasks = function () {
return src(`${buildPath}/**/*`)
.pipe(replace('../../assets', 'assets'))
.pipe(dest(`${buildPath}`));
};
// Combine js vendor assets in single core.js file using UseRef
// -------------------------------------------------------------------------------
const prodUseRefTasks = function () {
return src(`${buildPath}/*.html`).pipe(useref()).pipe(dest(buildPath));
};
// Uglify assets/js files
//--------------------------------------------------------------------------------
const prodMinifyJSTasks = function () {
return src(`${buildPath}/assets/js/**/*.js`)
.pipe(uglify())
.pipe(dest(`${buildPath}/assets/js/`));
};
// Suppress DeprecationWarning for useref()
process.removeAllListeners('warning');
process.on('warning', warning => {
if (warning.name === 'DeprecationWarning' && warning.code === 'DEP0180') {
return;
}
console.warn(warning.name, warning.message);
});
const prodPurgecssTasks = function () {
let iconClasses = [];
try {
// Define the directory where JSON files are stored
const jsonDirectory = path.join(__dirname, '../assets/json');
// Read all JSON files in the directory
const files = fs.readdirSync(jsonDirectory).filter(file => file.endsWith('.json'));
// Loop through each JSON file and extract icons
files.forEach(file => {
const jsonFilePath = path.join(jsonDirectory, file);
const searchData = JSON.parse(fs.readFileSync(jsonFilePath, 'utf8'));
// Check if the file contains the 'suggestions' and 'navigation' keys before processing
if (searchData.suggestions || searchData.navigation) {
// Combine suggestions and navigation from the current JSON file
const allGroups = [...Object.values(searchData.suggestions), ...Object.values(searchData.navigation)];
allGroups.forEach(group => {
group.forEach(item => {
if (item.icon) {
// Add icon to the list
iconClasses.push(`${item.icon}`);
}
});
});
}
});
} catch (error) {
console.warn('⚠️ Could not load JSON files. Running without dynamic safelist for icons.', error);
}
return src(`${buildPath}/**/*.css`)
.pipe(
purgecss({
content: [`${buildPath}/*.html`, `${buildPath}/**/*.js`],
defaultExtractor: content => {
const classPattern = /classList\.add\(['"`]([\w- ]+)['"`]\)/g;
const attrPattern = /setAttribute\(['"`](data-[\w-]+|aria-[\w-]+)['"`]/g;
let dynamicClasses = new Set();
let dynamicAttributes = new Set();
let match;
// Extract dynamically added classes
while ((match = classPattern.exec(content)) !== null) {
match[1].split(' ').forEach(cls => dynamicClasses.add(cls.trim()));
}
// Extract dynamically added attributes
while ((match = attrPattern.exec(content)) !== null) {
dynamicAttributes.add(match[1]);
}
// Extract static classes from the content
const staticClasses = content.match(/[\w-/:]+(?<!:)/g) || [];
return [...staticClasses, ...dynamicClasses];
},
safelist: {
standard: [
/^(is-|has-)/ // Keep utility classes
],
greedy: [
/^ps__rail/,
/^fc/,
/^aa/,
/^select2/,
/^swiper-pagination/,
/^swal2/,
/^plyr/,
/^noUi/,
...iconClasses.map(icon => new RegExp(`^${icon}$`)) // Dynamically added icon classes
],
deep: [/^data-bs/]
}
})
)
.pipe(dest(`${buildPath}`)); // Destination is the assets folder to overwrite in-place
};
const prodAllTask = series(
prodCopyHTMLTask,
prodCopyAssetsTask,
prodRenameTasks,
prodMinifyJSTasks,
prodPurgecssTasks,
prodUseRefTasks
);
// Exports
// ---------------------------------------------------------------------------
return {
copy: prodCopyHTMLTask,
copyAssests: prodCopyAssetsTask,
rename: prodRenameTasks,
useref: prodUseRefTasks,
minifyJS: prodMinifyJSTasks,
purgecss: prodPurgecssTasks,
all: prodAllTask
};
};