Create INDIAN-SCRIPTURE-MAP-JSX
Browse files- INDIAN-SCRIPTURE-MAP-JSX +583 -0
INDIAN-SCRIPTURE-MAP-JSX
ADDED
|
@@ -0,0 +1,583 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useState, useMemo, useEffect, useRef } from 'react';
|
| 2 |
+
import {
|
| 3 |
+
BookOpen, Clock, User, Info, Link as LinkIcon, Search, X, Feather,
|
| 4 |
+
Library, ScrollText, Sparkles, LayoutGrid, Network, Move
|
| 5 |
+
} from 'lucide-react';
|
| 6 |
+
|
| 7 |
+
// --- COMPREHENSIVE DATASET BASED ON THE FLOWCHART ---
|
| 8 |
+
// Redesigned with massive canvas spacing to prevent any overlapping and allow beautiful wire routing.
|
| 9 |
+
const SCRIPTURES = [
|
| 10 |
+
// LEVEL 0: ROOT
|
| 11 |
+
{ id: 'root', name: 'Hindu Scriptures', category: 'Root', timePeriod: 'Various', writer: 'Various Sages', description: 'The vast body of sacred texts in Hinduism, traditionally divided into Shruti (what is heard) and Smriti (what is remembered).', x: 0, y: 0, parentId: null, relatedTo: ['shruti', 'smriti'] },
|
| 12 |
+
|
| 13 |
+
// LEVEL 1: BROAD CLASSIFICATIONS
|
| 14 |
+
{ id: 'shruti', name: 'Shruti (श्रुति)', category: 'Classification', timePeriod: 'Pre-1500 BCE', writer: 'Revealed to Rishis', description: '"That which was heard" - the most authoritative, ancient religious texts comprising the central canon of Hinduism.', x: -800, y: 150, parentId: 'root', relatedTo: ['rigveda', 'samaveda', 'yajurveda', 'atharvaveda'] },
|
| 15 |
+
{ id: 'smriti', name: 'Smriti (स्मृति)', category: 'Classification', timePeriod: 'Post-500 BCE', writer: 'Various Human Authors', description: '"That which is remembered" - a body of Hindu texts usually attributed to an author, traditionally written down and constantly revised.', x: 800, y: 150, parentId: 'root', relatedTo: ['dharmashastras', 'puranas', 'vedangas', 'darshana', 'upaveda', 'itihaas', 'agamas'] },
|
| 16 |
+
|
| 17 |
+
// LEVEL 2: SHRUTI BRANCH (THE VEDAS)
|
| 18 |
+
{ id: 'rigveda', name: 'Rigveda', category: 'Veda', timePeriod: 'c. 1500 – 1000 BCE', writer: 'Various Rishis', description: 'The oldest sacred book of Hinduism, consisting of 1,028 hymns dedicated to various deities.', x: -1400, y: 350, parentId: 'shruti', relatedTo: ['karmakanda', 'gyanakanda'] },
|
| 19 |
+
{ id: 'samaveda', name: 'Samaveda', category: 'Veda', timePeriod: 'c. 1200 – 1000 BCE', writer: 'Various Rishis', description: 'The Veda of melodies and chants, mostly drawn from the Rigveda, set to musical notation.', x: -1000, y: 350, parentId: 'shruti', relatedTo: ['karmakanda', 'gyanakanda'] },
|
| 20 |
+
{ id: 'yajurveda', name: 'Yajurveda', category: 'Veda', timePeriod: 'c. 1200 – 1000 BCE', writer: 'Various Rishis', description: 'The Veda of prose mantras containing ritual offering formulas.', x: -600, y: 350, parentId: 'shruti', relatedTo: ['karmakanda', 'gyanakanda'] },
|
| 21 |
+
{ id: 'atharvaveda', name: 'Atharvaveda', category: 'Veda', timePeriod: 'c. 1000 – 900 BCE', writer: 'Atharvan and Angiras rishis', description: 'The "knowledge storehouse of the procedures for everyday life", dealing with spells and charms.', x: -200, y: 350, parentId: 'shruti', relatedTo: ['karmakanda', 'gyanakanda'] },
|
| 22 |
+
|
| 23 |
+
// LEVEL 3: KANDAS (SUBSECTIONS OF VEDAS)
|
| 24 |
+
{ id: 'karmakanda', name: 'Karma kanda (कर्मकाण्ड)', category: 'Kanda', timePeriod: 'Ancient', writer: 'Various', description: 'The section of the Vedas dealing with rituals, sacrifices, and duties. Includes Samhitas and Brahmanas.', x: -1200, y: 500, parentId: 'shruti', relatedTo: ['rigveda', 'yajurveda'] },
|
| 25 |
+
{ id: 'gyanakanda', name: 'Gyana kanda (ज्ञानकाण्ड)', category: 'Kanda', timePeriod: 'Ancient', writer: 'Various', description: 'The section of the Vedas dealing with knowledge and spirituality. Includes Aranyakas and Upanishads.', x: -400, y: 500, parentId: 'shruti', relatedTo: ['upanishads'] },
|
| 26 |
+
|
| 27 |
+
// LEVEL 4: UPANISHADS (UNDER GYANA KANDA)
|
| 28 |
+
{ id: 'aiteriya', name: 'Aitareya', category: 'Upanishad', timePeriod: 'c. 800 - 500 BCE', writer: 'Mahidasa Aitareya', description: 'Discusses three philosophical themes: the world, the soul (Atman), and the concept of ultimate reality (Brahman).', x: -600, y: 650, parentId: 'gyanakanda', relatedTo: ['rigveda'] },
|
| 29 |
+
{ id: 'chandogya', name: 'Chaandogya', category: 'Upanishad', timePeriod: 'c. 800 - 600 BCE', writer: 'Various Sages', description: 'One of the oldest and largest Upanishads, focusing on the chanting of Om and the realization of Brahman.', x: -600, y: 730, parentId: 'gyanakanda', relatedTo: ['samaveda'] },
|
| 30 |
+
{ id: 'kena', name: 'Kena', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Unknown', description: 'Investigates the nature of knowledge, inquiring "by whom" (Kena) the mind and senses are directed.', x: -600, y: 810, parentId: 'gyanakanda', relatedTo: ['samaveda'] },
|
| 31 |
+
{ id: 'katha', name: 'Kathaka (Katha)', category: 'Upanishad', timePeriod: 'c. 5th century BCE', writer: 'Unknown', description: 'Features the famous dialogue between the young boy Nachiketa and Yama (the deity of death).', x: -600, y: 890, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 32 |
+
{ id: 'taittiriya', name: 'Taittariya', category: 'Upanishad', timePeriod: 'c. 6th century BCE', writer: 'Taittiri Sages', description: 'Explores the five layers (Koshas) of human existence and the nature of bliss.', x: -600, y: 970, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 33 |
+
{ id: 'isha', name: 'Ishavasya', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Unknown', description: 'A short but profound text discussing the immanence of the Lord (Isha) in everything.', x: -600, y: 1050, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 34 |
+
{ id: 'brihadaaranyaka', name: 'Brihadaranyaka', category: 'Upanishad', timePeriod: 'c. 900 - 600 BCE', writer: 'Yajnavalkya', description: 'The "Great Forest" Upanishad. A massive text dealing with the Atman, karma, and rebirth.', x: -600, y: 1130, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 35 |
+
{ id: 'prashna', name: 'Prashna', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Pippalada', description: 'Structured around six questions (Prashna) asked by students regarding life, breath, and the ultimate reality.', x: -200, y: 650, parentId: 'gyanakanda', relatedTo: ['atharvaveda'] },
|
| 36 |
+
{ id: 'mundaka', name: 'Mundaka', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Angiras', description: 'Distinguishes between higher knowledge (of Brahman) and lower knowledge (rituals), famous for "Satyameva Jayate".', x: -200, y: 730, parentId: 'gyanakanda', relatedTo: ['atharvaveda'] },
|
| 37 |
+
{ id: 'mandukya', name: 'Maandukya', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Unknown', description: 'The shortest Upanishad, analyzing the four states of consciousness mapping to the syllable OM.', x: -200, y: 810, parentId: 'gyanakanda', relatedTo: ['atharvaveda'] },
|
| 38 |
+
{ id: 'kaushitaki', name: 'Kaushitaki', category: 'Upanishad', timePeriod: 'c. 800 - 500 BCE', writer: 'Unknown', description: 'Explores the nature of the self (Atman) and the ultimate reality (Brahman), emphasizing Prana (breath/life force).', x: -200, y: 890, parentId: 'gyanakanda', relatedTo: ['rigveda'] },
|
| 39 |
+
{ id: 'shvetashvatara', name: 'Shvetashvatara', category: 'Upanishad', timePeriod: 'c. 6th - 4th century BCE', writer: 'Shvetashvatara', description: 'Discusses Shiva as the supreme Lord, introducing elements of Yoga, Samkhya, and Bhakti within a Vedantic framework.', x: -200, y: 970, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 40 |
+
{ id: 'maitrayani', name: 'Maitrayani', category: 'Upanishad', timePeriod: 'c. 1st millennium BCE', writer: 'Maitri', description: 'Focuses on the concept of Atman and introduces the idea of the Trimurti (Brahma, Vishnu, Shiva) as manifestations of the Supreme.', x: -200, y: 1050, parentId: 'gyanakanda', relatedTo: ['yajurveda'] },
|
| 41 |
+
|
| 42 |
+
// LEVEL 2: SMRITI BRANCH CATEGORIES
|
| 43 |
+
{ id: 'dharmashastras', name: 'Dharmashastra', category: 'Category', timePeriod: 'Various', writer: 'Various', description: 'Treatises on Dharma (law, duty, and correct behavior).', x: 200, y: 350, parentId: 'smriti', relatedTo: ['manusmriti'] },
|
| 44 |
+
{ id: 'itihaas', name: 'Ithihaasa', category: 'Category', timePeriod: 'Various', writer: 'Various', description: '"History" - narrative epics containing profound philosophical teachings embedded in stories.', x: 500, y: 350, parentId: 'smriti', relatedTo: ['ramayana', 'mahabharat'] },
|
| 45 |
+
{ id: 'puranas', name: 'Purana', category: 'Category', timePeriod: 'Various', writer: 'Vyasa (traditionally)', description: 'Ancient lore containing narratives of the history of the universe, genealogies of kings, and myths of deities.', x: 900, y: 350, parentId: 'smriti', relatedTo: [] },
|
| 46 |
+
{ id: 'vedangas', name: 'Vedanga', category: 'Category', timePeriod: 'Ancient', writer: 'Various', description: 'Six auxiliary disciplines for understanding and preserving the Vedas.', x: 1300, y: 350, parentId: 'smriti', relatedTo: [] },
|
| 47 |
+
{ id: 'agamas', name: 'Agama', category: 'Category', timePeriod: 'Various', writer: 'Various', description: 'Theological treatises and practical manuals of divine worship (temple construction, rituals).', x: 1600, y: 350, parentId: 'smriti', relatedTo: [] },
|
| 48 |
+
{ id: 'darshana', name: 'Darshana', category: 'Category', timePeriod: 'Various', writer: 'Various', description: 'The six orthodox schools of Hindu philosophy.', x: 1900, y: 350, parentId: 'smriti', relatedTo: [] },
|
| 49 |
+
{ id: 'upaveda', name: 'Upavedas', category: 'Category', timePeriod: 'Various', writer: 'Various', description: 'Applied knowledge disciplines associated with the specific Vedas.', x: 2200, y: 350, parentId: 'smriti', relatedTo: [] },
|
| 50 |
+
|
| 51 |
+
// LEVEL 3: SMRITI CHILDREN (Vertical Layouts mapped by increasing Y with huge spacing)
|
| 52 |
+
// Dharmashastras
|
| 53 |
+
{ id: 'manusmriti', name: 'Manu', category: 'Dharmashastra', timePeriod: 'c. 200 BCE – 300 CE', writer: 'Attributed to Manu', description: 'An ancient legal text outlining codes of conduct, laws, and social duties.', x: 200, y: 500, parentId: 'dharmashastras', relatedTo: [] },
|
| 54 |
+
{ id: 'yagyavalkyasmriti', name: 'Yajnavalkya', category: 'Dharmashastra', timePeriod: 'c. 3rd-5th century CE', writer: 'Yajnavalkya', description: 'One of the most systematically structured texts on Dharma, influential in Hindu law.', x: 200, y: 580, parentId: 'dharmashastras', relatedTo: [] },
|
| 55 |
+
{ id: 'apastamba', name: 'Apastamba etc.', category: 'Dharmashastra', timePeriod: 'c. 600 - 300 BCE', writer: 'Apastamba', description: 'One of the best-preserved Dharmasutras, offering detailed aphorisms on law, duty, and Vedic rituals.', x: 200, y: 660, parentId: 'dharmashastras', relatedTo: [] },
|
| 56 |
+
|
| 57 |
+
// Itihaas
|
| 58 |
+
{ id: 'ramayana', name: 'Ramayana', category: 'Itihasa', timePeriod: 'c. 500 BCE – 100 BCE', writer: 'Valmiki', description: 'The epic narrating the life of Rama, exploring human values and the concept of dharma.', x: 500, y: 500, parentId: 'itihaas', relatedTo: ['mahabharat'] },
|
| 59 |
+
{ id: 'mahabharat', name: 'Mahabharata', category: 'Itihasa', timePeriod: 'c. 400 BCE – 400 CE', writer: 'Vyasa', description: 'The massive epic narrating the Kurukshetra War. It contains profound philosophical teachings.', x: 500, y: 580, parentId: 'itihaas', relatedTo: ['ramayana', 'gita'] },
|
| 60 |
+
{ id: 'gita', name: 'Gita', category: 'Itihasa', timePeriod: 'c. 400 BCE – 200 CE', writer: 'Vyasa', description: 'A 700-verse philosophical dialogue embedded in the Mahabharata between Prince Arjuna and Krishna regarding duty (Dharma) and righteous action.', x: 500, y: 660, parentId: 'mahabharat', relatedTo: ['upanishads'] },
|
| 61 |
+
|
| 62 |
+
// Puranas (18 Mahapuranas split into two columns widely separated)
|
| 63 |
+
// Column 1
|
| 64 |
+
{ id: 'brahmapurana', name: 'Brahma', category: 'Purana', timePeriod: 'c. 1st millennium CE', writer: 'Vyasa', description: 'One of the Mahapuranas, dealing with cosmology and geography, specifically regions around Godavari river.', x: 800, y: 500, parentId: 'puranas', relatedTo: [] },
|
| 65 |
+
{ id: 'padmapurana', name: 'Padma', category: 'Purana', timePeriod: 'c. 4th-15th century CE', writer: 'Vyasa', description: 'A massive text detailing cosmology, geography, and legends, often with a strong Vaishnava focus.', x: 800, y: 580, parentId: 'puranas', relatedTo: [] },
|
| 66 |
+
{ id: 'vishnupurana', name: 'Vishnu', category: 'Purana', timePeriod: 'c. 400 BCE - 900 CE', writer: 'Parashara', description: 'An important Pancharatra text detailing myths, cosmology, and genealogies centered on Vishnu.', x: 800, y: 660, parentId: 'puranas', relatedTo: [] },
|
| 67 |
+
{ id: 'vayupurana', name: 'Vayu', category: 'Purana', timePeriod: 'c. 300-500 CE', writer: 'Vyasa', description: 'One of the oldest Puranas, dedicated to Vayu (the wind god), containing extensive kingly genealogies.', x: 800, y: 740, parentId: 'puranas', relatedTo: [] },
|
| 68 |
+
{ id: 'bhagavatam', name: 'Bhagavata', category: 'Purana', timePeriod: 'c. 800 – 1000 CE', writer: 'Vyasa', description: 'Revered Purana promoting bhakti (devotion) to Krishna.', x: 800, y: 820, parentId: 'puranas', relatedTo: ['mahabharat'] },
|
| 69 |
+
{ id: 'naradapurana', name: 'Narada', category: 'Purana', timePeriod: 'c. 10th-12th century CE', writer: 'Vyasa', description: 'A text presented as teachings from the sage Narada, emphasizing devotion (Bhakti) to Vishnu.', x: 800, y: 900, parentId: 'puranas', relatedTo: [] },
|
| 70 |
+
{ id: 'markandeya', name: 'Markandeya', category: 'Purana', timePeriod: 'c. 3rd-4th century CE', writer: 'Vyasa', description: 'Features conversations between sages and includes the famous Devi Mahatmya (glory of the Goddess).', x: 800, y: 980, parentId: 'puranas', relatedTo: [] },
|
| 71 |
+
{ id: 'agnipurana', name: 'Agni', category: 'Purana', timePeriod: 'c. 8th-11th century CE', writer: 'Vyasa', description: 'An encyclopedic Purana covering diverse topics like ritual worship, cosmology, astrology, and martial arts.', x: 800, y: 1060, parentId: 'puranas', relatedTo: [] },
|
| 72 |
+
{ id: 'bhavishya', name: 'Bhavishya', category: 'Purana', timePeriod: 'c. 11th century CE', writer: 'Vyasa', description: 'A Purana notable for containing prophecies regarding future events and dynasties.', x: 800, y: 1140, parentId: 'puranas', relatedTo: [] },
|
| 73 |
+
// Column 2
|
| 74 |
+
{ id: 'brahmavaivarta', name: 'Brahmavaivarta', category: 'Purana', timePeriod: 'c. 8th-16th century CE', writer: 'Vyasa', description: 'Focuses heavily on the life and deeds of Krishna and his consort Radha.', x: 1000, y: 500, parentId: 'puranas', relatedTo: [] },
|
| 75 |
+
{ id: 'lingapurana', name: 'Linga', category: 'Purana', timePeriod: 'c. 5th-10th century CE', writer: 'Vyasa', description: 'Dedicated to Shiva, emphasizing his worship through the Lingam and detailing Shaiva philosophy.', x: 1000, y: 580, parentId: 'puranas', relatedTo: [] },
|
| 76 |
+
{ id: 'varaha', name: 'Varaha', category: 'Purana', timePeriod: 'c. 10th-12th century CE', writer: 'Vyasa', description: 'Narrated by Vishnu in his boar avatar (Varaha), focusing on devotion and pilgrimage sites.', x: 1000, y: 660, parentId: 'puranas', relatedTo: [] },
|
| 77 |
+
{ id: 'skanda', name: 'Skanda', category: 'Purana', timePeriod: 'c. 8th century CE onwards', writer: 'Vyasa', description: 'The largest Mahapurana, containing numerous geographical and pilgrimage guides (Tirtha Mahatmyas).', x: 1000, y: 740, parentId: 'puranas', relatedTo: [] },
|
| 78 |
+
{ id: 'vamana', name: 'Vamana', category: 'Purana', timePeriod: 'c. 9th-11th century CE', writer: 'Vyasa', description: 'Centered around the dwarf avatar (Vamana) of Vishnu, but contains substantial Shaiva material.', x: 1000, y: 820, parentId: 'puranas', relatedTo: [] },
|
| 79 |
+
{ id: 'kurma', name: 'Kurma', category: 'Purana', timePeriod: 'c. 8th century CE', writer: 'Vyasa', description: 'Narrated by Vishnu in his tortoise avatar (Kurma), covering mythology and the Kurma Gita.', x: 1000, y: 900, parentId: 'puranas', relatedTo: [] },
|
| 80 |
+
{ id: 'matsyapurana', name: 'Matsya', category: 'Purana', timePeriod: 'c. 3rd century CE', writer: 'Vyasa', description: 'Named after the fish avatar of Vishnu, containing diverse encyclopedic topics.', x: 1000, y: 980, parentId: 'puranas', relatedTo: [] },
|
| 81 |
+
{ id: 'garuda', name: 'Garuda', category: 'Purana', timePeriod: 'c. 1st millennium CE', writer: 'Vyasa', description: 'A Vaishnava text famous for its detailed descriptions of death, the afterlife, and funeral rites.', x: 1000, y: 1060, parentId: 'puranas', relatedTo: [] },
|
| 82 |
+
{ id: 'brahmanda', name: 'Brahmanda', category: 'Purana', timePeriod: 'c. 4th-6th century CE', writer: 'Vyasa', description: 'Details the \'cosmic egg\' (Brahmanda) cosmology, genealogies, and the famous Lalita Sahasranama.', x: 1000, y: 1140, parentId: 'puranas', relatedTo: [] },
|
| 83 |
+
{ id: 'shivapurana', name: 'Shiva', category: 'Purana', timePeriod: 'c. 10th-11th century CE', writer: 'Romaharshana/Vyasa', description: 'A major text centered on the Hindu god Shiva and his consort Parvati.', x: 900, y: 1220, parentId: 'puranas', relatedTo: [] }, // Centered below columns
|
| 84 |
+
|
| 85 |
+
// Vedangas
|
| 86 |
+
{ id: 'shiksha', name: 'Shiksha (phonetics)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Various', description: 'Phonetics, phonology, and pronunciation of Vedic mantras.', x: 1300, y: 500, parentId: 'vedangas', relatedTo: [] },
|
| 87 |
+
{ id: 'vyakarana', name: 'Vyakarana (grammar)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Panini (notable)', description: 'Grammar and linguistic analysis.', x: 1300, y: 580, parentId: 'vedangas', relatedTo: [] },
|
| 88 |
+
{ id: 'kalpa', name: 'Kalpasutra (Rites)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Various', description: 'Ritual instructions, rules, and geometry.', x: 1300, y: 660, parentId: 'vedangas', relatedTo: [] },
|
| 89 |
+
{ id: 'jyotisha', name: 'Jyotisha (Astronomy)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Lagadha (notable)', description: 'Auspicious timekeeping and astronomy for rituals.', x: 1300, y: 740, parentId: 'vedangas', relatedTo: [] },
|
| 90 |
+
{ id: 'nirukta', name: 'Nirukta (Etymology)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Yaska (notable)', description: 'Etymology and explanation of complex Vedic words.', x: 1300, y: 820, parentId: 'vedangas', relatedTo: [] },
|
| 91 |
+
{ id: 'chhanda', name: 'Chhanda (metre)', category: 'Vedanga', timePeriod: 'Ancient', writer: 'Pingala (notable)', description: 'Study of poetic meters in Vedic texts.', x: 1300, y: 900, parentId: 'vedangas', relatedTo: [] },
|
| 92 |
+
|
| 93 |
+
// Agamas
|
| 94 |
+
{ id: 'pancharatra', name: 'Pancharatra', category: 'Agama', timePeriod: 'Various', writer: 'Various', description: 'Agamas centered on the worship of Lord Vishnu/Narayana.', x: 1600, y: 500, parentId: 'agamas', relatedTo: [] },
|
| 95 |
+
{ id: 'shaiva', name: 'Shaiva', category: 'Agama', timePeriod: 'Various', writer: 'Various', description: 'Agamas detailing the rituals and philosophy of Shaivism.', x: 1600, y: 580, parentId: 'agamas', relatedTo: [] },
|
| 96 |
+
{ id: 'shakta', name: 'Shaakta', category: 'Agama', timePeriod: 'Various', writer: 'Various', description: 'Tantric texts focusing on the worship of the Goddess (Devi / Shakti).', x: 1600, y: 660, parentId: 'agamas', relatedTo: [] },
|
| 97 |
+
|
| 98 |
+
// Darshana
|
| 99 |
+
{ id: 'nyaya', name: 'Nyaaya', category: 'Darshana', timePeriod: 'Ancient', writer: 'Gautama', description: 'School focused on logic and epistemology.', x: 1900, y: 500, parentId: 'darshana', relatedTo: ['vaisheshika'] },
|
| 100 |
+
{ id: 'vaisheshika', name: 'Vaisheshika', category: 'Darshana', timePeriod: 'Ancient', writer: 'Kanada', description: 'School of atomism, postulating that all objects in the physical universe are reducible to atoms.', x: 1900, y: 580, parentId: 'darshana', relatedTo: ['nyaya'] },
|
| 101 |
+
{ id: 'samkhya', name: 'Sankhya', category: 'Darshana', timePeriod: 'Ancient', writer: 'Kapila', description: 'Strongly dualistic school identifying reality as consciousness (Purusha) and matter (Prakriti).', x: 1900, y: 660, parentId: 'darshana', relatedTo: ['yoga'] },
|
| 102 |
+
{ id: 'yoga', name: 'Yoga', category: 'Darshana', timePeriod: 'Ancient', writer: 'Patanjali', description: 'School focusing on meditation, contemplation and liberation (closely linked to Samkhya).', x: 1900, y: 740, parentId: 'darshana', relatedTo: ['samkhya'] },
|
| 103 |
+
{ id: 'purva_mimamsa', name: 'Purva Mimamsa', category: 'Darshana', timePeriod: 'Ancient', writer: 'Sage Jaimini', description: 'Also known as "Karma Mimamsa". Focuses on the Karma-kanda (ritualistic portion of the Vedas). It emphasizes the correct performance of Vedic rituals and achieving salvation through Dharma. Key Text: Mimamsa Sutra.', x: 1900, y: 820, parentId: 'darshana', relatedTo: ['uttara_mimamsa', 'karmakanda'] },
|
| 104 |
+
{ id: 'uttara_mimamsa', name: 'Uttara Mimamsa (Vedanta)', category: 'Darshana', timePeriod: 'Ancient', writer: 'Sage Badarayana (Vyasa)', description: 'Also known as "Jnana Mimamsa" or Vedanta. Focuses on the Jnana-kanda (knowledge portion of the Vedas). Explores the nature of Brahman (Universal Soul), Atman, and Moksha. Key Text: Brahma Sutra.', x: 1900, y: 900, parentId: 'darshana', relatedTo: ['purva_mimamsa', 'gyanakanda', 'upanishads'] },
|
| 105 |
+
|
| 106 |
+
// Upaveda
|
| 107 |
+
{ id: 'arthashastra', name: 'Arthashastra', category: 'Upaveda', timePeriod: 'Ancient', writer: 'Chanakya (Kautilya)', description: 'The science of statecraft, economic policy, and military strategy.', x: 2200, y: 500, parentId: 'upaveda', relatedTo: [] },
|
| 108 |
+
{ id: 'ayurveda', name: 'Ayurveda', category: 'Upaveda', timePeriod: 'Ancient', writer: 'Various', description: 'The ancient Indian system of medicine and life science (associated with Rigveda/Atharvaveda).', x: 2200, y: 580, parentId: 'upaveda', relatedTo: ['rigveda', 'atharvaveda'] },
|
| 109 |
+
{ id: 'gandharvaveda', name: 'Gandharvaveda', category: 'Upaveda', timePeriod: 'Ancient', writer: 'Various', description: 'The science of music, dance, and arts (associated with Samaveda).', x: 2200, y: 660, parentId: 'upaveda', relatedTo: ['samaveda'] },
|
| 110 |
+
{ id: 'dhanurveda', name: 'Dhanurveda', category: 'Upaveda', timePeriod: 'Ancient', writer: 'Various', description: 'The science of archery and warfare (associated with Yajurveda).', x: 2200, y: 740, parentId: 'upaveda', relatedTo: ['yajurveda'] },
|
| 111 |
+
{ id: 'shilpasthapatya', name: 'Shilpa-Sthapatya', category: 'Upaveda', timePeriod: 'Ancient', writer: 'Various', description: 'The science of architecture, engineering, and fine arts.', x: 2200, y: 820, parentId: 'upaveda', relatedTo: [] }
|
| 112 |
+
];
|
| 113 |
+
|
| 114 |
+
// --- COLOR THEMES BASED ON CATEGORY ---
|
| 115 |
+
const CATEGORY_COLORS = {
|
| 116 |
+
'Root': { bg: 'bg-indigo-600', border: 'border-indigo-800', text: 'text-indigo-50', light: 'bg-indigo-600', icon: 'text-indigo-200', badge: 'bg-indigo-800 text-indigo-100', node: 'bg-indigo-600 text-white border-indigo-800 shadow-indigo-500/50' },
|
| 117 |
+
'Classification': { bg: 'bg-violet-500', border: 'border-violet-700', text: 'text-violet-50', light: 'bg-violet-500', icon: 'text-violet-200', badge: 'bg-violet-700 text-violet-100', node: 'bg-violet-500 text-white border-violet-700 shadow-violet-500/40' },
|
| 118 |
+
'Category': { bg: 'bg-blue-500', border: 'border-blue-700', text: 'text-blue-50', light: 'bg-blue-500', icon: 'text-blue-200', badge: 'bg-blue-700 text-blue-100', node: 'bg-blue-500 text-white border-blue-700 shadow-blue-500/30' },
|
| 119 |
+
'Veda': { bg: 'bg-amber-100', border: 'border-amber-400', text: 'text-amber-900', light: 'bg-amber-50', icon: 'text-amber-600', badge: 'bg-amber-200 text-amber-800', node: 'bg-amber-100 text-amber-900 border-amber-400 shadow-amber-900/10' },
|
| 120 |
+
'Kanda': { bg: 'bg-orange-100', border: 'border-orange-400', text: 'text-orange-900', light: 'bg-orange-50', icon: 'text-orange-600', badge: 'bg-orange-200 text-orange-800', node: 'bg-orange-100 text-orange-900 border-orange-400 shadow-orange-900/10' },
|
| 121 |
+
'Upanishad': { bg: 'bg-cyan-100', border: 'border-cyan-400', text: 'text-cyan-900', light: 'bg-cyan-50', icon: 'text-cyan-600', badge: 'bg-cyan-200 text-cyan-800', node: 'bg-cyan-100 text-cyan-900 border-cyan-400 shadow-cyan-900/10' },
|
| 122 |
+
'Itihasa': { bg: 'bg-rose-100', border: 'border-rose-400', text: 'text-rose-900', light: 'bg-rose-50', icon: 'text-rose-600', badge: 'bg-rose-200 text-rose-800', node: 'bg-rose-100 text-rose-900 border-rose-400 shadow-rose-900/10' },
|
| 123 |
+
'Purana': { bg: 'bg-purple-100', border: 'border-purple-400', text: 'text-purple-900', light: 'bg-purple-50', icon: 'text-purple-600', badge: 'bg-purple-200 text-purple-800', node: 'bg-purple-100 text-purple-900 border-purple-400 shadow-purple-900/10' },
|
| 124 |
+
'Darshana': { bg: 'bg-emerald-100', border: 'border-emerald-400', text: 'text-emerald-900', light: 'bg-emerald-50', icon: 'text-emerald-600', badge: 'bg-emerald-200 text-emerald-800', node: 'bg-emerald-100 text-emerald-900 border-emerald-400 shadow-emerald-900/10' },
|
| 125 |
+
'Dharmashastra': { bg: 'bg-slate-100', border: 'border-slate-400', text: 'text-slate-900', light: 'bg-slate-50', icon: 'text-slate-600', badge: 'bg-slate-200 text-slate-800', node: 'bg-slate-100 text-slate-900 border-slate-400 shadow-slate-900/10' },
|
| 126 |
+
'Vedanga': { bg: 'bg-lime-100', border: 'border-lime-400', text: 'text-lime-900', light: 'bg-lime-50', icon: 'text-lime-600', badge: 'bg-lime-200 text-lime-800', node: 'bg-lime-100 text-lime-900 border-lime-400 shadow-lime-900/10' },
|
| 127 |
+
'Agama': { bg: 'bg-fuchsia-100', border: 'border-fuchsia-400', text: 'text-fuchsia-900', light: 'bg-fuchsia-50', icon: 'text-fuchsia-600', badge: 'bg-fuchsia-200 text-fuchsia-800', node: 'bg-fuchsia-100 text-fuchsia-900 border-fuchsia-400 shadow-fuchsia-900/10' },
|
| 128 |
+
'Upaveda': { bg: 'bg-sky-100', border: 'border-sky-400', text: 'text-sky-900', light: 'bg-sky-50', icon: 'text-sky-600', badge: 'bg-sky-200 text-sky-800', node: 'bg-sky-100 text-sky-900 border-sky-400 shadow-sky-900/10' },
|
| 129 |
+
};
|
| 130 |
+
|
| 131 |
+
// Wire colors mapped directly to target node categories
|
| 132 |
+
const WIRE_COLORS = {
|
| 133 |
+
'Classification': '#8b5cf6', 'Veda': '#f59e0b', 'Kanda': '#f97316',
|
| 134 |
+
'Upanishad': '#06b6d4', 'Category': '#3b82f6', 'Dharmashastra': '#64748b',
|
| 135 |
+
'Itihasa': '#f43f5e', 'Purana': '#a855f7', 'Vedanga': '#84cc16',
|
| 136 |
+
'Agama': '#d946ef', 'Darshana': '#10b981', 'Upaveda': '#0ea5e9',
|
| 137 |
+
};
|
| 138 |
+
|
| 139 |
+
const DEFAULT_COLOR = { bg: 'bg-gray-100', border: 'border-gray-400', text: 'text-gray-900', light: 'bg-gray-50', icon: 'text-gray-600', badge: 'bg-gray-200 text-gray-800', node: 'bg-gray-100 text-gray-900 border-gray-400' };
|
| 140 |
+
|
| 141 |
+
export default function App() {
|
| 142 |
+
const [viewMode, setViewMode] = useState('grid'); // 'grid' | 'mindmap'
|
| 143 |
+
const [searchQuery, setSearchQuery] = useState('');
|
| 144 |
+
const [selectedCategory, setSelectedCategory] = useState('All');
|
| 145 |
+
const [activeScriptureId, setActiveScriptureId] = useState(null);
|
| 146 |
+
|
| 147 |
+
// Filter Categories out of general views if they are structural nodes
|
| 148 |
+
const displayableScriptures = SCRIPTURES.filter(s => !['Root', 'Classification', 'Category'].includes(s.category));
|
| 149 |
+
|
| 150 |
+
// Extract unique filterable categories
|
| 151 |
+
const filterCategories = ['All', ...Array.from(new Set(displayableScriptures.map(s => s.category)))];
|
| 152 |
+
|
| 153 |
+
// Grid Filter logic
|
| 154 |
+
const filteredScriptures = useMemo(() => {
|
| 155 |
+
return displayableScriptures.filter(scripture => {
|
| 156 |
+
const matchesSearch = scripture.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
| 157 |
+
scripture.writer.toLowerCase().includes(searchQuery.toLowerCase());
|
| 158 |
+
const matchesCategory = selectedCategory === 'All' || scripture.category === selectedCategory;
|
| 159 |
+
return matchesSearch && matchesCategory;
|
| 160 |
+
});
|
| 161 |
+
}, [searchQuery, selectedCategory]);
|
| 162 |
+
|
| 163 |
+
const activeScripture = SCRIPTURES.find(s => s.id === activeScriptureId);
|
| 164 |
+
const getScriptureById = (id) => SCRIPTURES.find(s => s.id === id);
|
| 165 |
+
|
| 166 |
+
// Global Key Shortcut for toggling view
|
| 167 |
+
useEffect(() => {
|
| 168 |
+
const handleKeyDown = (e) => {
|
| 169 |
+
// Ignore if typing in an input
|
| 170 |
+
if (e.target.tagName.toLowerCase() === 'input') return;
|
| 171 |
+
|
| 172 |
+
if (e.key === 'z' || e.key === 'Z') {
|
| 173 |
+
setViewMode(prev => prev === 'grid' ? 'mindmap' : 'grid');
|
| 174 |
+
}
|
| 175 |
+
};
|
| 176 |
+
window.addEventListener('keydown', handleKeyDown);
|
| 177 |
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
| 178 |
+
}, []);
|
| 179 |
+
|
| 180 |
+
return (
|
| 181 |
+
<div className={`min-h-screen bg-stone-50 font-sans text-stone-900 selection:bg-orange-200 flex flex-col ${viewMode === 'mindmap' ? 'overflow-hidden' : ''}`}>
|
| 182 |
+
|
| 183 |
+
{/* HEADER */}
|
| 184 |
+
<header className="bg-gradient-to-r from-orange-600 via-red-500 to-amber-500 text-white shadow-md z-20 flex-shrink-0 relative">
|
| 185 |
+
<div className="max-w-[1400px] mx-auto px-4 py-4 md:py-6">
|
| 186 |
+
<div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
|
| 187 |
+
<div className="flex items-center gap-3">
|
| 188 |
+
<div className="p-2 bg-white/20 rounded-full backdrop-blur-sm">
|
| 189 |
+
<Library size={28} className="text-white" />
|
| 190 |
+
</div>
|
| 191 |
+
<div>
|
| 192 |
+
<h1 className="text-xl md:text-2xl font-bold tracking-tight leading-tight">Ancient Indian Scriptures</h1>
|
| 193 |
+
<p className="text-white/80 text-xs md:text-sm font-medium">Explore the interconnected wisdom of millennia</p>
|
| 194 |
+
</div>
|
| 195 |
+
</div>
|
| 196 |
+
|
| 197 |
+
<div className="flex items-center gap-3 w-full md:w-auto">
|
| 198 |
+
{viewMode === 'grid' && (
|
| 199 |
+
<div className="relative flex-grow md:w-64 lg:w-72">
|
| 200 |
+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-white/60" size={16} />
|
| 201 |
+
<input
|
| 202 |
+
type="text"
|
| 203 |
+
placeholder="Search text or author..."
|
| 204 |
+
value={searchQuery}
|
| 205 |
+
onChange={(e) => setSearchQuery(e.target.value)}
|
| 206 |
+
className="w-full pl-9 pr-4 py-2 text-sm rounded-full bg-white/10 border border-white/20 text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-white/50 backdrop-blur-sm transition-all"
|
| 207 |
+
/>
|
| 208 |
+
</div>
|
| 209 |
+
)}
|
| 210 |
+
|
| 211 |
+
<button
|
| 212 |
+
onClick={() => setViewMode(v => v === 'grid' ? 'mindmap' : 'grid')}
|
| 213 |
+
className="flex items-center gap-2 px-4 py-2 bg-white/10 hover:bg-white/20 border border-white/30 rounded-full transition-all text-sm font-semibold whitespace-nowrap"
|
| 214 |
+
title="Shortcut: Press 'Z'"
|
| 215 |
+
>
|
| 216 |
+
{viewMode === 'grid' ? <Network size={16} /> : <LayoutGrid size={16} />}
|
| 217 |
+
<span className="hidden sm:inline">{viewMode === 'grid' ? 'Flowchart View' : 'Grid View'}</span>
|
| 218 |
+
<kbd className="hidden sm:inline ml-1 bg-white/20 px-1.5 py-0.5 rounded text-[10px]">Z</kbd>
|
| 219 |
+
</button>
|
| 220 |
+
</div>
|
| 221 |
+
</div>
|
| 222 |
+
</div>
|
| 223 |
+
</header>
|
| 224 |
+
|
| 225 |
+
{/* DYNAMIC MAIN CONTENT AREA */}
|
| 226 |
+
<div className="flex-grow relative flex flex-col">
|
| 227 |
+
{viewMode === 'grid' ? (
|
| 228 |
+
<main className="max-w-[1400px] mx-auto px-4 py-8 w-full">
|
| 229 |
+
{/* FILTER BAR */}
|
| 230 |
+
<div className="flex flex-wrap gap-2 mb-8 justify-center">
|
| 231 |
+
{filterCategories.map(cat => {
|
| 232 |
+
const isSelected = selectedCategory === cat;
|
| 233 |
+
const colors = cat === 'All' ? { badge: 'bg-stone-200 text-stone-800 border-stone-300' } : (CATEGORY_COLORS[cat] || DEFAULT_COLOR);
|
| 234 |
+
|
| 235 |
+
return (
|
| 236 |
+
<button
|
| 237 |
+
key={cat}
|
| 238 |
+
onClick={() => setSelectedCategory(cat)}
|
| 239 |
+
className={`px-3 py-1.5 rounded-full text-xs sm:text-sm font-semibold transition-all border ${
|
| 240 |
+
isSelected
|
| 241 |
+
? `ring-2 ring-offset-2 ring-orange-400 shadow-sm ${colors.badge}`
|
| 242 |
+
: 'bg-white border-stone-200 text-stone-600 hover:bg-stone-100'
|
| 243 |
+
}`}
|
| 244 |
+
>
|
| 245 |
+
{cat}
|
| 246 |
+
</button>
|
| 247 |
+
)
|
| 248 |
+
})}
|
| 249 |
+
</div>
|
| 250 |
+
|
| 251 |
+
{/* SCRIPTURES GRID */}
|
| 252 |
+
{filteredScriptures.length > 0 ? (
|
| 253 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
|
| 254 |
+
{filteredScriptures.map((scripture) => {
|
| 255 |
+
const theme = CATEGORY_COLORS[scripture.category] || DEFAULT_COLOR;
|
| 256 |
+
|
| 257 |
+
return (
|
| 258 |
+
<div
|
| 259 |
+
key={scripture.id}
|
| 260 |
+
onClick={() => setActiveScriptureId(scripture.id)}
|
| 261 |
+
className={`relative group cursor-pointer overflow-hidden rounded-2xl border-2 ${theme.border} ${theme.light} hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex flex-col h-full`}
|
| 262 |
+
>
|
| 263 |
+
<div className={`p-5 flex-grow flex flex-col`}>
|
| 264 |
+
<div className="flex justify-between items-start mb-3">
|
| 265 |
+
<span className={`text-[10px] font-bold px-2 py-0.5 rounded-full uppercase tracking-wider ${theme.badge}`}>
|
| 266 |
+
{scripture.category}
|
| 267 |
+
</span>
|
| 268 |
+
<BookOpen size={16} className={`${theme.icon} opacity-50 group-hover:opacity-100 transition-opacity`} />
|
| 269 |
+
</div>
|
| 270 |
+
|
| 271 |
+
<h2 className={`text-xl font-extrabold mb-2 ${theme.text}`}>
|
| 272 |
+
{scripture.name}
|
| 273 |
+
</h2>
|
| 274 |
+
|
| 275 |
+
<div className="space-y-1.5 mb-3 flex-grow">
|
| 276 |
+
<div className="flex items-center gap-2 text-xs text-stone-600">
|
| 277 |
+
<Clock size={12} className={theme.icon} />
|
| 278 |
+
<span>{scripture.timePeriod}</span>
|
| 279 |
+
</div>
|
| 280 |
+
<div className="flex items-center gap-2 text-xs text-stone-600">
|
| 281 |
+
<Feather size={12} className={theme.icon} />
|
| 282 |
+
<span className="truncate">{scripture.writer}</span>
|
| 283 |
+
</div>
|
| 284 |
+
</div>
|
| 285 |
+
|
| 286 |
+
<p className="text-xs sm:text-sm text-stone-700 line-clamp-3 leading-relaxed mb-4">
|
| 287 |
+
{scripture.description}
|
| 288 |
+
</p>
|
| 289 |
+
|
| 290 |
+
<div className="mt-auto pt-3 border-t border-black/5 flex items-center justify-between">
|
| 291 |
+
<div className="flex items-center gap-1 text-[10px] sm:text-xs font-semibold text-stone-500">
|
| 292 |
+
<LinkIcon size={10} />
|
| 293 |
+
<span>{scripture.relatedTo ? scripture.relatedTo.length : 0} Links</span>
|
| 294 |
+
</div>
|
| 295 |
+
<span className={`text-xs font-bold flex items-center gap-1 ${theme.icon} group-hover:translate-x-1 transition-transform`}>
|
| 296 |
+
View <Sparkles size={12} />
|
| 297 |
+
</span>
|
| 298 |
+
</div>
|
| 299 |
+
</div>
|
| 300 |
+
</div>
|
| 301 |
+
);
|
| 302 |
+
})}
|
| 303 |
+
</div>
|
| 304 |
+
) : (
|
| 305 |
+
<div className="text-center py-20">
|
| 306 |
+
<ScrollText size={48} className="mx-auto text-stone-300 mb-4" />
|
| 307 |
+
<h3 className="text-xl font-bold text-stone-500">No scriptures found matching your search.</h3>
|
| 308 |
+
<button
|
| 309 |
+
onClick={() => {setSearchQuery(''); setSelectedCategory('All');}}
|
| 310 |
+
className="mt-4 px-6 py-2 bg-orange-100 text-orange-700 rounded-full font-medium hover:bg-orange-200 transition-colors"
|
| 311 |
+
>
|
| 312 |
+
Clear Filters
|
| 313 |
+
</button>
|
| 314 |
+
</div>
|
| 315 |
+
)}
|
| 316 |
+
</main>
|
| 317 |
+
) : (
|
| 318 |
+
<MindMapView onNodeClick={setActiveScriptureId} />
|
| 319 |
+
)}
|
| 320 |
+
</div>
|
| 321 |
+
|
| 322 |
+
{/* MODAL - SCRIPTURE DETAILS */}
|
| 323 |
+
{activeScripture && (
|
| 324 |
+
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
| 325 |
+
<div
|
| 326 |
+
className="absolute inset-0 bg-stone-900/60 backdrop-blur-sm transition-opacity"
|
| 327 |
+
onClick={() => setActiveScriptureId(null)}
|
| 328 |
+
></div>
|
| 329 |
+
|
| 330 |
+
<div className="relative w-full max-w-2xl bg-white rounded-3xl shadow-2xl overflow-hidden flex flex-col max-h-[90vh] animate-in fade-in zoom-in-95 duration-200">
|
| 331 |
+
{(() => {
|
| 332 |
+
const theme = CATEGORY_COLORS[activeScripture.category] || DEFAULT_COLOR;
|
| 333 |
+
const isStructural = ['Root', 'Classification', 'Category'].includes(activeScripture.category);
|
| 334 |
+
return (
|
| 335 |
+
<>
|
| 336 |
+
<div className={`p-6 sm:p-8 ${theme.bg} border-b ${theme.border} relative`}>
|
| 337 |
+
<button
|
| 338 |
+
onClick={() => setActiveScriptureId(null)}
|
| 339 |
+
className="absolute top-4 right-4 p-2 bg-white/50 hover:bg-white rounded-full transition-colors z-10"
|
| 340 |
+
>
|
| 341 |
+
<X size={20} className={theme.text} />
|
| 342 |
+
</button>
|
| 343 |
+
|
| 344 |
+
<span className={`inline-block text-[10px] sm:text-xs font-bold px-3 py-1 rounded-full uppercase tracking-wider mb-3 bg-white/60 ${theme.text}`}>
|
| 345 |
+
{activeScripture.category}
|
| 346 |
+
</span>
|
| 347 |
+
|
| 348 |
+
<h2 className={`text-2xl sm:text-4xl font-extrabold mb-4 ${theme.text}`}>
|
| 349 |
+
{activeScripture.name}
|
| 350 |
+
</h2>
|
| 351 |
+
|
| 352 |
+
{!isStructural && (
|
| 353 |
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
| 354 |
+
<div className="flex items-center gap-3 bg-white/40 px-4 py-2 rounded-xl backdrop-blur-sm">
|
| 355 |
+
<Clock size={16} className={theme.icon} />
|
| 356 |
+
<div>
|
| 357 |
+
<p className="text-[10px] text-black/50 font-bold uppercase">Time Period</p>
|
| 358 |
+
<p className={`text-sm font-semibold ${theme.text}`}>{activeScripture.timePeriod}</p>
|
| 359 |
+
</div>
|
| 360 |
+
</div>
|
| 361 |
+
<div className="flex items-center gap-3 bg-white/40 px-4 py-2 rounded-xl backdrop-blur-sm">
|
| 362 |
+
<User size={16} className={theme.icon} />
|
| 363 |
+
<div>
|
| 364 |
+
<p className="text-[10px] text-black/50 font-bold uppercase">Authorship</p>
|
| 365 |
+
<p className={`text-sm font-semibold ${theme.text}`}>{activeScripture.writer}</p>
|
| 366 |
+
</div>
|
| 367 |
+
</div>
|
| 368 |
+
</div>
|
| 369 |
+
)}
|
| 370 |
+
</div>
|
| 371 |
+
|
| 372 |
+
<div className="p-6 sm:p-8 overflow-y-auto">
|
| 373 |
+
<div className="mb-6">
|
| 374 |
+
<h3 className="text-base sm:text-lg font-bold text-stone-800 flex items-center gap-2 mb-2">
|
| 375 |
+
<Info size={18} className="text-orange-500" />
|
| 376 |
+
Overview
|
| 377 |
+
</h3>
|
| 378 |
+
<p className="text-sm sm:text-base text-stone-600 leading-relaxed">
|
| 379 |
+
{activeScripture.description}
|
| 380 |
+
</p>
|
| 381 |
+
</div>
|
| 382 |
+
|
| 383 |
+
{/* Hierarchy Relationships (Parent/Children) */}
|
| 384 |
+
<div className="mb-6">
|
| 385 |
+
{activeScripture.parentId && (
|
| 386 |
+
<div className="mb-4">
|
| 387 |
+
<h4 className="text-xs font-bold text-stone-400 uppercase mb-2">Belongs To</h4>
|
| 388 |
+
<RelatedButton id={activeScripture.parentId} onClick={setActiveScriptureId} />
|
| 389 |
+
</div>
|
| 390 |
+
)}
|
| 391 |
+
|
| 392 |
+
{SCRIPTURES.filter(s => s.parentId === activeScripture.id).length > 0 && (
|
| 393 |
+
<div>
|
| 394 |
+
<h4 className="text-xs font-bold text-stone-400 uppercase mb-2">Contains</h4>
|
| 395 |
+
<div className="flex flex-wrap gap-2">
|
| 396 |
+
{SCRIPTURES.filter(s => s.parentId === activeScripture.id).map(child => (
|
| 397 |
+
<RelatedButton key={child.id} id={child.id} onClick={setActiveScriptureId} />
|
| 398 |
+
))}
|
| 399 |
+
</div>
|
| 400 |
+
</div>
|
| 401 |
+
)}
|
| 402 |
+
</div>
|
| 403 |
+
|
| 404 |
+
{/* Conceptual Relationships */}
|
| 405 |
+
{activeScripture.relatedTo && activeScripture.relatedTo.length > 0 && (
|
| 406 |
+
<div className="border-t border-stone-100 pt-6">
|
| 407 |
+
<h3 className="text-base sm:text-lg font-bold text-stone-800 flex items-center gap-2 mb-4">
|
| 408 |
+
<LinkIcon size={18} className="text-orange-500" />
|
| 409 |
+
Thematically Related
|
| 410 |
+
</h3>
|
| 411 |
+
<div className="flex flex-wrap gap-2">
|
| 412 |
+
{activeScripture.relatedTo.map(relatedId => (
|
| 413 |
+
<RelatedButton key={relatedId} id={relatedId} onClick={setActiveScriptureId} />
|
| 414 |
+
))}
|
| 415 |
+
</div>
|
| 416 |
+
</div>
|
| 417 |
+
)}
|
| 418 |
+
</div>
|
| 419 |
+
</>
|
| 420 |
+
);
|
| 421 |
+
})()}
|
| 422 |
+
</div>
|
| 423 |
+
</div>
|
| 424 |
+
)}
|
| 425 |
+
</div>
|
| 426 |
+
);
|
| 427 |
+
}
|
| 428 |
+
|
| 429 |
+
// Helper component for related buttons in modal
|
| 430 |
+
function RelatedButton({ id, onClick }) {
|
| 431 |
+
const item = SCRIPTURES.find(s => s.id === id);
|
| 432 |
+
if (!item) return null;
|
| 433 |
+
const theme = CATEGORY_COLORS[item.category] || DEFAULT_COLOR;
|
| 434 |
+
|
| 435 |
+
return (
|
| 436 |
+
<button
|
| 437 |
+
onClick={() => onClick(item.id)}
|
| 438 |
+
className={`flex items-center gap-2 px-3 py-1.5 rounded-lg border ${theme.border} ${theme.light} hover:shadow-md hover:-translate-y-0.5 transition-all group text-left`}
|
| 439 |
+
>
|
| 440 |
+
<BookOpen size={12} className={theme.icon} />
|
| 441 |
+
<div>
|
| 442 |
+
<p className={`font-bold text-xs ${theme.text} group-hover:underline decoration-2 underline-offset-2`}>
|
| 443 |
+
{item.name}
|
| 444 |
+
</p>
|
| 445 |
+
</div>
|
| 446 |
+
</button>
|
| 447 |
+
);
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
// --- DRAGGABLE INFINITE CANVAS COMPONENT ---
|
| 451 |
+
function MindMapView({ onNodeClick }) {
|
| 452 |
+
const containerRef = useRef(null);
|
| 453 |
+
const [pan, setPan] = useState({ x: 0, y: 0 }); // Center by default below
|
| 454 |
+
const [zoom, setZoom] = useState(0.5); // Started zoomed out slightly more for the massive canvas
|
| 455 |
+
const [isDragging, setIsDragging] = useState(false);
|
| 456 |
+
const [startPan, setStartPan] = useState({ x: 0, y: 0 });
|
| 457 |
+
|
| 458 |
+
// Initialize center
|
| 459 |
+
useEffect(() => {
|
| 460 |
+
if (containerRef.current) {
|
| 461 |
+
const rect = containerRef.current.getBoundingClientRect();
|
| 462 |
+
setPan({ x: rect.width / 2, y: rect.height / 4 }); // Start higher up to show root
|
| 463 |
+
}
|
| 464 |
+
}, []);
|
| 465 |
+
|
| 466 |
+
const handlePointerDown = (e) => {
|
| 467 |
+
// Only pan if we click the background, not the nodes
|
| 468 |
+
if (e.target.closest('.mindmap-node')) return;
|
| 469 |
+
setIsDragging(true);
|
| 470 |
+
setStartPan({ x: e.clientX - pan.x, y: e.clientY - pan.y });
|
| 471 |
+
e.target.setPointerCapture(e.pointerId);
|
| 472 |
+
};
|
| 473 |
+
|
| 474 |
+
const handlePointerMove = (e) => {
|
| 475 |
+
if (!isDragging) return;
|
| 476 |
+
setPan({
|
| 477 |
+
x: e.clientX - startPan.x,
|
| 478 |
+
y: e.clientY - startPan.y,
|
| 479 |
+
});
|
| 480 |
+
};
|
| 481 |
+
|
| 482 |
+
const handlePointerUp = (e) => {
|
| 483 |
+
setIsDragging(false);
|
| 484 |
+
e.target.releasePointerCapture(e.pointerId);
|
| 485 |
+
};
|
| 486 |
+
|
| 487 |
+
const handleWheel = (e) => {
|
| 488 |
+
// Zoom around center of screen for simplicity
|
| 489 |
+
const zoomFactor = -e.deltaY * 0.001;
|
| 490 |
+
setZoom(z => Math.min(Math.max(0.1, z + zoomFactor), 2.5));
|
| 491 |
+
};
|
| 492 |
+
|
| 493 |
+
return (
|
| 494 |
+
<div
|
| 495 |
+
ref={containerRef}
|
| 496 |
+
className="absolute inset-0 bg-[#f4f0ec] overflow-hidden cursor-grab active:cursor-grabbing touch-none"
|
| 497 |
+
style={{ backgroundImage: 'radial-gradient(#cbd5e1 1px, transparent 1px)', backgroundSize: '40px 40px', backgroundPosition: `${pan.x}px ${pan.y}px` }}
|
| 498 |
+
onPointerDown={handlePointerDown}
|
| 499 |
+
onPointerMove={handlePointerMove}
|
| 500 |
+
onPointerUp={handlePointerUp}
|
| 501 |
+
onPointerCancel={handlePointerUp}
|
| 502 |
+
onWheel={handleWheel}
|
| 503 |
+
>
|
| 504 |
+
<div className="absolute top-4 left-4 z-10 flex flex-col gap-2 bg-white/80 p-3 rounded-xl shadow-sm backdrop-blur-sm border border-stone-200">
|
| 505 |
+
<div className="flex items-center gap-2 text-xs font-semibold text-stone-600">
|
| 506 |
+
<Move size={14} /> Drag canvas to pan
|
| 507 |
+
</div>
|
| 508 |
+
<div className="flex items-center gap-2 text-xs font-semibold text-stone-600">
|
| 509 |
+
<Search size={14} /> Scroll to zoom ({Math.round(zoom * 100)}%)
|
| 510 |
+
</div>
|
| 511 |
+
</div>
|
| 512 |
+
|
| 513 |
+
{/* Transforms the entire map coordinate space */}
|
| 514 |
+
<div
|
| 515 |
+
className="absolute origin-top-left will-change-transform"
|
| 516 |
+
style={{ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})` }}
|
| 517 |
+
>
|
| 518 |
+
{/* SVG layer for drawing hierarchical colored connections */}
|
| 519 |
+
<svg className="absolute inset-0 overflow-visible pointer-events-none" style={{ width: 1, height: 1 }}>
|
| 520 |
+
{SCRIPTURES.map(node => {
|
| 521 |
+
if (!node.parentId) return null;
|
| 522 |
+
const parent = SCRIPTURES.find(p => p.id === node.parentId);
|
| 523 |
+
if (!parent) return null;
|
| 524 |
+
|
| 525 |
+
// Calculate entry/exit points for a top-down tree aesthetic
|
| 526 |
+
const startX = parent.x;
|
| 527 |
+
const startY = parent.y + 20; // Bottom of parent node approx
|
| 528 |
+
const endX = node.x;
|
| 529 |
+
const endY = node.y - 20; // Top of child node approx
|
| 530 |
+
|
| 531 |
+
// Curved vertical path for sleek organic look
|
| 532 |
+
const pathData = `M ${startX} ${startY} C ${startX} ${startY + Math.abs(endY - startY)/2}, ${endX} ${startY + Math.abs(endY - startY)/2}, ${endX} ${endY}`;
|
| 533 |
+
|
| 534 |
+
// Map the wire color to the child node's category
|
| 535 |
+
const strokeColor = WIRE_COLORS[node.category] || '#94a3b8';
|
| 536 |
+
const isMainBranch = parent.id === 'root' || parent.id === 'shruti' || parent.id === 'smriti';
|
| 537 |
+
|
| 538 |
+
return (
|
| 539 |
+
<path
|
| 540 |
+
key={`edge-${node.id}`}
|
| 541 |
+
d={pathData}
|
| 542 |
+
fill="none"
|
| 543 |
+
stroke={strokeColor}
|
| 544 |
+
strokeWidth={isMainBranch ? "6" : "3"}
|
| 545 |
+
strokeOpacity={0.7}
|
| 546 |
+
strokeLinecap="round"
|
| 547 |
+
className="transition-all duration-500 drop-shadow-sm"
|
| 548 |
+
/>
|
| 549 |
+
);
|
| 550 |
+
})}
|
| 551 |
+
</svg>
|
| 552 |
+
|
| 553 |
+
{/* Nodes Layer */}
|
| 554 |
+
{SCRIPTURES.map(node => {
|
| 555 |
+
const theme = CATEGORY_COLORS[node.category] || DEFAULT_COLOR;
|
| 556 |
+
const isStructural = ['Root', 'Classification', 'Category'].includes(node.category);
|
| 557 |
+
|
| 558 |
+
return (
|
| 559 |
+
<div
|
| 560 |
+
key={node.id}
|
| 561 |
+
className={`mindmap-node absolute transform -translate-x-1/2 -translate-y-1/2 cursor-pointer transition-transform hover:scale-110 active:scale-95 ${
|
| 562 |
+
isStructural ? 'z-20' : 'z-10'
|
| 563 |
+
}`}
|
| 564 |
+
style={{ left: node.x, top: node.y }}
|
| 565 |
+
onClick={(e) => { e.stopPropagation(); onNodeClick(node.id); }}
|
| 566 |
+
>
|
| 567 |
+
<div className={`
|
| 568 |
+
${isStructural ? 'px-6 py-3 font-bold text-lg rounded-xl border-2' : 'px-4 py-2 font-semibold text-sm rounded-lg border'}
|
| 569 |
+
shadow-sm backdrop-blur-sm whitespace-nowrap text-center
|
| 570 |
+
${theme.node || `${theme.bg} ${theme.text} ${theme.border}`}
|
| 571 |
+
`}>
|
| 572 |
+
{node.name}
|
| 573 |
+
{!isStructural && (
|
| 574 |
+
<div className={`text-[10px] mt-1 opacity-70`}>{node.category}</div>
|
| 575 |
+
)}
|
| 576 |
+
</div>
|
| 577 |
+
</div>
|
| 578 |
+
);
|
| 579 |
+
})}
|
| 580 |
+
</div>
|
| 581 |
+
</div>
|
| 582 |
+
);
|
| 583 |
+
}
|