...
This commit is contained in:
parent
8d9018722e
commit
cf28f78529
160
react-shadcn-starter/src/lib/circle-data.ts
Normal file
160
react-shadcn-starter/src/lib/circle-data.ts
Normal file
@ -0,0 +1,160 @@
|
||||
import md5 from 'md5';
|
||||
|
||||
export type WebDAVConfig = {
|
||||
url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export type Role = 'admin' | 'stakeholder' | 'member' | 'coordinator' | 'viewer' | 'contributor';
|
||||
|
||||
export type Member = {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
role: Role;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const defaultMembers: Member[] = [
|
||||
{
|
||||
id: "1",
|
||||
name: "John Smith",
|
||||
email: "john.smith@example.com",
|
||||
role: "admin",
|
||||
description: "Project lead and main administrator"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Sarah Johnson",
|
||||
email: "sarah.j@example.com",
|
||||
role: "coordinator",
|
||||
description: "Team coordinator and event organizer"
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Mike Wilson",
|
||||
email: "mike.w@example.com",
|
||||
role: "stakeholder",
|
||||
description: "Key stakeholder representing finance department"
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "Lisa Chen",
|
||||
email: "lisa.chen@example.com",
|
||||
role: "contributor",
|
||||
description: "Technical contributor and documentation specialist"
|
||||
}
|
||||
];
|
||||
|
||||
export class CircleDataManager {
|
||||
private static instance: CircleDataManager;
|
||||
private currentHash: string | null = null;
|
||||
private webdavConfig: WebDAVConfig | null = null;
|
||||
private circleFile: string | null = null;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
static getInstance(): CircleDataManager {
|
||||
if (!CircleDataManager.instance) {
|
||||
CircleDataManager.instance = new CircleDataManager();
|
||||
}
|
||||
return CircleDataManager.instance;
|
||||
}
|
||||
|
||||
setConfig(config: WebDAVConfig, circleFile: string) {
|
||||
this.webdavConfig = config;
|
||||
this.circleFile = circleFile;
|
||||
}
|
||||
|
||||
private calculateHash(members: Member[]): string {
|
||||
// Sort members by ID to ensure consistent hash
|
||||
const sortedMembers = [...members].sort((a, b) => a.id.localeCompare(b.id));
|
||||
return md5(JSON.stringify(sortedMembers));
|
||||
}
|
||||
|
||||
hasChanged(members: Member[]): boolean {
|
||||
const newHash = this.calculateHash(members);
|
||||
if (newHash === this.currentHash) {
|
||||
return false;
|
||||
}
|
||||
this.currentHash = newHash;
|
||||
return true;
|
||||
}
|
||||
|
||||
async fetchMembers(): Promise<Member[]> {
|
||||
if (!this.webdavConfig || !this.circleFile) {
|
||||
throw new Error('WebDAV configuration or circle file not set');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.webdavConfig.url}${this.circleFile}`, {
|
||||
headers: {
|
||||
'Authorization': 'Basic ' + btoa(`${this.webdavConfig.username}:${this.webdavConfig.password}`)
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status === 404) {
|
||||
// If file doesn't exist, save and return default members
|
||||
await this.saveMembers(defaultMembers);
|
||||
return defaultMembers;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch circle data: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data.members;
|
||||
} catch (error) {
|
||||
// If there's any error (including 404), save and return default members
|
||||
await this.saveMembers(defaultMembers);
|
||||
return defaultMembers;
|
||||
}
|
||||
}
|
||||
|
||||
async saveMembers(members: Member[]): Promise<void> {
|
||||
if (!this.webdavConfig || !this.circleFile) {
|
||||
throw new Error('WebDAV configuration or circle file not set');
|
||||
}
|
||||
|
||||
const response = await fetch(`${this.webdavConfig.url}${this.circleFile}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Basic ' + btoa(`${this.webdavConfig.username}:${this.webdavConfig.password}`)
|
||||
},
|
||||
body: JSON.stringify({ members }, null, 2)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to save circle data');
|
||||
}
|
||||
|
||||
this.currentHash = this.calculateHash(members);
|
||||
}
|
||||
|
||||
addMember(members: Member[], newMember: Omit<Member, 'id'>): Member[] {
|
||||
const id = crypto.randomUUID();
|
||||
const member: Member = { ...newMember, id };
|
||||
return [...members, member];
|
||||
}
|
||||
|
||||
updateMember(members: Member[], id: string, updates: Partial<Omit<Member, 'id'>>): Member[] {
|
||||
return members.map(member =>
|
||||
member.id === id ? { ...member, ...updates } : member
|
||||
);
|
||||
}
|
||||
|
||||
removeMember(members: Member[], id: string): Member[] {
|
||||
return members.filter(member => member.id !== id);
|
||||
}
|
||||
|
||||
getMemberById(members: Member[], id: string): Member | undefined {
|
||||
return members.find(member => member.id === id);
|
||||
}
|
||||
|
||||
getMembersByRole(members: Member[], role: Role): Member[] {
|
||||
return members.filter(member => member.role === role);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user