Vatsal12345678 commited on
Commit
da1a664
·
verified ·
1 Parent(s): bfdd032

S. No. Software Date of Invoice Cost (Including Tax) Year

Browse files

1 CSI [Etabs, SAFE, SAP2000] July 9, 2020 SGD 12,176.60 July 9, 2020
2 Plaxis September 1, 2020 SGD 5,361.00 September 1, 2020
3 Tekla December 1, 2020 SGD 13,503.40 December 1, 2020
4 CSI [Etabs, SAFE, SAP2000] July 9, 2021 SGD 11,877.00 July 9, 2021
5 Plaxis September 1, 2021 SGD 5,391.00 September 1, 2021
6 Tekla December 1, 2021 SGD 6,868.60 December 1, 2021
7 CSI [Etabs, SAFE, SAP2000] August 10, 2022 SGD 13,482.00 August 10, 2022
8 Plaxis September 5, 2022 SGD 5,796.00 September 5, 2022
9 Tekla October 18, 2022 SGD 7,130.37 December 1, 2022
10 CSI [Etabs, SAFE, SAP2000] July 4, 2023 SGD 11,664.00 July 4, 2023
11 Plaxis September 21, 2023 SGD 6,201.00 September 5, 2023
12 Tekla October 18, 2023 SGD 7,792.20 December 1, 2023
13 CSI [Etabs, SAFE, SAP2000] July 4, 2024 SGD 11,336.00 July 4, 2024
14 Plaxis September 18, 2024 SGD 7,003.40 18/9/2024
15 Tekla October 10, 2024 SGD 8,316.00 10/10/2024
16 CSI [Etabs, SAFE, SAP2000] May 22, 2025 SGD 11,336.00 May 22, 2025
17 Unreal Engine 6-Sept-24 SGD 2,727.18 6-Sept-24
18 Plaxis September 18, 2025 SGD 7,752.84 18/9/2025

Files changed (6) hide show
  1. README.md +8 -5
  2. components/footer.js +34 -0
  3. components/header.js +37 -0
  4. index.html +82 -19
  5. script.js +139 -0
  6. style.css +24 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Software Expense Tracker
3
- emoji: 💻
4
- colorFrom: blue
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: Software Expense Tracker 📊
3
+ colorFrom: red
4
+ colorTo: purple
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ footer {
7
+ background-color: #1E293B;
8
+ }
9
+ </style>
10
+ <footer class="py-6">
11
+ <div class="container mx-auto px-4">
12
+ <div class="flex flex-col md:flex-row justify-between items-center">
13
+ <div class="text-white mb-4 md:mb-0">
14
+ © ${new Date().getFullYear()} Software Expense Tracker
15
+ </div>
16
+ <div class="flex space-x-4">
17
+ <a href="#" class="text-gray-300 hover:text-white">
18
+ <i data-feather="github"></i>
19
+ </a>
20
+ <a href="#" class="text-gray-300 hover:text-white">
21
+ <i data-feather="twitter"></i>
22
+ </a>
23
+ <a href="#" class="text-gray-300 hover:text-white">
24
+ <i data-feather="linkedin"></i>
25
+ </a>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </footer>
30
+ `;
31
+ }
32
+ }
33
+
34
+ customElements.define('custom-footer', CustomFooter);
components/header.js ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomHeader extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ nav {
7
+ background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
8
+ }
9
+
10
+ .nav-link:hover {
11
+ background-color: rgba(255, 255, 255, 0.1);
12
+ }
13
+ </style>
14
+ <nav class="shadow-lg">
15
+ <div class="container mx-auto px-4">
16
+ <div class="flex items-center justify-between h-16">
17
+ <div class="flex items-center">
18
+ <span class="text-white font-bold text-xl flex items-center">
19
+ <i data-feather="dollar-sign" class="mr-2"></i>
20
+ Software Expense Tracker
21
+ </span>
22
+ </div>
23
+ <div class="hidden md:block">
24
+ <div class="ml-10 flex items-baseline space-x-4">
25
+ <a href="#" class="nav-link px-3 py-2 rounded-md text-sm font-medium text-white bg-white bg-opacity-10">Dashboard</a>
26
+ <a href="#" class="nav-link px-3 py-2 rounded-md text-sm font-medium text-white hover:bg-white hover:bg-opacity-10">Reports</a>
27
+ <a href="#" class="nav-link px-3 py-2 rounded-md text-sm font-medium text-white hover:bg-white hover:bg-opacity-10">Settings</a>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </nav>
33
+ `;
34
+ }
35
+ }
36
+
37
+ customElements.define('custom-header', CustomHeader);
index.html CHANGED
@@ -1,19 +1,82 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Software Expense Tracker</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
10
+ <script src="https://unpkg.com/feather-icons"></script>
11
+ <script>
12
+ tailwind.config = {
13
+ theme: {
14
+ extend: {
15
+ colors: {
16
+ primary: '#3B82F6',
17
+ secondary: '#10B981',
18
+ }
19
+ }
20
+ }
21
+ }
22
+ </script>
23
+ </head>
24
+ <body class="bg-gray-50">
25
+ <div class="min-h-screen">
26
+ <custom-header></custom-header>
27
+
28
+ <main class="container mx-auto px-4 py-8">
29
+ <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
30
+ <div class="p-6">
31
+ <h1 class="text-3xl font-bold text-primary mb-4">Software Expense Tracker</h1>
32
+ <p class="text-gray-600 mb-6">Track your software license costs and renewal dates</p>
33
+
34
+ <div class="overflow-x-auto">
35
+ <table class="min-w-full divide-y divide-gray-200">
36
+ <thead class="bg-gray-50">
37
+ <tr>
38
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">No.</th>
39
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Software</th>
40
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date of Invoice</th>
41
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Cost (SGD)</th>
42
+ <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Renewal Date</th>
43
+ </tr>
44
+ </thead>
45
+ <tbody class="bg-white divide-y divide-gray-200" id="expenseTable">
46
+ <!-- Data will be populated by JavaScript -->
47
+ </tbody>
48
+ </table>
49
+ </div>
50
+ </div>
51
+ </div>
52
+
53
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
54
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
55
+ <div class="p-6">
56
+ <h2 class="text-xl font-semibold text-primary mb-4">Annual Spending</h2>
57
+ <canvas id="annualChart" height="300"></canvas>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
62
+ <div class="p-6">
63
+ <h2 class="text-xl font-semibold text-primary mb-4">Software Distribution</h2>
64
+ <canvas id="softwareChart" height="300"></canvas>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </main>
69
+
70
+ <custom-footer></custom-footer>
71
+ </div>
72
+
73
+ <script src="components/header.js"></script>
74
+ <script src="components/footer.js"></script>
75
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
76
+ <script src="script.js"></script>
77
+ <script>
78
+ feather.replace();
79
+ </script>
80
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
81
+ </body>
82
+ </html>
script.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', function() {
2
+ // Expense data
3
+ const expenses = [
4
+ { id: 1, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 9, 2020', cost: 12176.60, renewalDate: 'July 9, 2020' },
5
+ { id: 2, software: 'Plaxis', invoiceDate: 'September 1, 2020', cost: 5361.00, renewalDate: 'September 1, 2020' },
6
+ { id: 3, software: 'Tekla', invoiceDate: 'December 1, 2020', cost: 13503.40, renewalDate: 'December 1, 2020' },
7
+ { id: 4, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 9, 2021', cost: 11877.00, renewalDate: 'July 9, 2021' },
8
+ { id: 5, software: 'Plaxis', invoiceDate: 'September 1, 2021', cost: 5391.00, renewalDate: 'September 1, 2021' },
9
+ { id: 6, software: 'Tekla', invoiceDate: 'December 1, 2021', cost: 6868.60, renewalDate: 'December 1, 2021' },
10
+ { id: 7, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'August 10, 2022', cost: 13482.00, renewalDate: 'August 10, 2022' },
11
+ { id: 8, software: 'Plaxis', invoiceDate: 'September 5, 2022', cost: 5796.00, renewalDate: 'September 5, 2022' },
12
+ { id: 9, software: 'Tekla', invoiceDate: 'October 18, 2022', cost: 7130.37, renewalDate: 'December 1, 2022' },
13
+ { id: 10, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 4, 2023', cost: 11664.00, renewalDate: 'July 4, 2023' },
14
+ { id: 11, software: 'Plaxis', invoiceDate: 'September 21, 2023', cost: 6201.00, renewalDate: 'September 5, 2023' },
15
+ { id: 12, software: 'Tekla', invoiceDate: 'October 18, 2023', cost: 7792.20, renewalDate: 'December 1, 2023' },
16
+ { id: 13, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'July 4, 2024', cost: 11336.00, renewalDate: 'July 4, 2024' },
17
+ { id: 14, software: 'Plaxis', invoiceDate: 'September 18, 2024', cost: 7003.40, renewalDate: '18/9/2024' },
18
+ { id: 15, software: 'Tekla', invoiceDate: 'October 10, 2024', cost: 8316.00, renewalDate: '10/10/2024' },
19
+ { id: 16, software: 'CSI [Etabs, SAFE, SAP2000]', invoiceDate: 'May 22, 2025', cost: 11336.00, renewalDate: 'May 22, 2025' },
20
+ { id: 17, software: 'Unreal Engine', invoiceDate: '6-Sept-24', cost: 2727.18, renewalDate: '6-Sept-24' },
21
+ { id: 18, software: 'Plaxis', invoiceDate: 'September 18, 2025', cost: 7752.84, renewalDate: '18/9/2025' }
22
+ ];
23
+
24
+ // Populate table
25
+ const tableBody = document.getElementById('expenseTable');
26
+ expenses.forEach(expense => {
27
+ const row = document.createElement('tr');
28
+ row.className = 'hover:bg-gray-50 fade-in';
29
+ row.innerHTML = `
30
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${expense.id}</td>
31
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.software}</td>
32
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.invoiceDate}</td>
33
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.cost.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'})}</td>
34
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${expense.renewalDate}</td>
35
+ `;
36
+ tableBody.appendChild(row);
37
+ });
38
+
39
+ // Prepare data for charts
40
+ const years = ['2020', '2021', '2022', '2023', '2024', '2025'];
41
+ const annualCosts = years.map(year => {
42
+ return expenses
43
+ .filter(expense => expense.renewalDate.includes(year))
44
+ .reduce((sum, expense) => sum + expense.cost, 0);
45
+ });
46
+
47
+ const softwareNames = [...new Set(expenses.map(expense => expense.software))];
48
+ const softwareCosts = softwareNames.map(software => {
49
+ return expenses
50
+ .filter(expense => expense.software === software)
51
+ .reduce((sum, expense) => sum + expense.cost, 0);
52
+ });
53
+
54
+ // Create charts
55
+ createAnnualChart(years, annualCosts);
56
+ createSoftwareChart(softwareNames, softwareCosts);
57
+ });
58
+
59
+ function createAnnualChart(years, costs) {
60
+ const ctx = document.getElementById('annualChart').getContext('2d');
61
+ new Chart(ctx, {
62
+ type: 'bar',
63
+ data: {
64
+ labels: years,
65
+ datasets: [{
66
+ label: 'Annual Software Costs (SGD)',
67
+ data: costs,
68
+ backgroundColor: '#3B82F6',
69
+ borderColor: '#2563EB',
70
+ borderWidth: 1
71
+ }]
72
+ },
73
+ options: {
74
+ responsive: true,
75
+ plugins: {
76
+ legend: {
77
+ position: 'top',
78
+ },
79
+ tooltip: {
80
+ callbacks: {
81
+ label: function(context) {
82
+ return context.parsed.y.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'});
83
+ }
84
+ }
85
+ }
86
+ },
87
+ scales: {
88
+ y: {
89
+ beginAtZero: true,
90
+ ticks: {
91
+ callback: function(value) {
92
+ return value.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'});
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ });
99
+ }
100
+
101
+ function createSoftwareChart(softwareNames, costs) {
102
+ const ctx = document.getElementById('softwareChart').getContext('2d');
103
+ new Chart(ctx, {
104
+ type: 'pie',
105
+ data: {
106
+ labels: softwareNames,
107
+ datasets: [{
108
+ data: costs,
109
+ backgroundColor: [
110
+ '#3B82F6',
111
+ '#10B981',
112
+ '#F59E0B',
113
+ '#EF4444',
114
+ '#8B5CF6'
115
+ ],
116
+ borderWidth: 1
117
+ }]
118
+ },
119
+ options: {
120
+ responsive: true,
121
+ plugins: {
122
+ legend: {
123
+ position: 'right',
124
+ },
125
+ tooltip: {
126
+ callbacks: {
127
+ label: function(context) {
128
+ const label = context.label || '';
129
+ const value = context.raw || 0;
130
+ const total = context.dataset.data.reduce((a, b) => a + b, 0);
131
+ const percentage = Math.round((value / total) * 100);
132
+ return `${label}: ${value.toLocaleString('en-SG', {style: 'currency', currency: 'SGD'})} (${percentage}%)`;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ });
139
+ }
style.css CHANGED
@@ -1,28 +1,34 @@
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
28
  }
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
2
+
3
  body {
4
+ font-family: 'Inter', sans-serif;
5
+ }
6
+
7
+ /* Custom scrollbar */
8
+ ::-webkit-scrollbar {
9
+ width: 8px;
10
+ height: 8px;
11
  }
12
 
13
+ ::-webkit-scrollbar-track {
14
+ background: #f1f1f1;
 
15
  }
16
 
17
+ ::-webkit-scrollbar-thumb {
18
+ background: #888;
19
+ border-radius: 4px;
 
 
20
  }
21
 
22
+ ::-webkit-scrollbar-thumb:hover {
23
+ background: #555;
 
 
 
 
24
  }
25
 
26
+ /* Animation classes */
27
+ .fade-in {
28
+ animation: fadeIn 0.5s ease-in;
29
  }
30
+
31
+ @keyframes fadeIn {
32
+ from { opacity: 0; }
33
+ to { opacity: 1; }
34
+ }