Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/technical-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ MeetWise is a client-side single-page application (SPA) built with React (using
- Use sub-components (`MeetingCard`, `MeetingRater`, `StatsPanel`, charting components) for modularity.
- Trigger actions in the `settingsStore` based on user interactions (e.g., rating a meeting, changing status flags, adding comments).

### 5.9 Favicon System

- SVG-based favicons with automatic PNG generation for cross-browser compatibility
- Uses a script (`scripts/generate-favicons.js`) to convert the primary SVG to various required sizes
- Automatically generates favicons during the build process via `npm run prebuild`
- Deployed with proper headers and manifest for PWA and browser compatibility
- Includes sizes: 16x16, 32x32, 180x180 (Apple Touch), 192x192 and 512x512 (Android Chrome)

## 6. Data Flow

1. **Initialization:** `App.tsx` -> `googleCalendarService.initializeGoogleApi` -> `settingsStore.initializeStore` -> `db.ts` (loads all encrypted data) -> `encryption.ts.decrypt` -> State hydrated in Zustand.
Expand Down
9 changes: 7 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<meta name="theme-color" content="#4F46E5" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>📅 MeetWise | Tame your meetings</title>
<!-- Google tag (gtag.js) -->
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
"type": "module",
"scripts": {
"dev": "vite",
"prebuild": "npm run generate-favicons",
"build": "tsc -b && vite build",
"lint": "eslint . --max-warnings 999",
"preview": "vite preview",
"prepare": "husky install",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "npm run lint && npm run gitleaks",
"gitleaks": "gitleaks protect --verbose --redact --staged",
"generate-mock-data": "tsx scripts/generateMockData.ts"
"generate-mock-data": "tsx scripts/generateMockData.ts",
"generate-favicons": "node scripts/generate-favicons.js"
},
"dependencies": {
"@hello-pangea/dnd": "^16.6.0",
Expand Down
Binary file added public/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions public/site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "MeetWise",
"short_name": "MeetWise",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#4F46E5",
"background_color": "#ffffff",
"display": "standalone"
}
52 changes: 52 additions & 0 deletions scripts/generate-favicons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env node

import { execFileSync } from "child_process";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

// Get the directory name in ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Ensure the public directory exists
const publicDir = path.join(__dirname, "../public");
if (!fs.existsSync(publicDir)) {
fs.mkdirSync(publicDir, { recursive: true });
}

// Path to SVG favicon
const svgPath = path.join(publicDir, "favicon.svg");

// Define sizes for different favicon formats
const sizes = [
{ name: "favicon-16x16.png", size: 16 },
{ name: "favicon-32x32.png", size: 32 },
{ name: "apple-touch-icon.png", size: 180 },
{ name: "android-chrome-192x192.png", size: 192 },
{ name: "android-chrome-512x512.png", size: 512 },
];

// Check if SVG file exists
if (!fs.existsSync(svgPath)) {
console.error("Error: favicon.svg does not exist in the public directory!");
process.exit(1);
}

console.log("Generating favicon files from SVG...");

// Generate PNG files for each size
sizes.forEach(({ name, size }) => {
const outputPath = path.join(publicDir, name);

try {
console.log(`Generating ${name}...`);
// Use execFileSync instead of execSync to prevent command injection
execFileSync("svgexport", [svgPath, outputPath, `${size}:${size}`]);
console.log(`Generated ${name}`);
} catch (error) {
console.error(`Error generating ${name}:`, error.message);
}
});

console.log("Favicon generation complete!");