-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
133 lines (124 loc) · 5.3 KB
/
script.js
File metadata and controls
133 lines (124 loc) · 5.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
Vue.createApp({
data() {
return {
// Config
userName: 'nexus122', // Cambiame y la pagina cambiara entera
onlyDemoProyects: true, // ¿Solo proyectos con demo?
orderDateAscendent: true, // ¿Ordenar por fecha ascendente?
isDarkTheme: true,
// Filter Data
searcher: '',
selectedTopics: [],
// Data
githubRepos: [],
isLoading: false,
fetchError: null,
userInfo: {}
}
},
methods: {
async fetchGithubRepos() {
this.isLoading = true;
this.fetchError = null;
const CACHE_KEY = `gh_repos_${this.userName}`;
const CACHE_TTL = 10 * 60 * 1000; // 10 minutes
const cached = JSON.parse(localStorage.getItem(CACHE_KEY) || 'null');
if (cached && Date.now() - cached.ts < CACHE_TTL) {
this.githubRepos = cached.data;
this.isLoading = false;
return;
}
try {
let page = 1;
const perPage = 100;
let allRepos = [];
while (true) {
const result = await fetch(`https://api.github.com/users/${this.userName}/repos?type=all&per_page=${perPage}&page=${page}`);
if (!result.ok) throw new Error(`GitHub API error ${result.status}`);
const repos = await result.json();
allRepos = allRepos.concat(repos);
if (repos.length < perPage) break;
page++;
}
this.githubRepos = allRepos;
localStorage.setItem(CACHE_KEY, JSON.stringify({ ts: Date.now(), data: allRepos }));
} catch (error) {
this.fetchError = error;
} finally {
this.isLoading = false;
}
},
async fetchUserInfo() {
try {
const result = await fetch(`https://api.github.com/users/${this.userName}`);
if (!result.ok) throw new Error(`GitHub API error ${result.status}`);
this.userInfo = await result.json();
} catch (error) {
this.fetchError = error;
}
},
dateClick() {
this.orderDateAscendent = !this.orderDateAscendent;
},
toggleTheme() {
this.isDarkTheme = !this.isDarkTheme;
const theme = this.isDarkTheme ? 'dark' : 'light';
document.documentElement.className = theme;
localStorage.setItem('portfolio-theme', theme);
},
toggleTopic(topic) {
const idx = this.selectedTopics.indexOf(topic);
if (idx > -1) this.selectedTopics.splice(idx, 1);
else this.selectedTopics.push(topic);
}
},
mounted() {
// Sync Vue state with the theme already applied by the inline script
const savedTheme = localStorage.getItem('portfolio-theme');
if (savedTheme) {
this.isDarkTheme = savedTheme === 'dark';
}
this.fetchGithubRepos();
this.fetchUserInfo();
document.title = `${this.userName} — Portfolio`;
},
computed: {
availableTopics() {
const allTopics = this.githubRepos.flatMap(repo => repo.topics || []);
return [...new Set(allTopics)].sort();
},
proyectosFiltrados() {
let filteredProyects = this.githubRepos;
// Arreglar los nombres que tengan guiones (non-mutating: spread into new object)
filteredProyects = filteredProyects.map(proyect => {
let displayName = proyect.name;
if (displayName.includes('-')) displayName = displayName.replaceAll("-", " ");
if (displayName.includes('_')) displayName = displayName.replaceAll("_", " ");
return { ...proyect, name: displayName };
});
if (this.onlyDemoProyects) {
// Cogeremos solo los proyectos que tengan una demo definida
filteredProyects = filteredProyects.filter(repo => repo.homepage);
// Nos ahorramos los proyectos que tienen una url que no cuenta con https ya que nos redirige a nuestra propia pagina.
filteredProyects = filteredProyects.filter(repo => repo.homepage.includes('https'));
}
filteredProyects = filteredProyects.filter(repo => repo.name.toLowerCase().includes(this.searcher.toLowerCase()));
if (this.selectedTopics.length > 0) {
filteredProyects = filteredProyects.filter(repo =>
(repo.topics || []).some(t => this.selectedTopics.includes(t))
);
}
// Ordenar por update date
if(this.orderDateAscendent) {
filteredProyects = filteredProyects.sort((a, b) => {
return new Date(b.updated_at) - new Date(a.updated_at);
});
}else{
filteredProyects = filteredProyects.sort((a, b) => {
return new Date(a.updated_at) - new Date(b.updated_at);
});
}
return filteredProyects;
},
}
}).mount('#app');