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
492 changes: 492 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"prepare": "husky install",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "npm run lint && npm run gitleaks",
"gitleaks": "gitleaks protect --verbose --redact --staged"
"gitleaks": "gitleaks protect --verbose --redact --staged",
"generate-mock-data": "tsx scripts/generateMockData.ts"
},
"dependencies": {
"@hello-pangea/dnd": "^16.6.0",
Expand Down Expand Up @@ -87,6 +88,7 @@
"husky": "^9.1.7",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"tsx": "^4.19.2",
"typescript": "^5.5.3",
"typescript-eslint": "^8.7.0",
"vite": "^5.4.8"
Expand Down
131 changes: 131 additions & 0 deletions scripts/generateMockData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import fs from "fs";
import path from "path";
import type { Meeting } from "../src/types";
import { fileURLToPath } from "url";
import { dirname } from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Helper function to create dates relative to today
const getRelativeDate = (
daysFromNow: number,
hours: number,
minutes: number = 0
) => {
const date = new Date();
date.setHours(0, 0, 0, 0);
date.setDate(date.getDate() + daysFromNow);
date.setHours(hours, minutes, 0, 0);
return date.toISOString();
};

// Helper to generate a random meeting
const generateMeeting = (id: number, daysFromNow: number) => {
const startHour = 9 + Math.floor(Math.random() * 7);
const duration = [0.5, 1, 1.5, 2][Math.floor(Math.random() * 4)];
const participantCount = Math.floor(Math.random() * 15) + 2;

const meetingTypes = [
{
title: "Team Sync",
desc: "Regular team sync to discuss progress and blockers",
},
{
title: "Project Review",
desc: "Review of ongoing project milestones and deliverables",
},
{
title: "Planning Session",
desc: "Strategic planning and roadmap discussion",
},
{
title: "Client Meeting",
desc: "Meeting with client stakeholders to discuss requirements",
},
{
title: "Design Review",
desc: "Review of design proposals and feedback session",
},
];

const randomType =
meetingTypes[Math.floor(Math.random() * meetingTypes.length)];
const hasPreRead = Math.random() > 0.6;

return {
id: id.toString(),
title: `${randomType.title} ${id}`,
startTime: getRelativeDate(daysFromNow, startHour),
endTime: getRelativeDate(daysFromNow, startHour + duration),
duration,
rank: id,
location: Math.random() > 0.5 ? "Virtual - Zoom" : "Conference Room A",
description: hasPreRead
? `${randomType.desc}\n\nPre-read: https://docs.example.com/doc${id}`
: randomType.desc,
participants: Array(participantCount)
.fill(null)
.map((_, i) => `Team Member ${i + 1}`),
isImportant: Math.random() > 0.7,
needsPrep: Math.random() > 0.5,
dayOfWeek: new Date(
getRelativeDate(daysFromNow, startHour)
).toLocaleDateString("en-US", { weekday: "long" }),
comments:
Math.random() > 0.7
? [
{
id: `c${id}`,
text: "Please review materials before the meeting",
author: "Team Lead",
timestamp: new Date().toISOString(),
},
]
: [],
icon: "calendar",
preworkIcon: "file-text",
showActions: true,
comment: "",
rating: 0,
};
};

// Generate meetings for past 90 days and future 10 days
const generateMeetings = () => {
const meetings: Meeting[] = [];
let id = 1;

for (let day = -90; day <= 10; day++) {
const date = new Date();
date.setDate(date.getDate() + day);
if (date.getDay() !== 0 && date.getDay() !== 6) {
const meetingsPerDay = Math.floor(Math.random() * 4) + 2;
for (let m = 0; m < meetingsPerDay; m++) {
meetings.push(generateMeeting(id++, day));
}
}
}

return meetings.sort(
(a, b) => new Date(a.startTime).getTime() - new Date(b.startTime).getTime()
);
};

// Generate the mock data file content
const generateMockDataFile = () => {
const meetings = generateMeetings();
const fileContent = `
import type { Meeting } from "@/types";

export const mockMeetings: Meeting[] = ${JSON.stringify(meetings, null, 2)};
`;

const outputPath = path.join(__dirname, "../src/mockData.ts");
fs.writeFileSync(outputPath, fileContent);
console.log(
`Generated mock data with ${meetings.length} meetings at ${outputPath}`
);
};

generateMockDataFile();
15 changes: 10 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ function App() {
const [activeTab, setActiveTab] = useState<"review" | "rate" | "plan">(
"review"
);
const [storeInitialized, setStoreInitialized] = useState(false);

useEffect(() => {
googleCalendarService.initializeGoogleApi(
import.meta.env.VITE_GOOGLE_CLIENT_ID
);
initializeStore();
const init = async () => {
await googleCalendarService.initializeGoogleApi(
import.meta.env.VITE_GOOGLE_CLIENT_ID
);
await initializeStore();
setStoreInitialized(true);
};
init();
}, [initializeStore]);

if (isLoading) {
if (isLoading || !storeInitialized) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
Expand Down
45 changes: 22 additions & 23 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { importGoogleCalendar } from "@/services/calendarService";
import { db } from "@/services/db";
import { ExportInstructions } from "./ExportInstructions";
import { EmailDialog } from "./EmailDialog";
// import { mockMeetings } from "@/mockData";
import { mockMeetings } from "@/mockData";

interface HeaderProps {
meetings: Meeting[];
Expand All @@ -27,9 +27,9 @@ export function Header({
meetings,
setMeetings,
clearAllData,
}: // useMockData,
// setUseMockData,
HeaderProps) {
useMockData,
setUseMockData,
}: HeaderProps) {
const [isImporting, setIsImporting] = useState(false);
const [isClearing, setIsClearing] = useState(false);
const [emailDialogOpen, setEmailDialogOpen] = useState(false);
Expand Down Expand Up @@ -67,25 +67,25 @@ HeaderProps) {
}
};

// const handleMockData = () => {
// setMeetings(mockMeetings);
// setUseMockData(true);
// };
const handleMockData = () => {
setMeetings(mockMeetings);
setUseMockData(true);
};

return (
<div className="flex items-center justify-between mb-6">
<h1 className="text-2xl font-bold">MeetWise</h1>
<div className="flex items-center gap-2">
<h1 className="text-2xl font-bold">MeetWise</h1>
<ExportInstructions />
</div>
<div className="flex gap-2">
<div className="flex items-center">
<Button
variant="outline"
onClick={() => document.getElementById("file-upload")?.click()}
>
<UploadIcon className="w-4 h-4 mr-2" />
Import
</Button>
<ExportInstructions />
</div>
<Button
variant="outline"
onClick={() => document.getElementById("file-upload")?.click()}
>
<UploadIcon className="w-4 h-4 mr-2" />
Import
</Button>
<Input
id="file-upload"
type="file"
Expand All @@ -105,15 +105,14 @@ HeaderProps) {
>
{isClearing ? "Clearing..." : "Clear Data"}
</Button>

{/* Removing mock data from the UI for now */}
{/* <Button
<Button
variant="outline"
onClick={handleMockData}
disabled={useMockData}
>
<CalendarIcon className="w-4 h-4 mr-2" />
Use Mock Data
</Button> */}
</Button>
<Button
variant="outline"
disabled={isImporting}
Expand Down
Loading
Loading