From 308d2de36556b231ad67bbd97fda860d6d7a02da Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Mon, 28 Jul 2025 09:07:36 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=B9=20Major=20Codebase=20Cleanup:=20Re?= =?UTF-8?q?move=20Legacy=20React=20Code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🗑️ Removed Unused Files (11 files): - 6 temporary import result JSON files - 3 placeholder pages (community.js, analytics.js, decks.js) - 3 unused components (CollaborationManager, ActivityLog, BulkInviteModal) - 2 TypeScript config files (tsconfig.json, next-env.d.ts) 📦 Cleaned Up Dependencies: - Removed 5 unused TypeScript packages - Kept resend for future invite/notification features - Removed 8 packages total, reduced bundle size ✨ Benefits: - Cleaner codebase with only active files - Reduced build time and bundle size - Eliminated TypeScript overhead (project uses only JS) - Removed legacy React patterns and unused components - Better maintainability and clarity The codebase is now lean and focused on active features --- ...port-results-2025-07-24T15-23-54-843Z.json | 1150 --------------- ...port-results-2025-07-24T17-20-21-039Z.json | 1301 ----------------- components/ActivityLog.js | 172 --- components/BulkInviteModal.js | 219 --- components/CollaborationManager.js | 355 ----- ...port-results-2025-07-24T17-27-46-410Z.json | 34 - ...port-results-2025-07-24T17-32-10-187Z.json | 25 - ...port-results-2025-07-24T17-34-04-839Z.json | 34 - next-env.d.ts | 5 - package-lock.json | 82 +- package.json | 8 +- pages/analytics.js | 27 - pages/community.js | 27 - pages/decks.js | 27 - ...port-results-2025-07-23T19-35-56-994Z.json | 1283 ---------------- tsconfig.json | 41 - 16 files changed, 2 insertions(+), 4788 deletions(-) delete mode 100644 bulk-import-results-2025-07-24T15-23-54-843Z.json delete mode 100644 bulk-import-results-2025-07-24T17-20-21-039Z.json delete mode 100644 components/ActivityLog.js delete mode 100644 components/BulkInviteModal.js delete mode 100644 components/CollaborationManager.js delete mode 100644 lorcana-import-results-2025-07-24T17-27-46-410Z.json delete mode 100644 lorcana-import-results-2025-07-24T17-32-10-187Z.json delete mode 100644 lorcana-import-results-2025-07-24T17-34-04-839Z.json delete mode 100644 next-env.d.ts delete mode 100644 pages/analytics.js delete mode 100644 pages/community.js delete mode 100644 pages/decks.js delete mode 100644 popular-sets-import-results-2025-07-23T19-35-56-994Z.json delete mode 100644 tsconfig.json diff --git a/bulk-import-results-2025-07-24T15-23-54-843Z.json b/bulk-import-results-2025-07-24T15-23-54-843Z.json deleted file mode 100644 index cc23436..0000000 --- a/bulk-import-results-2025-07-24T15-23-54-843Z.json +++ /dev/null @@ -1,1150 +0,0 @@ -{ - "mtg": { - "total": 103, - "successful": 102, - "failed": 1, - "sets": [ - { - "code": "neo", - "name": "Kamigawa: Neon Dynasty", - "success": true - }, - { - "code": "vow", - "name": "Innistrad: Crimson Vow", - "success": true - }, - { - "code": "mid", - "name": "Innistrad: Midnight Hunt", - "success": true - }, - { - "code": "afr", - "name": "Adventures in the Forgotten Realms", - "success": true - }, - { - "code": "stx", - "name": "Strixhaven: School of Mages", - "success": true - }, - { - "code": "khm", - "name": "Kaldheim", - "success": true - }, - { - "code": "znr", - "name": "Zendikar Rising", - "success": true - }, - { - "code": "iko", - "name": "Ikoria: Lair of Behemoths", - "success": true - }, - { - "code": "thb", - "name": "Theros Beyond Death", - "success": true - }, - { - "code": "eld", - "name": "Throne of Eldraine", - "success": true - }, - { - "code": "m20", - "name": "Core Set 2020", - "success": true - }, - { - "code": "war", - "name": "War of the Spark", - "success": true - }, - { - "code": "rna", - "name": "Ravnica Allegiance", - "success": true - }, - { - "code": "grn", - "name": "Guilds of Ravnica", - "success": true - }, - { - "code": "m19", - "name": "Core Set 2019", - "success": true - }, - { - "code": "dom", - "name": "Dominaria", - "success": true - }, - { - "code": "rix", - "name": "Rivals of Ixalan", - "success": true - }, - { - "code": "xln", - "name": "Ixalan", - "success": true - }, - { - "code": "hou", - "name": "Hour of Devastation", - "success": true - }, - { - "code": "akh", - "name": "Amonkhet", - "success": true - }, - { - "code": "aer", - "name": "Aether Revolt", - "success": true - }, - { - "code": "kld", - "name": "Kaladesh", - "success": true - }, - { - "code": "emn", - "name": "Eldritch Moon", - "success": true - }, - { - "code": "soi", - "name": "Shadows over Innistrad", - "success": true - }, - { - "code": "ogw", - "name": "Oath of the Gatewatch", - "success": true - }, - { - "code": "bfz", - "name": "Battle for Zendikar", - "success": true - }, - { - "code": "ori", - "name": "Magic Origins", - "success": true - }, - { - "code": "dtk", - "name": "Dragons of Tarkir", - "success": true - }, - { - "code": "frf", - "name": "Fate Reforged", - "success": true - }, - { - "code": "ktk", - "name": "Khans of Tarkir", - "success": true - }, - { - "code": "m15", - "name": "Magic 2015", - "success": true - }, - { - "code": "jou", - "name": "Journey into Nyx", - "success": true - }, - { - "code": "bng", - "name": "Born of the Gods", - "success": true - }, - { - "code": "ths", - "name": "Theros", - "success": true - }, - { - "code": "m14", - "name": "Magic 2014", - "success": true - }, - { - "code": "dgm", - "name": "Dragon's Maze", - "success": true - }, - { - "code": "gtc", - "name": "Gatecrash", - "success": true - }, - { - "code": "rtr", - "name": "Return to Ravnica", - "success": true - }, - { - "code": "m13", - "name": "Magic 2013", - "success": true - }, - { - "code": "avr", - "name": "Avacyn Restored", - "success": true - }, - { - "code": "dka", - "name": "Dark Ascension", - "success": true - }, - { - "code": "isd", - "name": "Innistrad", - "success": true - }, - { - "code": "m12", - "name": "Magic 2012", - "success": true - }, - { - "code": "nph", - "name": "New Phyrexia", - "success": true - }, - { - "code": "mbs", - "name": "Mirrodin Besieged", - "success": true - }, - { - "code": "som", - "name": "Scars of Mirrodin", - "success": true - }, - { - "code": "m11", - "name": "Magic 2011", - "success": true - }, - { - "code": "roe", - "name": "Rise of the Eldrazi", - "success": true - }, - { - "code": "wwk", - "name": "Worldwake", - "success": true - }, - { - "code": "zen", - "name": "Zendikar", - "success": true - }, - { - "code": "m10", - "name": "Magic 2010", - "success": true - }, - { - "code": "arb", - "name": "Alara Reborn", - "success": true - }, - { - "code": "con", - "name": "Conflux", - "success": true - }, - { - "code": "ala", - "name": "Shards of Alara", - "success": true - }, - { - "code": "eve", - "name": "Eventide", - "success": true - }, - { - "code": "shm", - "name": "Shadowmoor", - "success": true - }, - { - "code": "mor", - "name": "Morningtide", - "success": true - }, - { - "code": "lrw", - "name": "Lorwyn", - "success": true - }, - { - "code": "fut", - "name": "Future Sight", - "success": true - }, - { - "code": "plc", - "name": "Planar Chaos", - "success": true - }, - { - "code": "tsp", - "name": "Time Spiral", - "success": true - }, - { - "code": "csp", - "name": "Coldsnap", - "success": true - }, - { - "code": "dis", - "name": "Dissension", - "success": true - }, - { - "code": "gpt", - "name": "Guildpact", - "success": true - }, - { - "code": "rav", - "name": "Ravnica: City of Guilds", - "success": true - }, - { - "code": "9ed", - "name": "Ninth Edition", - "success": true - }, - { - "code": "sok", - "name": "Saviors of Kamigawa", - "success": true - }, - { - "code": "bet", - "name": "Betrayers of Kamigawa", - "success": false, - "error": "Import failed" - }, - { - "code": "chk", - "name": "Champions of Kamigawa", - "success": true - }, - { - "code": "5dn", - "name": "Fifth Dawn", - "success": true - }, - { - "code": "dst", - "name": "Darksteel", - "success": true - }, - { - "code": "mrd", - "name": "Mirrodin", - "success": true - }, - { - "code": "8ed", - "name": "Eighth Edition", - "success": true - }, - { - "code": "scg", - "name": "Scourge", - "success": true - }, - { - "code": "lgn", - "name": "Legions", - "success": true - }, - { - "code": "ons", - "name": "Onslaught", - "success": true - }, - { - "code": "7ed", - "name": "Seventh Edition", - "success": true - }, - { - "code": "apc", - "name": "Apocalypse", - "success": true - }, - { - "code": "pls", - "name": "Planeshift", - "success": true - }, - { - "code": "inv", - "name": "Invasion", - "success": true - }, - { - "code": "6ed", - "name": "Classic Sixth Edition", - "success": true - }, - { - "code": "pcy", - "name": "Prophecy", - "success": true - }, - { - "code": "nem", - "name": "Nemesis", - "success": true - }, - { - "code": "mmq", - "name": "Mercadian Masques", - "success": true - }, - { - "code": "uds", - "name": "Urza's Destiny", - "success": true - }, - { - "code": "ulg", - "name": "Urza's Legacy", - "success": true - }, - { - "code": "usg", - "name": "Urza's Saga", - "success": true - }, - { - "code": "5ed", - "name": "Fifth Edition", - "success": true - }, - { - "code": "exo", - "name": "Exodus", - "success": true - }, - { - "code": "sth", - "name": "Stronghold", - "success": true - }, - { - "code": "tmp", - "name": "Tempest", - "success": true - }, - { - "code": "4ed", - "name": "Fourth Edition", - "success": true - }, - { - "code": "vis", - "name": "Visions", - "success": true - }, - { - "code": "all", - "name": "Alliances", - "success": true - }, - { - "code": "ice", - "name": "Ice Age", - "success": true - }, - { - "code": "3ed", - "name": "Revised Edition", - "success": true - }, - { - "code": "fem", - "name": "Fallen Empires", - "success": true - }, - { - "code": "drk", - "name": "The Dark", - "success": true - }, - { - "code": "leg", - "name": "Legends", - "success": true - }, - { - "code": "atq", - "name": "Antiquities", - "success": true - }, - { - "code": "arn", - "name": "Arabian Nights", - "success": true - }, - { - "code": "leb", - "name": "Limited Edition Beta", - "success": true - }, - { - "code": "lea", - "name": "Limited Edition Alpha", - "success": true - } - ] - }, - "pokemon": { - "total": 107, - "successful": 49, - "failed": 58, - "sets": [ - { - "code": "base1", - "name": "Base Set", - "success": false, - "error": "Import failed" - }, - { - "code": "base2", - "name": "Base Set 2", - "success": true - }, - { - "code": "base3", - "name": "Base Set 3", - "success": true - }, - { - "code": "gym1", - "name": "Gym Heroes", - "success": false, - "error": "Import failed" - }, - { - "code": "gym2", - "name": "Gym Challenge", - "success": false, - "error": "Import failed" - }, - { - "code": "neo1", - "name": "Neo Genesis", - "success": false, - "error": "Import failed" - }, - { - "code": "neo2", - "name": "Neo Discovery", - "success": false, - "error": "Import failed" - }, - { - "code": "neo3", - "name": "Neo Revelation", - "success": false, - "error": "Import failed" - }, - { - "code": "neo4", - "name": "Neo Destiny", - "success": false, - "error": "Import failed" - }, - { - "code": "ecard1", - "name": "Expedition Base Set", - "success": false, - "error": "Import failed" - }, - { - "code": "ecard2", - "name": "Aquapolis", - "success": false, - "error": "Import failed" - }, - { - "code": "ecard3", - "name": "Skyridge", - "success": false, - "error": "Import failed" - }, - { - "code": "ex1", - "name": "Ruby & Sapphire", - "success": false, - "error": "Import failed" - }, - { - "code": "ex2", - "name": "Sandstorm", - "success": false, - "error": "Import failed" - }, - { - "code": "ex3", - "name": "Dragon", - "success": true - }, - { - "code": "ex4", - "name": "Team Magma vs Team Aqua", - "success": true - }, - { - "code": "ex5", - "name": "Hidden Legends", - "success": true - }, - { - "code": "ex6", - "name": "FireRed & LeafGreen", - "success": false, - "error": "Import failed" - }, - { - "code": "ex7", - "name": "Team Rocket Returns", - "success": true - }, - { - "code": "ex8", - "name": "Deoxys", - "success": true - }, - { - "code": "ex9", - "name": "Emerald", - "success": true - }, - { - "code": "ex10", - "name": "Unseen Forces", - "success": true - }, - { - "code": "ex11", - "name": "Delta Species", - "success": true - }, - { - "code": "ex12", - "name": "Legend Maker", - "success": true - }, - { - "code": "ex13", - "name": "Holon Phantoms", - "success": true - }, - { - "code": "ex14", - "name": "Crystal Guardians", - "success": true - }, - { - "code": "ex15", - "name": "Dragon Frontiers", - "success": false, - "error": "Import failed" - }, - { - "code": "ex16", - "name": "Power Keepers", - "success": true - }, - { - "code": "dpp1", - "name": "Diamond & Pearl", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp2", - "name": "Mysterious Treasures", - "success": true - }, - { - "code": "dpp3", - "name": "Secret Wonders", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp4", - "name": "Great Encounters", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp5", - "name": "Majestic Dawn", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp6", - "name": "Legends Awakened", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp7", - "name": "Stormfront", - "success": false, - "error": "Import failed" - }, - { - "code": "dpp8", - "name": "Platinum", - "success": true - }, - { - "code": "dpp9", - "name": "Rising Rivals", - "success": true - }, - { - "code": "dpp10", - "name": "Supreme Victors", - "success": true - }, - { - "code": "dpp11", - "name": "Arceus", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss1", - "name": "HeartGold & SoulSilver", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss2", - "name": "Unleashed", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss3", - "name": "Undaunted", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss4", - "name": "Triumphant", - "success": true - }, - { - "code": "col1", - "name": "Call of Legends", - "success": true - }, - { - "code": "bw1", - "name": "Black & White", - "success": true - }, - { - "code": "bw2", - "name": "Emerging Powers", - "success": false, - "error": "Import failed" - }, - { - "code": "bw3", - "name": "Noble Victories", - "success": true - }, - { - "code": "bw4", - "name": "Next Destinies", - "success": true - }, - { - "code": "bw5", - "name": "Dark Explorers", - "success": false, - "error": "Import failed" - }, - { - "code": "bw6", - "name": "Dragons Exalted", - "success": false, - "error": "Import failed" - }, - { - "code": "bw7", - "name": "Boundaries Crossed", - "success": false, - "error": "Import failed" - }, - { - "code": "bw8", - "name": "Plasma Storm", - "success": false, - "error": "Import failed" - }, - { - "code": "bw9", - "name": "Plasma Freeze", - "success": false, - "error": "Import failed" - }, - { - "code": "bw10", - "name": "Plasma Blast", - "success": false, - "error": "Import failed" - }, - { - "code": "bw11", - "name": "Legendary Treasures", - "success": true - }, - { - "code": "xy1", - "name": "XY", - "success": true - }, - { - "code": "xy2", - "name": "Flashfire", - "success": true - }, - { - "code": "xy3", - "name": "Furious Fists", - "success": true - }, - { - "code": "xy4", - "name": "Phantom Forces", - "success": true - }, - { - "code": "xy5", - "name": "Primal Clash", - "success": false, - "error": "Import failed" - }, - { - "code": "xy6", - "name": "Double Crisis", - "success": false, - "error": "Import failed" - }, - { - "code": "xy7", - "name": "Roaring Skies", - "success": true - }, - { - "code": "xy8", - "name": "Ancient Origins", - "success": false, - "error": "Import failed" - }, - { - "code": "xy9", - "name": "BREAKthrough", - "success": true - }, - { - "code": "xy10", - "name": "BREAKpoint", - "success": true - }, - { - "code": "xy11", - "name": "Fates Collide", - "success": true - }, - { - "code": "xy12", - "name": "Steam Siege", - "success": false, - "error": "Import failed" - }, - { - "code": "xy12", - "name": "Evolutions", - "success": true - }, - { - "code": "sm1", - "name": "Sun & Moon", - "success": false, - "error": "Import failed" - }, - { - "code": "sm2", - "name": "Guardians Rising", - "success": false, - "error": "Import failed" - }, - { - "code": "sm3", - "name": "Burning Shadows", - "success": true - }, - { - "code": "sm4", - "name": "Crimson Invasion", - "success": true - }, - { - "code": "sm5", - "name": "Ultra Prism", - "success": false, - "error": "Import failed" - }, - { - "code": "sm6", - "name": "Forbidden Light", - "success": false, - "error": "Import failed" - }, - { - "code": "sm7", - "name": "Celestial Storm", - "success": true - }, - { - "code": "sm8", - "name": "Dragon Majesty", - "success": true - }, - { - "code": "sm9", - "name": "Lost Thunder", - "success": true - }, - { - "code": "sm10", - "name": "Team Up", - "success": true - }, - { - "code": "sm11", - "name": "Detective Pikachu", - "success": false, - "error": "Import failed" - }, - { - "code": "sm12", - "name": "Unbroken Bonds", - "success": false, - "error": "Import failed" - }, - { - "code": "sm115", - "name": "Unified Minds", - "success": false, - "error": "Import failed" - }, - { - "code": "sm116", - "name": "Hidden Fates", - "success": false, - "error": "Import failed" - }, - { - "code": "sm117", - "name": "Cosmic Eclipse", - "success": true - }, - { - "code": "swsh1", - "name": "Sword & Shield", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh2", - "name": "Rebel Clash", - "success": true - }, - { - "code": "swsh3", - "name": "Darkness Ablaze", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh4", - "name": "Champions Path", - "success": true - }, - { - "code": "swsh5", - "name": "Vivid Voltage", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh6", - "name": "Shining Fates", - "success": true - }, - { - "code": "swsh7", - "name": "Battle Styles", - "success": true - }, - { - "code": "swsh8", - "name": "Chilling Reign", - "success": true - }, - { - "code": "swsh9", - "name": "Evolving Skies", - "success": true - }, - { - "code": "swsh10", - "name": "Celebrations", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh11", - "name": "Fusion Strike", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh12", - "name": "Brilliant Stars", - "success": true - }, - { - "code": "swsh12", - "name": "Astral Radiance", - "success": true - }, - { - "code": "swsh12", - "name": "Pokemon GO", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh12", - "name": "Lost Origin", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh12", - "name": "Silver Tempest", - "success": false, - "error": "Import failed" - }, - { - "code": "swsh12", - "name": "Crown Zenith", - "success": false, - "error": "Import failed" - }, - { - "code": "sv1", - "name": "Scarlet & Violet", - "success": false, - "error": "Import failed" - }, - { - "code": "sv2", - "name": "Paldea Evolved", - "success": false, - "error": "Import failed" - }, - { - "code": "sv3", - "name": "Obsidian Flames", - "success": false, - "error": "Import failed" - }, - { - "code": "sv4", - "name": "151", - "success": false, - "error": "Import failed" - }, - { - "code": "sv5", - "name": "Paradox Rift", - "success": false, - "error": "Import failed" - }, - { - "code": "sv6", - "name": "Paldean Fates", - "success": false, - "error": "Import failed" - }, - { - "code": "sv7", - "name": "Temporal Forces", - "success": true - } - ] - }, - "lorcana": { - "total": 3, - "successful": 0, - "failed": 3, - "sets": [ - { - "code": "tfc", - "name": "The First Chapter", - "success": false, - "error": "Method not allowed" - }, - { - "code": "rotf", - "name": "Rise of the Floodborn", - "success": false, - "error": "Method not allowed" - }, - { - "code": "ink", - "name": "Into the Inklands", - "success": false, - "error": "Method not allowed" - } - ] - } -} \ No newline at end of file diff --git a/bulk-import-results-2025-07-24T17-20-21-039Z.json b/bulk-import-results-2025-07-24T17-20-21-039Z.json deleted file mode 100644 index 05e0924..0000000 --- a/bulk-import-results-2025-07-24T17-20-21-039Z.json +++ /dev/null @@ -1,1301 +0,0 @@ -{ - "mtg": { - "total": 103, - "successful": 101, - "failed": 2, - "sets": [ - { - "code": "neo", - "name": "Kamigawa: Neon Dynasty", - "success": true, - "importedCount": 0 - }, - { - "code": "vow", - "name": "Innistrad: Crimson Vow", - "success": true, - "importedCount": 0 - }, - { - "code": "mid", - "name": "Innistrad: Midnight Hunt", - "success": false, - "error": "Import failed" - }, - { - "code": "afr", - "name": "Adventures in the Forgotten Realms", - "success": true, - "importedCount": 0 - }, - { - "code": "stx", - "name": "Strixhaven: School of Mages", - "success": true, - "importedCount": 0 - }, - { - "code": "khm", - "name": "Kaldheim", - "success": true, - "importedCount": 0 - }, - { - "code": "znr", - "name": "Zendikar Rising", - "success": true, - "importedCount": 0 - }, - { - "code": "iko", - "name": "Ikoria: Lair of Behemoths", - "success": true, - "importedCount": 0 - }, - { - "code": "thb", - "name": "Theros Beyond Death", - "success": true, - "importedCount": 0 - }, - { - "code": "eld", - "name": "Throne of Eldraine", - "success": true, - "importedCount": 0 - }, - { - "code": "m20", - "name": "Core Set 2020", - "success": true, - "importedCount": 0 - }, - { - "code": "war", - "name": "War of the Spark", - "success": true, - "importedCount": 0 - }, - { - "code": "rna", - "name": "Ravnica Allegiance", - "success": true, - "importedCount": 0 - }, - { - "code": "grn", - "name": "Guilds of Ravnica", - "success": true, - "importedCount": 0 - }, - { - "code": "m19", - "name": "Core Set 2019", - "success": true, - "importedCount": 0 - }, - { - "code": "dom", - "name": "Dominaria", - "success": true, - "importedCount": 0 - }, - { - "code": "rix", - "name": "Rivals of Ixalan", - "success": true, - "importedCount": 0 - }, - { - "code": "xln", - "name": "Ixalan", - "success": true, - "importedCount": 0 - }, - { - "code": "hou", - "name": "Hour of Devastation", - "success": true, - "importedCount": 0 - }, - { - "code": "akh", - "name": "Amonkhet", - "success": true, - "importedCount": 0 - }, - { - "code": "aer", - "name": "Aether Revolt", - "success": true, - "importedCount": 0 - }, - { - "code": "kld", - "name": "Kaladesh", - "success": true, - "importedCount": 0 - }, - { - "code": "emn", - "name": "Eldritch Moon", - "success": true, - "importedCount": 0 - }, - { - "code": "soi", - "name": "Shadows over Innistrad", - "success": true, - "importedCount": 0 - }, - { - "code": "ogw", - "name": "Oath of the Gatewatch", - "success": true, - "importedCount": 0 - }, - { - "code": "bfz", - "name": "Battle for Zendikar", - "success": true, - "importedCount": 0 - }, - { - "code": "ori", - "name": "Magic Origins", - "success": true, - "importedCount": 0 - }, - { - "code": "dtk", - "name": "Dragons of Tarkir", - "success": true, - "importedCount": 0 - }, - { - "code": "frf", - "name": "Fate Reforged", - "success": true, - "importedCount": 0 - }, - { - "code": "ktk", - "name": "Khans of Tarkir", - "success": true, - "importedCount": 0 - }, - { - "code": "m15", - "name": "Magic 2015", - "success": true, - "importedCount": 0 - }, - { - "code": "jou", - "name": "Journey into Nyx", - "success": true, - "importedCount": 0 - }, - { - "code": "bng", - "name": "Born of the Gods", - "success": true, - "importedCount": 0 - }, - { - "code": "ths", - "name": "Theros", - "success": true, - "importedCount": 0 - }, - { - "code": "m14", - "name": "Magic 2014", - "success": true, - "importedCount": 0 - }, - { - "code": "dgm", - "name": "Dragon's Maze", - "success": true, - "importedCount": 0 - }, - { - "code": "gtc", - "name": "Gatecrash", - "success": true, - "importedCount": 0 - }, - { - "code": "rtr", - "name": "Return to Ravnica", - "success": true, - "importedCount": 0 - }, - { - "code": "m13", - "name": "Magic 2013", - "success": true, - "importedCount": 0 - }, - { - "code": "avr", - "name": "Avacyn Restored", - "success": true, - "importedCount": 0 - }, - { - "code": "dka", - "name": "Dark Ascension", - "success": true, - "importedCount": 0 - }, - { - "code": "isd", - "name": "Innistrad", - "success": true, - "importedCount": 0 - }, - { - "code": "m12", - "name": "Magic 2012", - "success": true, - "importedCount": 0 - }, - { - "code": "nph", - "name": "New Phyrexia", - "success": true, - "importedCount": 0 - }, - { - "code": "mbs", - "name": "Mirrodin Besieged", - "success": true, - "importedCount": 0 - }, - { - "code": "som", - "name": "Scars of Mirrodin", - "success": true, - "importedCount": 0 - }, - { - "code": "m11", - "name": "Magic 2011", - "success": true, - "importedCount": 0 - }, - { - "code": "roe", - "name": "Rise of the Eldrazi", - "success": true, - "importedCount": 0 - }, - { - "code": "wwk", - "name": "Worldwake", - "success": true, - "importedCount": 0 - }, - { - "code": "zen", - "name": "Zendikar", - "success": true, - "importedCount": 0 - }, - { - "code": "m10", - "name": "Magic 2010", - "success": true, - "importedCount": 0 - }, - { - "code": "arb", - "name": "Alara Reborn", - "success": true, - "importedCount": 0 - }, - { - "code": "con", - "name": "Conflux", - "success": true, - "importedCount": 0 - }, - { - "code": "ala", - "name": "Shards of Alara", - "success": true, - "importedCount": 0 - }, - { - "code": "eve", - "name": "Eventide", - "success": true, - "importedCount": 0 - }, - { - "code": "shm", - "name": "Shadowmoor", - "success": true, - "importedCount": 0 - }, - { - "code": "mor", - "name": "Morningtide", - "success": true, - "importedCount": 0 - }, - { - "code": "lrw", - "name": "Lorwyn", - "success": true, - "importedCount": 0 - }, - { - "code": "fut", - "name": "Future Sight", - "success": true, - "importedCount": 0 - }, - { - "code": "plc", - "name": "Planar Chaos", - "success": true, - "importedCount": 0 - }, - { - "code": "tsp", - "name": "Time Spiral", - "success": true, - "importedCount": 0 - }, - { - "code": "csp", - "name": "Coldsnap", - "success": true, - "importedCount": 0 - }, - { - "code": "dis", - "name": "Dissension", - "success": true, - "importedCount": 0 - }, - { - "code": "gpt", - "name": "Guildpact", - "success": true, - "importedCount": 0 - }, - { - "code": "rav", - "name": "Ravnica: City of Guilds", - "success": true, - "importedCount": 0 - }, - { - "code": "9ed", - "name": "Ninth Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "sok", - "name": "Saviors of Kamigawa", - "success": true, - "importedCount": 0 - }, - { - "code": "bet", - "name": "Betrayers of Kamigawa", - "success": false, - "error": "Import failed" - }, - { - "code": "chk", - "name": "Champions of Kamigawa", - "success": true, - "importedCount": 0 - }, - { - "code": "5dn", - "name": "Fifth Dawn", - "success": true, - "importedCount": 0 - }, - { - "code": "dst", - "name": "Darksteel", - "success": true, - "importedCount": 0 - }, - { - "code": "mrd", - "name": "Mirrodin", - "success": true, - "importedCount": 0 - }, - { - "code": "8ed", - "name": "Eighth Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "scg", - "name": "Scourge", - "success": true, - "importedCount": 0 - }, - { - "code": "lgn", - "name": "Legions", - "success": true, - "importedCount": 0 - }, - { - "code": "ons", - "name": "Onslaught", - "success": true, - "importedCount": 0 - }, - { - "code": "7ed", - "name": "Seventh Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "apc", - "name": "Apocalypse", - "success": true, - "importedCount": 0 - }, - { - "code": "pls", - "name": "Planeshift", - "success": true, - "importedCount": 0 - }, - { - "code": "inv", - "name": "Invasion", - "success": true, - "importedCount": 0 - }, - { - "code": "6ed", - "name": "Classic Sixth Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "pcy", - "name": "Prophecy", - "success": true, - "importedCount": 0 - }, - { - "code": "nem", - "name": "Nemesis", - "success": true, - "importedCount": 0 - }, - { - "code": "mmq", - "name": "Mercadian Masques", - "success": true, - "importedCount": 0 - }, - { - "code": "uds", - "name": "Urza's Destiny", - "success": true, - "importedCount": 0 - }, - { - "code": "ulg", - "name": "Urza's Legacy", - "success": true, - "importedCount": 0 - }, - { - "code": "usg", - "name": "Urza's Saga", - "success": true, - "importedCount": 0 - }, - { - "code": "5ed", - "name": "Fifth Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "exo", - "name": "Exodus", - "success": true, - "importedCount": 0 - }, - { - "code": "sth", - "name": "Stronghold", - "success": true, - "importedCount": 0 - }, - { - "code": "tmp", - "name": "Tempest", - "success": true, - "importedCount": 0 - }, - { - "code": "4ed", - "name": "Fourth Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "vis", - "name": "Visions", - "success": true, - "importedCount": 0 - }, - { - "code": "all", - "name": "Alliances", - "success": true, - "importedCount": 0 - }, - { - "code": "ice", - "name": "Ice Age", - "success": true, - "importedCount": 0 - }, - { - "code": "3ed", - "name": "Revised Edition", - "success": true, - "importedCount": 0 - }, - { - "code": "fem", - "name": "Fallen Empires", - "success": true, - "importedCount": 0 - }, - { - "code": "drk", - "name": "The Dark", - "success": true, - "importedCount": 0 - }, - { - "code": "leg", - "name": "Legends", - "success": true, - "importedCount": 0 - }, - { - "code": "atq", - "name": "Antiquities", - "success": true, - "importedCount": 0 - }, - { - "code": "arn", - "name": "Arabian Nights", - "success": true, - "importedCount": 0 - }, - { - "code": "leb", - "name": "Limited Edition Beta", - "success": true, - "importedCount": 0 - }, - { - "code": "lea", - "name": "Limited Edition Alpha", - "success": true, - "importedCount": 0 - } - ] - }, - "pokemon": { - "total": 107, - "successful": 94, - "failed": 13, - "sets": [ - { - "code": "base1", - "name": "Base Set", - "success": true, - "importedCount": 102 - }, - { - "code": "base2", - "name": "Base Set 2", - "success": false, - "error": "Import failed" - }, - { - "code": "base3", - "name": "Base Set 3", - "success": true, - "importedCount": 0 - }, - { - "code": "gym1", - "name": "Gym Heroes", - "success": false, - "error": "Import failed" - }, - { - "code": "gym2", - "name": "Gym Challenge", - "success": true, - "importedCount": 132 - }, - { - "code": "neo1", - "name": "Neo Genesis", - "success": true, - "importedCount": 111 - }, - { - "code": "neo2", - "name": "Neo Discovery", - "success": true, - "importedCount": 75 - }, - { - "code": "neo3", - "name": "Neo Revelation", - "success": true, - "importedCount": 66 - }, - { - "code": "neo4", - "name": "Neo Destiny", - "success": true, - "importedCount": 113 - }, - { - "code": "ecard1", - "name": "Expedition Base Set", - "success": true, - "importedCount": 165 - }, - { - "code": "ecard2", - "name": "Aquapolis", - "success": true, - "importedCount": 182 - }, - { - "code": "ecard3", - "name": "Skyridge", - "success": true, - "importedCount": 182 - }, - { - "code": "ex1", - "name": "Ruby & Sapphire", - "success": true, - "importedCount": 109 - }, - { - "code": "ex2", - "name": "Sandstorm", - "success": true, - "importedCount": 100 - }, - { - "code": "ex3", - "name": "Dragon", - "success": true, - "importedCount": 0 - }, - { - "code": "ex4", - "name": "Team Magma vs Team Aqua", - "success": true, - "importedCount": 0 - }, - { - "code": "ex5", - "name": "Hidden Legends", - "success": true, - "importedCount": 0 - }, - { - "code": "ex6", - "name": "FireRed & LeafGreen", - "success": true, - "importedCount": 116 - }, - { - "code": "ex7", - "name": "Team Rocket Returns", - "success": true, - "importedCount": 0 - }, - { - "code": "ex8", - "name": "Deoxys", - "success": true, - "importedCount": 0 - }, - { - "code": "ex9", - "name": "Emerald", - "success": true, - "importedCount": 0 - }, - { - "code": "ex10", - "name": "Unseen Forces", - "success": true, - "importedCount": 0 - }, - { - "code": "ex11", - "name": "Delta Species", - "success": true, - "importedCount": 0 - }, - { - "code": "ex12", - "name": "Legend Maker", - "success": true, - "importedCount": 0 - }, - { - "code": "ex13", - "name": "Holon Phantoms", - "success": true, - "importedCount": 0 - }, - { - "code": "ex14", - "name": "Crystal Guardians", - "success": true, - "importedCount": 0 - }, - { - "code": "ex15", - "name": "Dragon Frontiers", - "success": true, - "importedCount": 101 - }, - { - "code": "ex16", - "name": "Power Keepers", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp1", - "name": "Diamond & Pearl", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp2", - "name": "Mysterious Treasures", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp3", - "name": "Secret Wonders", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp4", - "name": "Great Encounters", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp5", - "name": "Majestic Dawn", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp6", - "name": "Legends Awakened", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp7", - "name": "Stormfront", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp8", - "name": "Platinum", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp9", - "name": "Rising Rivals", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp10", - "name": "Supreme Victors", - "success": true, - "importedCount": 0 - }, - { - "code": "dpp11", - "name": "Arceus", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss1", - "name": "HeartGold & SoulSilver", - "success": false, - "error": "Import failed" - }, - { - "code": "hgss2", - "name": "Unleashed", - "success": true, - "importedCount": 96 - }, - { - "code": "hgss3", - "name": "Undaunted", - "success": true, - "importedCount": 91 - }, - { - "code": "hgss4", - "name": "Triumphant", - "success": true, - "importedCount": 0 - }, - { - "code": "col1", - "name": "Call of Legends", - "success": true, - "importedCount": 0 - }, - { - "code": "bw1", - "name": "Black & White", - "success": true, - "importedCount": 0 - }, - { - "code": "bw2", - "name": "Emerging Powers", - "success": true, - "importedCount": 98 - }, - { - "code": "bw3", - "name": "Noble Victories", - "success": true, - "importedCount": 0 - }, - { - "code": "bw4", - "name": "Next Destinies", - "success": true, - "importedCount": 0 - }, - { - "code": "bw5", - "name": "Dark Explorers", - "success": true, - "importedCount": 111 - }, - { - "code": "bw6", - "name": "Dragons Exalted", - "success": true, - "importedCount": 128 - }, - { - "code": "bw7", - "name": "Boundaries Crossed", - "success": true, - "importedCount": 153 - }, - { - "code": "bw8", - "name": "Plasma Storm", - "success": false, - "error": "Import failed" - }, - { - "code": "bw9", - "name": "Plasma Freeze", - "success": false, - "error": "Import failed" - }, - { - "code": "bw10", - "name": "Plasma Blast", - "success": false, - "error": "Import failed" - }, - { - "code": "bw11", - "name": "Legendary Treasures", - "success": true, - "importedCount": 0 - }, - { - "code": "xy1", - "name": "XY", - "success": true, - "importedCount": 0 - }, - { - "code": "xy2", - "name": "Flashfire", - "success": false, - "error": "Import failed" - }, - { - "code": "xy3", - "name": "Furious Fists", - "success": false, - "error": "Import failed" - }, - { - "code": "xy4", - "name": "Phantom Forces", - "success": false, - "error": "Import failed" - }, - { - "code": "xy5", - "name": "Primal Clash", - "success": true, - "importedCount": 164 - }, - { - "code": "xy6", - "name": "Double Crisis", - "success": true, - "importedCount": 112 - }, - { - "code": "xy7", - "name": "Roaring Skies", - "success": false, - "error": "Import failed" - }, - { - "code": "xy8", - "name": "Ancient Origins", - "success": false, - "error": "Import failed" - }, - { - "code": "xy9", - "name": "BREAKthrough", - "success": true, - "importedCount": 0 - }, - { - "code": "xy10", - "name": "BREAKpoint", - "success": false, - "error": "Import failed" - }, - { - "code": "xy11", - "name": "Fates Collide", - "success": true, - "importedCount": 0 - }, - { - "code": "xy12", - "name": "Steam Siege", - "success": true, - "importedCount": 0 - }, - { - "code": "xy12", - "name": "Evolutions", - "success": true, - "importedCount": 0 - }, - { - "code": "sm1", - "name": "Sun & Moon", - "success": true, - "importedCount": 173 - }, - { - "code": "sm2", - "name": "Guardians Rising", - "success": true, - "importedCount": 180 - }, - { - "code": "sm3", - "name": "Burning Shadows", - "success": true, - "importedCount": 0 - }, - { - "code": "sm4", - "name": "Crimson Invasion", - "success": true, - "importedCount": 0 - }, - { - "code": "sm5", - "name": "Ultra Prism", - "success": true, - "importedCount": 178 - }, - { - "code": "sm6", - "name": "Forbidden Light", - "success": true, - "importedCount": 150 - }, - { - "code": "sm7", - "name": "Celestial Storm", - "success": true, - "importedCount": 0 - }, - { - "code": "sm8", - "name": "Dragon Majesty", - "success": true, - "importedCount": 0 - }, - { - "code": "sm9", - "name": "Lost Thunder", - "success": true, - "importedCount": 0 - }, - { - "code": "sm10", - "name": "Team Up", - "success": true, - "importedCount": 0 - }, - { - "code": "sm11", - "name": "Detective Pikachu", - "success": true, - "importedCount": 250 - }, - { - "code": "sm12", - "name": "Unbroken Bonds", - "success": true, - "importedCount": 250 - }, - { - "code": "sm115", - "name": "Unified Minds", - "success": true, - "importedCount": 69 - }, - { - "code": "sm116", - "name": "Hidden Fates", - "success": true, - "importedCount": 0 - }, - { - "code": "sm117", - "name": "Cosmic Eclipse", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh1", - "name": "Sword & Shield", - "success": true, - "importedCount": 216 - }, - { - "code": "swsh2", - "name": "Rebel Clash", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh3", - "name": "Darkness Ablaze", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh4", - "name": "Champions Path", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh5", - "name": "Vivid Voltage", - "success": true, - "importedCount": 183 - }, - { - "code": "swsh6", - "name": "Shining Fates", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh7", - "name": "Battle Styles", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh8", - "name": "Chilling Reign", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh9", - "name": "Evolving Skies", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh10", - "name": "Celebrations", - "success": true, - "importedCount": 216 - }, - { - "code": "swsh11", - "name": "Fusion Strike", - "success": true, - "importedCount": 217 - }, - { - "code": "swsh12", - "name": "Brilliant Stars", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh12", - "name": "Astral Radiance", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh12", - "name": "Pokemon GO", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh12", - "name": "Lost Origin", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh12", - "name": "Silver Tempest", - "success": true, - "importedCount": 0 - }, - { - "code": "swsh12", - "name": "Crown Zenith", - "success": true, - "importedCount": 0 - }, - { - "code": "sv1", - "name": "Scarlet & Violet", - "success": true, - "importedCount": 250 - }, - { - "code": "sv2", - "name": "Paldea Evolved", - "success": true, - "importedCount": 250 - }, - { - "code": "sv3", - "name": "Obsidian Flames", - "success": true, - "importedCount": 230 - }, - { - "code": "sv4", - "name": "151", - "success": true, - "importedCount": 250 - }, - { - "code": "sv5", - "name": "Paradox Rift", - "success": true, - "importedCount": 218 - }, - { - "code": "sv6", - "name": "Paldean Fates", - "success": true, - "importedCount": 226 - }, - { - "code": "sv7", - "name": "Temporal Forces", - "success": true, - "importedCount": 0 - } - ] - }, - "lorcana": { - "total": 3, - "successful": 3, - "failed": 0, - "sets": [ - { - "code": "tfc", - "name": "The First Chapter", - "success": true, - "importedCount": 1 - }, - { - "code": "rotf", - "name": "Rise of the Floodborn", - "success": true, - "importedCount": 1 - }, - { - "code": "ink", - "name": "Into the Inklands", - "success": true, - "importedCount": 1 - } - ] - } -} \ No newline at end of file diff --git a/components/ActivityLog.js b/components/ActivityLog.js deleted file mode 100644 index beff00c..0000000 --- a/components/ActivityLog.js +++ /dev/null @@ -1,172 +0,0 @@ -import { useState, useEffect } from 'react'; - -export default function ActivityLog({ collectionId }) { - const [activities, setActivities] = useState([]); - const [loading, setLoading] = useState(true); - const [showAll, setShowAll] = useState(false); - - useEffect(() => { - if (collectionId) { - fetchActivities(); - } - }, [collectionId]); - - const fetchActivities = async () => { - try { - const response = await fetch(`/api/collections/${collectionId}/activity`); - if (response.ok) { - const data = await response.json(); - setActivities(data); - } - } catch (error) { - console.error('Error fetching activities:', error); - } finally { - setLoading(false); - } - }; - - const getActivityIcon = (action) => { - switch (action) { - case 'card_added': return '➕'; - case 'card_removed': return '➖'; - case 'card_quantity_updated': return '��'; - case 'collection_updated': return '✏️'; - case 'collection_deleted': return '🗑️'; - case 'user_invited': return '📧'; - case 'invitation_accepted': return '✅'; - case 'invitation_declined': return '❌'; - case 'permission_updated': return '🔐'; - case 'user_removed': return '👋'; - default: return '📝'; - } - }; - - const getActivityDescription = (activity) => { - const { action, details } = activity; - - switch (action) { - case 'card_added': - return `added a card (qty: ${details.quantity})`; - case 'card_removed': - return details.reason === 'quantity_zero' - ? 'removed a card by setting quantity to 0' - : 'removed a card from the collection'; - case 'card_quantity_updated': - return details.oldQuantity - ? `updated card quantity from ${details.oldQuantity} to ${details.newQuantity}` - : `updated card quantity to ${details.newQuantity}`; - case 'collection_updated': - return 'updated collection details'; - case 'collection_deleted': - return 'deleted the collection'; - case 'user_invited': - return `invited ${details.email} as ${details.role}`; - case 'invitation_accepted': - return 'accepted an invitation'; - case 'invitation_declined': - return 'declined an invitation'; - case 'permission_updated': - return `updated user permissions to ${details.role}`; - case 'user_removed': - return 'removed a user from the collection'; - default: - return action.replace(/_/g, ' '); - } - }; - - const formatTimeAgo = (timestamp) => { - const now = new Date(); - const activityTime = new Date(timestamp); - const diffMs = now - activityTime; - const diffMins = Math.floor(diffMs / 60000); - const diffHours = Math.floor(diffMs / 3600000); - const diffDays = Math.floor(diffMs / 86400000); - - if (diffMins < 1) return 'just now'; - if (diffMins < 60) return `${diffMins}m ago`; - if (diffHours < 24) return `${diffHours}h ago`; - if (diffDays < 7) return `${diffDays}d ago`; - return activityTime.toLocaleDateString(); - }; - - if (loading) { - return ( -
-
-
-
-
-
-
-
-
-
- ); - } - - const displayedActivities = showAll ? activities : activities.slice(0, 5); - - return ( -
-
-

- Recent Activity -

- {activities.length > 5 && ( - - )} -
- -
- {displayedActivities.map((activity) => ( -
-
- {getActivityIcon(activity.action)} -
-
-
-

- {activity.user_email || 'System'} - {' '} - {getActivityDescription(activity)} -

- - {formatTimeAgo(activity.created_at)} - -
- {activity.details && Object.keys(activity.details).length > 0 && ( -
- {activity.action === 'collection_updated' && activity.details.name && ( - Name: "{activity.details.name}" - )} - {activity.action === 'user_invited' && activity.details.message && ( - Message: "{activity.details.message}" - )} -
- )} -
-
- ))} - - {activities.length === 0 && ( -
-
📝
-

- No activity yet. Start collaborating to see updates here! -

-
- )} -
-
- ); -} diff --git a/components/BulkInviteModal.js b/components/BulkInviteModal.js deleted file mode 100644 index 12cd2ed..0000000 --- a/components/BulkInviteModal.js +++ /dev/null @@ -1,219 +0,0 @@ -import { useState } from 'react'; - -export default function BulkInviteModal({ collectionId, isOpen, onClose, onSuccess }) { - const [inviteData, setInviteData] = useState({ - emails: '', - role: 'editor', - message: '' - }); - const [processing, setProcessing] = useState(false); - const [results, setResults] = useState(null); - - const handleSubmit = async (e) => { - e.preventDefault(); - setProcessing(true); - setResults(null); - - try { - // Parse emails (split by comma, semicolon, or newline) - const emailList = inviteData.emails - .split(/[,;\n]/) - .map(email => email.trim()) - .filter(email => email && email.includes('@')); - - if (emailList.length === 0) { - alert('Please enter at least one valid email address'); - setProcessing(false); - return; - } - - // Send invitations - const invitePromises = emailList.map(email => - fetch(`/api/collections/${collectionId}/permissions`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - email, - role: inviteData.role, - message: inviteData.message - }) - }).then(async response => ({ - email, - success: response.ok, - error: response.ok ? null : (await response.json()).error - })) - ); - - const results = await Promise.all(invitePromises); - setResults(results); - - const successCount = results.filter(r => r.success).length; - if (successCount > 0 && onSuccess) { - onSuccess(); - } - - } catch (error) { - console.error('Bulk invite error:', error); - alert('An error occurred while sending invitations'); - } finally { - setProcessing(false); - } - }; - - const handleClose = () => { - setInviteData({ emails: '', role: 'editor', message: '' }); - setResults(null); - onClose(); - }; - - const successCount = results ? results.filter(r => r.success).length : 0; - const failureCount = results ? results.filter(r => !r.success).length : 0; - - if (!isOpen) return null; - - return ( -
-
-

- Bulk Invite Collaborators -

- - {!results ? ( -
-
- -