5 次程式碼提交

作者 SHA1 備註 提交日期
  Alejandro Soledad 643ccdb383 Adding Capsules List Page and Single Capsule Page. Additionally, made minor text editing. 1 年之前
  Alejandro Soledad 229914a258 Merge branch 'UserStory1' of git.ccom.uprrp.edu:CCOM4030/AlAlRy into UserStory2 2 年之前
  Alex Ortiz 64316173e9 First Modification 2 年之前
  Alex Ortiz b2916b9a1a Added comments and modified a bit the code 2 年之前
  Alex Ortiz 9719acd64b MergeSort function code added 2 年之前

+ 29
- 0
.gitignore 查看文件

@@ -0,0 +1,29 @@
1
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2
+
3
+# dependencies
4
+/node_modules
5
+/.pnp
6
+.pnp.js
7
+
8
+# testing
9
+/coverage
10
+
11
+# production
12
+/build
13
+
14
+# misc
15
+.DS_Store
16
+.env.local
17
+.env.development.local
18
+.env.test.local
19
+.env.production.local
20
+/.vscode/*
21
+!/.vscode/extensions.json
22
+.idea
23
+
24
+npm-debug.log*
25
+yarn-debug.log*
26
+yarn-error.log*
27
+
28
+# Optional eslint cache
29
+.eslintcache

+ 5
- 0
.vscode/extensions.json 查看文件

@@ -0,0 +1,5 @@
1
+{
2
+    "recommendations": [
3
+        "ionic.ionic"
4
+    ]
5
+}

+ 10
- 0
capacitor.config.ts 查看文件

@@ -0,0 +1,10 @@
1
+import { CapacitorConfig } from '@capacitor/cli';
2
+
3
+const config: CapacitorConfig = {
4
+  appId: 'io.ionic.starter',
5
+  appName: 'Ionic-EnciclopediaPR',
6
+  webDir: 'build',
7
+  bundledWebRuntime: false
8
+};
9
+
10
+export default config;

+ 7
- 0
ionic.config.json 查看文件

@@ -0,0 +1,7 @@
1
+{
2
+  "name": "Ionic-EnciclopediaPR",
3
+  "integrations": {
4
+    "capacitor": {}
5
+  },
6
+  "type": "react"
7
+}

+ 16150
- 0
package-lock.json
文件差異過大導致無法顯示
查看文件


+ 72
- 0
package.json 查看文件

@@ -0,0 +1,72 @@
1
+{
2
+  "name": "ionic-enciclopedia-pr",
3
+  "version": "0.0.1",
4
+  "private": true,
5
+  "dependencies": {
6
+    "@capacitor/app": "4.1.1",
7
+    "@capacitor/core": "4.5.0",
8
+    "@capacitor/haptics": "4.1.0",
9
+    "@capacitor/keyboard": "4.1.0",
10
+    "@capacitor/status-bar": "4.1.0",
11
+    "@ionic/react": "^6.0.0",
12
+    "@ionic/react-router": "^6.0.0",
13
+    "@testing-library/jest-dom": "^5.11.9",
14
+    "@testing-library/react": "^13.3.0",
15
+    "@testing-library/user-event": "^12.6.3",
16
+    "@types/jest": "^26.0.20",
17
+    "@types/node": "^12.19.15",
18
+    "@types/react": "^18.0.17",
19
+    "@types/react-dom": "^18.0.6",
20
+    "@types/react-router": "^5.1.11",
21
+    "@types/react-router-dom": "^5.1.7",
22
+    "history": "^4.9.0",
23
+    "ionicons": "^6.0.3",
24
+    "react": "^18.2.0",
25
+    "react-dom": "^18.2.0",
26
+    "react-router": "^5.2.0",
27
+    "react-router-dom": "^5.2.0",
28
+    "react-scripts": "^5.0.1",
29
+    "typescript": "^4.1.3",
30
+    "web-vitals": "^0.2.4",
31
+    "workbox-background-sync": "^5.1.4",
32
+    "workbox-broadcast-update": "^5.1.4",
33
+    "workbox-cacheable-response": "^5.1.4",
34
+    "workbox-core": "^5.1.4",
35
+    "workbox-expiration": "^5.1.4",
36
+    "workbox-google-analytics": "^5.1.4",
37
+    "workbox-navigation-preload": "^5.1.4",
38
+    "workbox-precaching": "^5.1.4",
39
+    "workbox-range-requests": "^5.1.4",
40
+    "workbox-routing": "^5.1.4",
41
+    "workbox-strategies": "^5.1.4",
42
+    "workbox-streams": "^5.1.4"
43
+  },
44
+  "scripts": {
45
+    "start": "react-scripts start",
46
+    "build": "react-scripts build",
47
+    "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'",
48
+    "eject": "react-scripts eject"
49
+  },
50
+  "eslintConfig": {
51
+    "extends": [
52
+      "react-app",
53
+      "react-app/jest"
54
+    ]
55
+  },
56
+  "browserslist": {
57
+    "production": [
58
+      ">0.2%",
59
+      "not dead",
60
+      "not op_mini all"
61
+    ],
62
+    "development": [
63
+      "last 1 chrome version",
64
+      "last 1 firefox version",
65
+      "last 1 safari version"
66
+    ]
67
+  },
68
+  "devDependencies": {
69
+    "@capacitor/cli": "4.5.0"
70
+  },
71
+  "description": "An Ionic project"
72
+}

二進制
public/assets/icon/favicon.png 查看文件


二進制
public/assets/icon/icon.png 查看文件


+ 1
- 0
public/assets/shapes.svg 查看文件

@@ -0,0 +1 @@
1
+<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>

+ 31
- 0
public/index.html 查看文件

@@ -0,0 +1,31 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+  <head>
4
+    <meta charset="utf-8" />
5
+    <title>Ionic App</title>
6
+
7
+    <base href="/" />
8
+
9
+    <meta name="color-scheme" content="light dark" />
10
+    <meta
11
+      name="viewport"
12
+      content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
13
+    />
14
+    <meta name="format-detection" content="telephone=no" />
15
+    <meta name="msapplication-tap-highlight" content="no" />
16
+
17
+    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18
+
19
+    <link rel="shortcut icon" type="image/png" href="%PUBLIC_URL%/assets/icon/favicon.png" />
20
+
21
+    <!-- add to homescreen for ios -->
22
+    <meta name="apple-mobile-web-app-capable" content="yes" />
23
+    <meta name="apple-mobile-web-app-title" content="Ionic App" />
24
+    <meta name="apple-mobile-web-app-status-bar-style" content="black" />
25
+  </head>
26
+
27
+  <body>
28
+    <div id="root"></div>
29
+  </body>
30
+
31
+</html>

+ 21
- 0
public/manifest.json 查看文件

@@ -0,0 +1,21 @@
1
+{
2
+  "short_name": "Ionic App",
3
+  "name": "My Ionic App",
4
+  "icons": [
5
+    {
6
+      "src": "assets/icon/favicon.png",
7
+      "sizes": "64x64 32x32 24x24 16x16",
8
+      "type": "image/x-icon"
9
+    },
10
+    {
11
+      "src": "assets/icon/icon.png",
12
+      "type": "image/png",
13
+      "sizes": "512x512",
14
+      "purpose": "maskable"
15
+    }
16
+  ],
17
+  "start_url": ".",
18
+  "display": "standalone",
19
+  "theme_color": "#ffffff",
20
+  "background_color": "#ffffff"
21
+}

二進制
resources/icon.png 查看文件


二進制
resources/splash.png 查看文件


+ 8
- 0
src/App.test.tsx 查看文件

@@ -0,0 +1,8 @@
1
+import React from 'react';
2
+import { render } from '@testing-library/react';
3
+import App from './App';
4
+
5
+test('renders without crashing', () => {
6
+  const { baseElement } = render(<App />);
7
+  expect(baseElement).toBeDefined();
8
+});

+ 29
- 0
src/App.tsx 查看文件

@@ -0,0 +1,29 @@
1
+import { IonNav, setupIonicReact } from '@ionic/react';
2
+import HomePage from './pages/HomePage';
3
+
4
+/* Core CSS required for Ionic components to work properly */
5
+import '@ionic/react/css/core.css';
6
+
7
+/* Basic CSS for apps built with Ionic */
8
+import '@ionic/react/css/normalize.css';
9
+import '@ionic/react/css/structure.css';
10
+import '@ionic/react/css/typography.css';
11
+
12
+/* Optional CSS utils that can be commented out */
13
+import '@ionic/react/css/padding.css';
14
+import '@ionic/react/css/float-elements.css';
15
+import '@ionic/react/css/text-alignment.css';
16
+import '@ionic/react/css/text-transformation.css';
17
+import '@ionic/react/css/flex-utils.css';
18
+import '@ionic/react/css/display.css';
19
+
20
+/* Theme variables */
21
+import './theme/variables.css';
22
+
23
+setupIonicReact();
24
+
25
+const App: React.FC = () => (
26
+  <IonNav root={() => <HomePage />}></IonNav>
27
+);
28
+
29
+export default App;

二進制
src/assets/BombaPuertorriquena.jpg 查看文件


二進制
src/assets/EnciclopediaPR.png 查看文件


二進制
src/assets/RobertoClemente.jpg 查看文件


+ 24
- 0
src/components/ExploreContainer.css 查看文件

@@ -0,0 +1,24 @@
1
+.container {
2
+  text-align: center;
3
+  position: absolute;
4
+  left: 0;
5
+  right: 0;
6
+  top: 50%;
7
+  transform: translateY(-50%);
8
+}
9
+
10
+.container strong {
11
+  font-size: 20px;
12
+  line-height: 26px;
13
+}
14
+
15
+.container p {
16
+  font-size: 16px;
17
+  line-height: 22px;
18
+  color: #8c8c8c;
19
+  margin: 0;
20
+}
21
+
22
+.container a {
23
+  text-decoration: none;
24
+}

+ 16
- 0
src/components/ExploreContainer.tsx 查看文件

@@ -0,0 +1,16 @@
1
+import './ExploreContainer.css';
2
+
3
+interface ContainerProps {
4
+  name: string;
5
+}
6
+
7
+const ExploreContainer: React.FC<ContainerProps> = ({ name }) => {
8
+  return (
9
+    <div className="container">
10
+      <strong>{name}</strong>
11
+      <p>Explore <a target="_blank" rel="noopener noreferrer" href="https://ionicframework.com/docs/components">UI Components</a></p>
12
+    </div>
13
+  );
14
+};
15
+
16
+export default ExploreContainer;

+ 23
- 0
src/index.tsx 查看文件

@@ -0,0 +1,23 @@
1
+import React from 'react';
2
+import { createRoot } from 'react-dom/client';
3
+import App from './App';
4
+import * as serviceWorkerRegistration from './serviceWorkerRegistration';
5
+import reportWebVitals from './reportWebVitals';
6
+
7
+const container = document.getElementById('root');
8
+const root = createRoot(container!);
9
+root.render(
10
+  <React.StrictMode>
11
+    <App />
12
+  </React.StrictMode>
13
+);
14
+
15
+// If you want your app to work offline and load faster, you can change
16
+// unregister() to register() below. Note this comes with some pitfalls.
17
+// Learn more about service workers: https://cra.link/PWA
18
+serviceWorkerRegistration.unregister();
19
+
20
+// If you want to start measuring performance in your app, pass a function
21
+// to log results (for example: reportWebVitals(console.log))
22
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
23
+reportWebVitals();

+ 0
- 0
src/pages/AboutUs.css 查看文件


+ 46
- 0
src/pages/AboutUs.tsx 查看文件

@@ -0,0 +1,46 @@
1
+import {
2
+  IonImg,
3
+  IonContent,
4
+  IonHeader,
5
+  IonTitle,
6
+  IonPage,
7
+  IonToolbar,
8
+  IonFooter,
9
+  IonNavLink,
10
+  IonTabButton,
11
+  IonIcon
12
+} from '@ionic/react';
13
+import { arrowBack } from 'ionicons/icons';
14
+import React from 'react';
15
+import './AboutUs.css';
16
+import HomePage from './HomePage';
17
+import EnciclopediaPR from '../assets/EnciclopediaPR.png';
18
+
19
+const AboutUs: React.FC = () => {
20
+  return (
21
+    <IonPage>
22
+      <IonHeader>
23
+        <IonToolbar>
24
+          <IonTitle>Más sobre nosotros</IonTitle>
25
+          <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>
26
+        </IonToolbar>
27
+      </IonHeader>
28
+      <IonContent fullscreen className="ion-padding">
29
+        <h1>Enciclopedia PR</h1>
30
+        <h2>Más sobre nosotros:</h2>
31
+        <p>Para más información sobre EnciclopediaPR, visite la página <a {href='https://enciclopediapr.org/'}></a> {enciclopediapr.org} </p>
32
+      </IonContent>
33
+      <IonFooter>
34
+        <IonToolbar>
35
+          <IonNavLink routerDirection="forward" component={() => <HomePage />}>
36
+            <IonTabButton tab="HomePage" href="/HomePage">
37
+              <IonIcon icon={arrowBack} />
38
+            </IonTabButton>
39
+          </IonNavLink>
40
+        </IonToolbar>
41
+      </IonFooter>
42
+    </IonPage>
43
+  );
44
+};
45
+
46
+export default AboutUs;

+ 0
- 0
src/pages/Biography.css 查看文件


+ 50
- 0
src/pages/Biography.tsx 查看文件

@@ -0,0 +1,50 @@
1
+import {
2
+    IonPage,
3
+    IonContent,
4
+    IonHeader,
5
+    IonTitle,
6
+    IonToolbar,
7
+    IonFooter,
8
+    IonNavLink,
9
+    IonTabButton,
10
+    IonIcon,
11
+    IonImg
12
+} from '@ionic/react';
13
+import { arrowBack } from 'ionicons/icons';
14
+import React from 'react';
15
+import './Biography.css';
16
+import ListBiographies from './ListBiographies';
17
+import EnciclopediaPR from '../assets/EnciclopediaPR.png';
18
+import RobertoClemente from '../assets/RobertoClemente.jpg';
19
+
20
+const Biography: React.FC = () => {
21
+    return (
22
+        <IonPage>
23
+            <IonHeader>
24
+                <IonToolbar>
25
+                    <IonTitle>Biografía</IonTitle>
26
+                    <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>
27
+                </IonToolbar>
28
+            </IonHeader>
29
+            <IonContent fullscreen className="ion-padding">
30
+                <IonImg style={{ height: 300, width: 600 }} src={RobertoClemente} alt='Logo'></IonImg>
31
+                <h1>Roberto Clemente</h1>
32
+
33
+                <p>Pelotero, Filántropo</p>
34
+                <p>Fue un afamado pelotero puertorriqueño que formó parte de las Grandes Ligas de Estados Unidos. El notable jardinero derecho y bateador fue el primer latinoamericano en formar parte del Salón de la Fama del Béisbol de Estados Unidos. También fue conocido por su labor filantrópica.</p>
35
+                <p>Nació el 18 de agosto de 1934 en San Antón, Carolina. Sus padres fueron Melchor Clemente y Luisa Walker. Desde los ocho años mostró habilidades deportivas con su participación en programas de pequeñas ligas y atletismo infantil. Se destacó en pista y campo, deporte en el que ganó varias medallas, específicamente en tiro de jabalina y distancias cortas. Con apenas 14 años, ya formaba parte del equipo de softball de Sello Rojo, compañía procesadora de arroz. Más adelante, formó parte del equipo de pelota aficionado de Juncos. En 1952, con 18 años de edad, ingresó a la liga de beisbol profesional de Puerto Rico, cuando fue contratado por los Cangrejeros de Santurce. El tiempo que formó parte de este equipo fue crucial para su carrera, ya que pudo pulir sus destrezas deportivas.</p>
36
+            </IonContent>
37
+            <IonFooter>
38
+                <IonToolbar>
39
+                    <IonNavLink routerDirection="forward" component={() => <ListBiographies />}>
40
+                        <IonTabButton tab="ListBiographies" href="/ListBiographies">
41
+                            <IonIcon icon={arrowBack} />
42
+                        </IonTabButton>
43
+                    </IonNavLink>
44
+                </IonToolbar>
45
+            </IonFooter>
46
+        </IonPage>
47
+    );
48
+};
49
+
50
+export default Biography;

+ 0
- 0
src/pages/Capsule.css 查看文件


+ 50
- 0
src/pages/Capsule.tsx 查看文件

@@ -0,0 +1,50 @@
1
+import {
2
+    IonPage,
3
+    IonContent,
4
+    IonHeader,
5
+    IonTitle,
6
+    IonToolbar,
7
+    IonFooter,
8
+    IonNavLink,
9
+    IonTabButton,
10
+    IonIcon,
11
+    IonImg
12
+} from '@ionic/react';
13
+import { arrowBack } from 'ionicons/icons';
14
+import React from 'react';
15
+import './Capsule.css';
16
+import ListCapsules from './ListCapsules';
17
+import EnciclopediaPR from '../assets/EnciclopediaPR.png';
18
+import Bomba from '../assets/BombaPuertorriquena.jpg';
19
+
20
+const Capsule: React.FC = () => {
21
+    return (
22
+        <IonPage>
23
+            <IonHeader>
24
+                <IonToolbar>
25
+                    <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>
26
+                    <IonTitle>Cápsula</IonTitle>
27
+                </IonToolbar>
28
+            </IonHeader>
29
+            <IonContent fullscreen className="ion-padding">
30
+                <IonImg style={{ height: 300, width: 600 }} src={Bomba} alt='Logo'></IonImg>
31
+                <h1>Breve Historia del baile en Puerto Rico</h1>
32
+
33
+                <p>Han existido distintas formas de danzar o bailar desde la historia muy antigua de la humanidad. En Puerto Rico el primer baile documentado por los cronistas de Indias es el llamado areito, con las variantes de escritura areyto y areíto. Era un baile coreado y musicalizado, dirigido por un guía. Esta manifestación de movimiento corporal, que Gonzalo Fernández de Oviedo llamó “bailar cantando”, fue común en los grupos indígenas de la región caribeña.</p>
34
+                <p>Se ejecutaba en hileras, con los participantes cogidos de las manos, de los brazos o, según Bartolomé de las Casas, “los brazos de los unos puestos sobre los hombros de los otros”. Según Pedro Mártir de Anglería, los participantes llevaban caracoles en los brazos y piernas, con los que producían “un ruido agradable”. Narraban una historia y el guía indicaba qué pasos y cantos se repetirían hasta que ésta culminara.</p>
35
+                <p>Aunque la llegada de los conquistadores españoles produjo una rápida desaparición de la población indígena y de cualquier expresión autóctona que las autoridades consideraran pagana, Fray Iñigo Abbad y Lasierra afirmaba en 1789 que “la diversión más apreciable para estos isleños son los bailes; los tienen sin más motivo que el de pasar el tiempo y rara vez faltan en una cosa u otra”.</p>
36
+            </IonContent>
37
+            <IonFooter>
38
+                <IonToolbar>
39
+                    <IonNavLink routerDirection="forward" component={() => <ListCapsules />}>
40
+                        <IonTabButton tab="ListCapsules" href="/ListCapsules">
41
+                            <IonIcon icon={arrowBack} />
42
+                        </IonTabButton>
43
+                    </IonNavLink>
44
+                </IonToolbar>
45
+            </IonFooter>
46
+        </IonPage>
47
+    );
48
+};
49
+
50
+export default Capsule;

+ 4
- 0
src/pages/HomePage.css 查看文件

@@ -0,0 +1,4 @@
1
+ion-card-header.ios {
2
+    display: flex;
3
+    flex-flow: column-reverse;
4
+}

+ 73
- 0
src/pages/HomePage.tsx 查看文件

@@ -0,0 +1,73 @@
1
+import {
2
+  IonContent,
3
+  IonButton,
4
+  IonHeader,
5
+  IonPage,
6
+  IonTitle,
7
+  IonToolbar,
8
+  IonCard,
9
+  IonCardHeader,
10
+  IonCardSubtitle,
11
+  IonCardTitle,
12
+  IonNavLink,
13
+  IonFooter,
14
+  IonTabButton,
15
+  IonIcon,
16
+  IonLabel,
17
+  IonImg
18
+} from '@ionic/react';
19
+import { square } from 'ionicons/icons';
20
+import './HomePage.css';
21
+import ListBiographies from './ListBiographies';
22
+import ListCapsules from './ListCapsules';
23
+import AboutUs from './AboutUs';
24
+import EnciclopediaPR from '../assets/EnciclopediaPR.png';
25
+
26
+const HomePage: React.FC = () => {
27
+  return (
28
+    <IonPage>
29
+      <IonHeader>
30
+        <IonToolbar>
31
+          <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>
32
+          <IonTitle>Hogar</IonTitle>
33
+        </IonToolbar>
34
+      </IonHeader>
35
+      <IonContent fullscreen>
36
+        <IonCard>
37
+          <IonCardHeader>
38
+            <IonCardTitle>Biografías</IonCardTitle>
39
+            <IonCardSubtitle>Lista de todas las biografías</IonCardSubtitle>
40
+          </IonCardHeader>
41
+          <IonNavLink routerDirection="forward" component={() => <ListBiographies />}>
42
+            <IonButton size="default" expand="block" shape="round">
43
+              Buscar
44
+            </IonButton>
45
+          </IonNavLink>
46
+        </IonCard>
47
+        <IonCard>
48
+          <IonCardHeader>
49
+            <IonCardTitle>Cápsulas</IonCardTitle>
50
+            <IonCardSubtitle>Lista de todas las cápsulas</IonCardSubtitle>
51
+          </IonCardHeader>
52
+          <IonNavLink routerDirection="forward" component={() => <ListCapsules />}>
53
+            <IonButton size="default" expand="block" shape="round">
54
+              Buscar
55
+            </IonButton>
56
+          </IonNavLink>
57
+        </IonCard>
58
+      </IonContent>
59
+      <IonFooter>
60
+        <IonToolbar>
61
+          <IonNavLink routerDirection="forward" component={() => <AboutUs />}>
62
+            <IonTabButton tab="AboutUs" href="/AboutUs">
63
+              <IonIcon icon={square} />
64
+              <IonLabel>Sobre nosotros</IonLabel>
65
+            </IonTabButton>
66
+          </IonNavLink>
67
+        </IonToolbar>
68
+      </IonFooter>
69
+    </IonPage>
70
+  );
71
+};
72
+
73
+export default HomePage;

+ 0
- 0
src/pages/ListBiographies.css 查看文件


+ 67
- 0
src/pages/ListBiographies.tsx 查看文件

@@ -0,0 +1,67 @@
1
+import {
2
+  IonImg,
3
+  IonCard,
4
+  IonCardContent,
5
+  IonCardHeader,
6
+  IonCardSubtitle,
7
+  IonCardTitle,
8
+  IonSearchbar,
9
+  IonContent,
10
+  IonHeader,
11
+  IonPage,
12
+  IonTitle,
13
+  IonToolbar,
14
+  IonButton,
15
+  IonNavLink,
16
+  IonFooter,
17
+  IonTabButton,
18
+  IonIcon
19
+} from '@ionic/react';
20
+import { arrowBack } from 'ionicons/icons';
21
+import './ListBiographies.css';
22
+import Biography from './Biography';
23
+import HomePage from './HomePage';
24
+import EnciclopediaPR from '../assets/EnciclopediaPR.png';
25
+import RobertoClemente from '../assets/RobertoClemente.jpg';
26
+
27
+const ListBiographies: React.FC = () => {
28
+  return (
29
+    <IonPage>
30
+      <IonHeader>
31
+        <IonToolbar>
32
+          <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>\
33
+          <IonTitle>Lista de Biografías</IonTitle>
34
+        </IonToolbar>
35
+      </IonHeader>
36
+      <IonContent fullscreen>
37
+        <IonSearchbar></IonSearchbar>
38
+        <IonCard>
39
+          <IonImg style={{ height: 300, width: 600 }} src={RobertoClemente} alt='Logo'></IonImg>
40
+          <IonCardHeader>
41
+            <IonCardTitle>Roberto Clemente</IonCardTitle>
42
+            <IonCardSubtitle>Tabs: Deportista</IonCardSubtitle>
43
+          </IonCardHeader>
44
+
45
+          <IonCardContent>
46
+            Fue un afamado pelotero puertorriqueño que formó parte de las Grandes Ligas de Estados Unidos. El notable jardinero derecho y bateador fue el primer latinoamericano en formar parte del Salón de la Fama del Béisbol de Estados Unidos. También fue conocido por su labor filantrópica.
47
+          </IonCardContent>
48
+
49
+          <IonNavLink routerDirection="forward" component={() => <Biography />}>
50
+            <IonButton>Go to</IonButton>
51
+          </IonNavLink>
52
+        </IonCard>
53
+      </IonContent>
54
+      <IonFooter>
55
+        <IonToolbar>
56
+          <IonNavLink routerDirection="forward" component={() => <HomePage />}>
57
+            <IonTabButton tab="HomePage" href="/HomePage">
58
+              <IonIcon icon={arrowBack} />
59
+            </IonTabButton>
60
+          </IonNavLink>
61
+        </IonToolbar>
62
+      </IonFooter>
63
+    </IonPage>
64
+  );
65
+};
66
+
67
+export default ListBiographies;

+ 0
- 0
src/pages/ListCapsules.css 查看文件


+ 64
- 0
src/pages/ListCapsules.tsx 查看文件

@@ -0,0 +1,64 @@
1
+import {
2
+    IonList,
3
+    IonItem,
4
+    IonLabel,
5
+    IonImg,
6
+    IonSearchbar,
7
+    IonContent,
8
+    IonHeader,
9
+    IonPage,
10
+    IonTitle,
11
+    IonToolbar,
12
+    IonButton,
13
+    IonNavLink,
14
+    IonFooter,
15
+    IonTabButton,
16
+    IonIcon
17
+  } from '@ionic/react';
18
+  import { arrowBack } from 'ionicons/icons';
19
+  import './ListCapsules.css';
20
+  import HomePage from './HomePage';
21
+  import Capsule from './Capsule'
22
+  import EnciclopediaPR from '../assets/EnciclopediaPR.png';
23
+
24
+  const ListCapsules: React.FC = () => {
25
+    return (
26
+      <IonPage>
27
+        <IonHeader>
28
+          <IonToolbar>
29
+            <IonImg style={{ height: 50, width: 100 }} src={EnciclopediaPR} alt='Logo'></IonImg>
30
+            <IonTitle>Lista de Cápsulas de Contenido</IonTitle>
31
+          </IonToolbar>
32
+        </IonHeader>
33
+        <IonContent fullscreen>
34
+            <IonSearchbar></IonSearchbar>
35
+            <IonList inset={true}>
36
+                <IonItem>
37
+                    <IonLabel>Breve Historia del baile en Puerto Rico</IonLabel>
38
+                    <IonNavLink routerDirection="forward" component={() => <Capsule />}>
39
+                    <IonButton>Visitar</IonButton>
40
+          </IonNavLink>
41
+                </IonItem>
42
+                <IonItem>
43
+                    <IonLabel>Cápsula#2</IonLabel>
44
+                </IonItem>
45
+                <IonItem>
46
+                    <IonLabel>Cápsula#3</IonLabel>
47
+                </IonItem>
48
+            </IonList>
49
+        </IonContent>
50
+        <IonFooter>
51
+          <IonToolbar>
52
+            <IonNavLink routerDirection="forward" component={() => <HomePage />}>
53
+                <IonTabButton tab="HomePage" href="/HomePage">
54
+                <IonIcon icon={arrowBack} />
55
+              </IonTabButton>
56
+            </IonNavLink>
57
+          </IonToolbar>
58
+        </IonFooter>
59
+      </IonPage>
60
+    );
61
+  };
62
+  
63
+  export default ListCapsules;
64
+  

+ 1
- 0
src/react-app-env.d.ts 查看文件

@@ -0,0 +1 @@
1
+/// <reference types="react-scripts" />

+ 15
- 0
src/reportWebVitals.ts 查看文件

@@ -0,0 +1,15 @@
1
+import { ReportHandler } from 'web-vitals';
2
+
3
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4
+  if (onPerfEntry && onPerfEntry instanceof Function) {
5
+    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6
+      getCLS(onPerfEntry);
7
+      getFID(onPerfEntry);
8
+      getFCP(onPerfEntry);
9
+      getLCP(onPerfEntry);
10
+      getTTFB(onPerfEntry);
11
+    });
12
+  }
13
+};
14
+
15
+export default reportWebVitals;

+ 80
- 0
src/service-worker.ts 查看文件

@@ -0,0 +1,80 @@
1
+/// <reference lib="webworker" />
2
+/* eslint-disable no-restricted-globals */
3
+
4
+// This service worker can be customized!
5
+// See https://developers.google.com/web/tools/workbox/modules
6
+// for the list of available Workbox modules, or add any other
7
+// code you'd like.
8
+// You can also remove this file if you'd prefer not to use a
9
+// service worker, and the Workbox build step will be skipped.
10
+
11
+import { clientsClaim } from 'workbox-core';
12
+import { ExpirationPlugin } from 'workbox-expiration';
13
+import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
14
+import { registerRoute } from 'workbox-routing';
15
+import { StaleWhileRevalidate } from 'workbox-strategies';
16
+
17
+declare const self: ServiceWorkerGlobalScope;
18
+
19
+clientsClaim();
20
+
21
+// Precache all of the assets generated by your build process.
22
+// Their URLs are injected into the manifest variable below.
23
+// This variable must be present somewhere in your service worker file,
24
+// even if you decide not to use precaching. See https://cra.link/PWA
25
+precacheAndRoute(self.__WB_MANIFEST);
26
+
27
+// Set up App Shell-style routing, so that all navigation requests
28
+// are fulfilled with your index.html shell. Learn more at
29
+// https://developers.google.com/web/fundamentals/architecture/app-shell
30
+const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
31
+registerRoute(
32
+  // Return false to exempt requests from being fulfilled by index.html.
33
+  ({ request, url }: { request: Request; url: URL }) => {
34
+    // If this isn't a navigation, skip.
35
+    if (request.mode !== 'navigate') {
36
+      return false;
37
+    }
38
+
39
+    // If this is a URL that starts with /_, skip.
40
+    if (url.pathname.startsWith('/_')) {
41
+      return false;
42
+    }
43
+
44
+    // If this looks like a URL for a resource, because it contains
45
+    // a file extension, skip.
46
+    if (url.pathname.match(fileExtensionRegexp)) {
47
+      return false;
48
+    }
49
+
50
+    // Return true to signal that we want to use the handler.
51
+    return true;
52
+  },
53
+  createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
54
+);
55
+
56
+// An example runtime caching route for requests that aren't handled by the
57
+// precache, in this case same-origin .png requests like those from in public/
58
+registerRoute(
59
+  // Add in any other file extensions or routing criteria as needed.
60
+  ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'),
61
+  // Customize this strategy as needed, e.g., by changing to CacheFirst.
62
+  new StaleWhileRevalidate({
63
+    cacheName: 'images',
64
+    plugins: [
65
+      // Ensure that once this runtime cache reaches a maximum size the
66
+      // least-recently used images are removed.
67
+      new ExpirationPlugin({ maxEntries: 50 }),
68
+    ],
69
+  })
70
+);
71
+
72
+// This allows the web app to trigger skipWaiting via
73
+// registration.waiting.postMessage({type: 'SKIP_WAITING'})
74
+self.addEventListener('message', (event) => {
75
+  if (event.data && event.data.type === 'SKIP_WAITING') {
76
+    self.skipWaiting();
77
+  }
78
+});
79
+
80
+// Any other custom service worker logic can go here.

+ 142
- 0
src/serviceWorkerRegistration.ts 查看文件

@@ -0,0 +1,142 @@
1
+// This optional code is used to register a service worker.
2
+// register() is not called by default.
3
+
4
+// This lets the app load faster on subsequent visits in production, and gives
5
+// it offline capabilities. However, it also means that developers (and users)
6
+// will only see deployed updates on subsequent visits to a page, after all the
7
+// existing tabs open on the page have been closed, since previously cached
8
+// resources are updated in the background.
9
+
10
+// To learn more about the benefits of this model and instructions on how to
11
+// opt-in, read https://cra.link/PWA
12
+
13
+const isLocalhost = Boolean(
14
+  window.location.hostname === 'localhost' ||
15
+    // [::1] is the IPv6 localhost address.
16
+    window.location.hostname === '[::1]' ||
17
+    // 127.0.0.0/8 are considered localhost for IPv4.
18
+    window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
19
+);
20
+
21
+type Config = {
22
+  onSuccess?: (registration: ServiceWorkerRegistration) => void;
23
+  onUpdate?: (registration: ServiceWorkerRegistration) => void;
24
+};
25
+
26
+export function register(config?: Config) {
27
+  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
28
+    // The URL constructor is available in all browsers that support SW.
29
+    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
30
+    if (publicUrl.origin !== window.location.origin) {
31
+      // Our service worker won't work if PUBLIC_URL is on a different origin
32
+      // from what our page is served on. This might happen if a CDN is used to
33
+      // serve assets; see https://github.com/facebook/create-react-app/issues/2374
34
+      return;
35
+    }
36
+
37
+    window.addEventListener('load', () => {
38
+      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
39
+
40
+      if (isLocalhost) {
41
+        // This is running on localhost. Let's check if a service worker still exists or not.
42
+        checkValidServiceWorker(swUrl, config);
43
+
44
+        // Add some additional logging to localhost, pointing developers to the
45
+        // service worker/PWA documentation.
46
+        navigator.serviceWorker.ready.then(() => {
47
+          console.log(
48
+            'This web app is being served cache-first by a service ' +
49
+              'worker. To learn more, visit https://cra.link/PWA'
50
+          );
51
+        });
52
+      } else {
53
+        // Is not localhost. Just register service worker
54
+        registerValidSW(swUrl, config);
55
+      }
56
+    });
57
+  }
58
+}
59
+
60
+function registerValidSW(swUrl: string, config?: Config) {
61
+  navigator.serviceWorker
62
+    .register(swUrl)
63
+    .then((registration) => {
64
+      registration.onupdatefound = () => {
65
+        const installingWorker = registration.installing;
66
+        if (installingWorker == null) {
67
+          return;
68
+        }
69
+        installingWorker.onstatechange = () => {
70
+          if (installingWorker.state === 'installed') {
71
+            if (navigator.serviceWorker.controller) {
72
+              // At this point, the updated precached content has been fetched,
73
+              // but the previous service worker will still serve the older
74
+              // content until all client tabs are closed.
75
+              console.log(
76
+                'New content is available and will be used when all ' +
77
+                  'tabs for this page are closed. See https://cra.link/PWA.'
78
+              );
79
+
80
+              // Execute callback
81
+              if (config && config.onUpdate) {
82
+                config.onUpdate(registration);
83
+              }
84
+            } else {
85
+              // At this point, everything has been precached.
86
+              // It's the perfect time to display a
87
+              // "Content is cached for offline use." message.
88
+              console.log('Content is cached for offline use.');
89
+
90
+              // Execute callback
91
+              if (config && config.onSuccess) {
92
+                config.onSuccess(registration);
93
+              }
94
+            }
95
+          }
96
+        };
97
+      };
98
+    })
99
+    .catch((error) => {
100
+      console.error('Error during service worker registration:', error);
101
+    });
102
+}
103
+
104
+function checkValidServiceWorker(swUrl: string, config?: Config) {
105
+  // Check if the service worker can be found. If it can't reload the page.
106
+  fetch(swUrl, {
107
+    headers: { 'Service-Worker': 'script' },
108
+  })
109
+    .then((response) => {
110
+      // Ensure service worker exists, and that we really are getting a JS file.
111
+      const contentType = response.headers.get('content-type');
112
+      if (
113
+        response.status === 404 ||
114
+        (contentType != null && contentType.indexOf('javascript') === -1)
115
+      ) {
116
+        // No service worker found. Probably a different app. Reload the page.
117
+        navigator.serviceWorker.ready.then((registration) => {
118
+          registration.unregister().then(() => {
119
+            window.location.reload();
120
+          });
121
+        });
122
+      } else {
123
+        // Service worker found. Proceed as normal.
124
+        registerValidSW(swUrl, config);
125
+      }
126
+    })
127
+    .catch(() => {
128
+      console.log('No internet connection found. App is running in offline mode.');
129
+    });
130
+}
131
+
132
+export function unregister() {
133
+  if ('serviceWorker' in navigator) {
134
+    navigator.serviceWorker.ready
135
+      .then((registration) => {
136
+        registration.unregister();
137
+      })
138
+      .catch((error) => {
139
+        console.error(error.message);
140
+      });
141
+  }
142
+}

+ 14
- 0
src/setupTests.ts 查看文件

@@ -0,0 +1,14 @@
1
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
2
+// allows you to do things like:
3
+// expect(element).toHaveTextContent(/react/i)
4
+// learn more: https://github.com/testing-library/jest-dom
5
+import '@testing-library/jest-dom/extend-expect';
6
+
7
+// Mock matchmedia
8
+window.matchMedia = window.matchMedia || function() {
9
+  return {
10
+      matches: false,
11
+      addListener: function() {},
12
+      removeListener: function() {}
13
+  };
14
+};

+ 236
- 0
src/theme/variables.css 查看文件

@@ -0,0 +1,236 @@
1
+/* Ionic Variables and Theming. For more info, please see:
2
+http://ionicframework.com/docs/theming/ */
3
+
4
+/** Ionic CSS Variables **/
5
+:root {
6
+  /** primary **/
7
+  --ion-color-primary: #3880FF;
8
+  --ion-color-primary-rgb: 56, 128, 255;
9
+  --ion-color-primary-contrast: #ffffff;
10
+  --ion-color-primary-contrast-rgb: 255, 255, 255;
11
+  --ion-color-primary-shade: #3171e0;
12
+  --ion-color-primary-tint: #4c8dff;
13
+
14
+  /** secondary **/
15
+  --ion-color-secondary: #3dc2ff;
16
+  --ion-color-secondary-rgb: 61, 194, 255;
17
+  --ion-color-secondary-contrast: #ffffff;
18
+  --ion-color-secondary-contrast-rgb: 255, 255, 255;
19
+  --ion-color-secondary-shade: #36abe0;
20
+  --ion-color-secondary-tint: #50c8ff;
21
+
22
+  /** tertiary **/
23
+  --ion-color-tertiary: #5260ff;
24
+  --ion-color-tertiary-rgb: 82, 96, 255;
25
+  --ion-color-tertiary-contrast: #ffffff;
26
+  --ion-color-tertiary-contrast-rgb: 255, 255, 255;
27
+  --ion-color-tertiary-shade: #4854e0;
28
+  --ion-color-tertiary-tint: #6370ff;
29
+
30
+  /** success **/
31
+  --ion-color-success: #2dd36f;
32
+  --ion-color-success-rgb: 45, 211, 111;
33
+  --ion-color-success-contrast: #ffffff;
34
+  --ion-color-success-contrast-rgb: 255, 255, 255;
35
+  --ion-color-success-shade: #28ba62;
36
+  --ion-color-success-tint: #42d77d;
37
+
38
+  /** warning **/
39
+  --ion-color-warning: #ffc409;
40
+  --ion-color-warning-rgb: 255, 196, 9;
41
+  --ion-color-warning-contrast: #000000;
42
+  --ion-color-warning-contrast-rgb: 0, 0, 0;
43
+  --ion-color-warning-shade: #e0ac08;
44
+  --ion-color-warning-tint: #ffca22;
45
+
46
+  /** danger **/
47
+  --ion-color-danger: #eb445a;
48
+  --ion-color-danger-rgb: 235, 68, 90;
49
+  --ion-color-danger-contrast: #ffffff;
50
+  --ion-color-danger-contrast-rgb: 255, 255, 255;
51
+  --ion-color-danger-shade: #cf3c4f;
52
+  --ion-color-danger-tint: #ed576b;
53
+
54
+  /** dark **/
55
+  --ion-color-dark: #222428;
56
+  --ion-color-dark-rgb: 34, 36, 40;
57
+  --ion-color-dark-contrast: #ffffff;
58
+  --ion-color-dark-contrast-rgb: 255, 255, 255;
59
+  --ion-color-dark-shade: #1e2023;
60
+  --ion-color-dark-tint: #383a3e;
61
+
62
+  /** medium **/
63
+  --ion-color-medium: #92949c;
64
+  --ion-color-medium-rgb: 146, 148, 156;
65
+  --ion-color-medium-contrast: #ffffff;
66
+  --ion-color-medium-contrast-rgb: 255, 255, 255;
67
+  --ion-color-medium-shade: #808289;
68
+  --ion-color-medium-tint: #9d9fa6;
69
+
70
+  /** light **/
71
+  --ion-color-light: #f4f5f8;
72
+  --ion-color-light-rgb: 244, 245, 248;
73
+  --ion-color-light-contrast: #000000;
74
+  --ion-color-light-contrast-rgb: 0, 0, 0;
75
+  --ion-color-light-shade: #d7d8da;
76
+  --ion-color-light-tint: #f5f6f9;
77
+}
78
+
79
+@media (prefers-color-scheme: dark) {
80
+  /*
81
+   * Dark Colors
82
+   * -------------------------------------------
83
+   */
84
+
85
+  body {
86
+    --ion-color-primary: #afccff;
87
+    --ion-color-primary-rgb: 175, 204, 255;
88
+    --ion-color-primary-contrast: #000000;
89
+    --ion-color-primary-contrast-rgb: 0, 0, 0;
90
+    --ion-color-primary-shade: #9ab4e0;
91
+    --ion-color-primary-tint: #b7d1ff;
92
+
93
+    --ion-color-secondary: #50c8ff;
94
+    --ion-color-secondary-rgb: 80,200,255;
95
+    --ion-color-secondary-contrast: #ffffff;
96
+    --ion-color-secondary-contrast-rgb: 255,255,255;
97
+    --ion-color-secondary-shade: #46b0e0;
98
+    --ion-color-secondary-tint: #62ceff;
99
+
100
+    --ion-color-tertiary: #6a64ff;
101
+    --ion-color-tertiary-rgb: 106,100,255;
102
+    --ion-color-tertiary-contrast: #ffffff;
103
+    --ion-color-tertiary-contrast-rgb: 255,255,255;
104
+    --ion-color-tertiary-shade: #5d58e0;
105
+    --ion-color-tertiary-tint: #7974ff;
106
+
107
+    --ion-color-success: #2fdf75;
108
+    --ion-color-success-rgb: 47,223,117;
109
+    --ion-color-success-contrast: #000000;
110
+    --ion-color-success-contrast-rgb: 0,0,0;
111
+    --ion-color-success-shade: #29c467;
112
+    --ion-color-success-tint: #44e283;
113
+
114
+    --ion-color-warning: #ffd534;
115
+    --ion-color-warning-rgb: 255,213,52;
116
+    --ion-color-warning-contrast: #000000;
117
+    --ion-color-warning-contrast-rgb: 0,0,0;
118
+    --ion-color-warning-shade: #e0bb2e;
119
+    --ion-color-warning-tint: #ffd948;
120
+
121
+    --ion-color-danger: #ff4961;
122
+    --ion-color-danger-rgb: 255,73,97;
123
+    --ion-color-danger-contrast: #ffffff;
124
+    --ion-color-danger-contrast-rgb: 255,255,255;
125
+    --ion-color-danger-shade: #e04055;
126
+    --ion-color-danger-tint: #ff5b71;
127
+
128
+    --ion-color-dark: #f4f5f8;
129
+    --ion-color-dark-rgb: 244,245,248;
130
+    --ion-color-dark-contrast: #000000;
131
+    --ion-color-dark-contrast-rgb: 0,0,0;
132
+    --ion-color-dark-shade: #d7d8da;
133
+    --ion-color-dark-tint: #f5f6f9;
134
+
135
+    --ion-color-medium: #989aa2;
136
+    --ion-color-medium-rgb: 152,154,162;
137
+    --ion-color-medium-contrast: #000000;
138
+    --ion-color-medium-contrast-rgb: 0,0,0;
139
+    --ion-color-medium-shade: #86888f;
140
+    --ion-color-medium-tint: #a2a4ab;
141
+
142
+    --ion-color-light: #222428;
143
+    --ion-color-light-rgb: 34,36,40;
144
+    --ion-color-light-contrast: #ffffff;
145
+    --ion-color-light-contrast-rgb: 255,255,255;
146
+    --ion-color-light-shade: #1e2023;
147
+    --ion-color-light-tint: #383a3e;
148
+  }
149
+
150
+  /*
151
+   * iOS Dark Theme
152
+   * -------------------------------------------
153
+   */
154
+
155
+  .ios body {
156
+    --ion-background-color: #000000;
157
+    --ion-background-color-rgb: 0,0,0;
158
+
159
+    --ion-text-color: #ffffff;
160
+    --ion-text-color-rgb: 255,255,255;
161
+
162
+    --ion-color-step-50: #0d0d0d;
163
+    --ion-color-step-100: #1a1a1a;
164
+    --ion-color-step-150: #262626;
165
+    --ion-color-step-200: #333333;
166
+    --ion-color-step-250: #404040;
167
+    --ion-color-step-300: #4d4d4d;
168
+    --ion-color-step-350: #595959;
169
+    --ion-color-step-400: #666666;
170
+    --ion-color-step-450: #737373;
171
+    --ion-color-step-500: #808080;
172
+    --ion-color-step-550: #8c8c8c;
173
+    --ion-color-step-600: #999999;
174
+    --ion-color-step-650: #a6a6a6;
175
+    --ion-color-step-700: #b3b3b3;
176
+    --ion-color-step-750: #bfbfbf;
177
+    --ion-color-step-800: #cccccc;
178
+    --ion-color-step-850: #d9d9d9;
179
+    --ion-color-step-900: #e6e6e6;
180
+    --ion-color-step-950: #f2f2f2;
181
+
182
+    --ion-item-background: #000000;
183
+
184
+    --ion-card-background: #1c1c1d;
185
+  }
186
+
187
+  .ios ion-modal {
188
+    --ion-background-color: var(--ion-color-step-100);
189
+    --ion-toolbar-background: var(--ion-color-step-150);
190
+    --ion-toolbar-border-color: var(--ion-color-step-250);
191
+  }
192
+
193
+
194
+  /*
195
+   * Material Design Dark Theme
196
+   * -------------------------------------------
197
+   */
198
+
199
+  .md body {
200
+    --ion-background-color: #121212;
201
+    --ion-background-color-rgb: 18,18,18;
202
+
203
+    --ion-text-color: #ffffff;
204
+    --ion-text-color-rgb: 255,255,255;
205
+
206
+    --ion-border-color: #222222;
207
+
208
+    --ion-color-step-50: #1e1e1e;
209
+    --ion-color-step-100: #2a2a2a;
210
+    --ion-color-step-150: #363636;
211
+    --ion-color-step-200: #414141;
212
+    --ion-color-step-250: #4d4d4d;
213
+    --ion-color-step-300: #595959;
214
+    --ion-color-step-350: #656565;
215
+    --ion-color-step-400: #717171;
216
+    --ion-color-step-450: #7d7d7d;
217
+    --ion-color-step-500: #898989;
218
+    --ion-color-step-550: #949494;
219
+    --ion-color-step-600: #a0a0a0;
220
+    --ion-color-step-650: #acacac;
221
+    --ion-color-step-700: #b8b8b8;
222
+    --ion-color-step-750: #c4c4c4;
223
+    --ion-color-step-800: #d0d0d0;
224
+    --ion-color-step-850: #dbdbdb;
225
+    --ion-color-step-900: #e7e7e7;
226
+    --ion-color-step-950: #f3f3f3;
227
+
228
+    --ion-item-background: #1e1e1e;
229
+
230
+    --ion-toolbar-background: #1f1f1f;
231
+
232
+    --ion-tab-bar-background: #1f1f1f;
233
+
234
+    --ion-card-background: #1e1e1e;
235
+  }
236
+}

+ 26
- 0
tsconfig.json 查看文件

@@ -0,0 +1,26 @@
1
+{
2
+  "compilerOptions": {
3
+    "target": "es5",
4
+    "lib": [
5
+      "dom",
6
+      "dom.iterable",
7
+      "esnext"
8
+    ],
9
+    "allowJs": true,
10
+    "skipLibCheck": true,
11
+    "esModuleInterop": true,
12
+    "allowSyntheticDefaultImports": true,
13
+    "strict": true,
14
+    "forceConsistentCasingInFileNames": true,
15
+    "noFallthroughCasesInSwitch": true,
16
+    "module": "esnext",
17
+    "moduleResolution": "node",
18
+    "resolveJsonModule": true,
19
+    "isolatedModules": true,
20
+    "noEmit": true,
21
+    "jsx": "react-jsx"
22
+  },
23
+  "include": [
24
+    "src"
25
+  ]
26
+}