diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index fbcac7e..f539473 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -25,6 +25,6 @@ jobs: server: ${{ secrets.FTP_HOST }} username: ${{ secrets.FTP_USER }} password: ${{ secrets.FTP_PASS }} - local-dir: ./ + local-dir: app/src/main/assets/ server-dir: / diff --git a/.github/workflows/build-apk.yml b/.github/workflows/build-apk.yml new file mode 100644 index 0000000..27db231 --- /dev/null +++ b/.github/workflows/build-apk.yml @@ -0,0 +1,35 @@ +name: Build APK + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup JDK + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Grant execute permission + run: chmod +x ./gradlew + + - name: Build APK + run: ./gradlew assembleRelease + + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: app-release + path: app/build/outputs/apk/release/app-release.apk diff --git a/MainActivity.kt b/MainActivity.kt new file mode 100644 index 0000000..170e7ff --- /dev/null +++ b/MainActivity.kt @@ -0,0 +1,25 @@ +package com.example.app + +import android.os.Bundle +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.appcompat.app.AppCompatActivity + +class MainActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val webView = WebView(this) + + webView.settings.javaScriptEnabled = true + webView.settings.allowFileAccess = true + webView.settings.domStorageEnabled = true + + webView.webViewClient = WebViewClient() + + webView.loadUrl("file:///android_asset/index.html") + + setContentView(webView) + } +} diff --git a/QuizzyTemplate/App b/QuizzyTemplate/App deleted file mode 160000 index 149f214..0000000 --- a/QuizzyTemplate/App +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 149f214357b2a991e93bab6d418c91479a78e0ac diff --git a/QuizzyTemplate/Doc/app.css b/QuizzyTemplate/Doc/app.css deleted file mode 100644 index 44d85a1..0000000 --- a/QuizzyTemplate/Doc/app.css +++ /dev/null @@ -1,410 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); - -:root { - --primary: #6366F1; - --primary-dark: #4F46E5; - --secondary: #8B5CF6; - --accent: #FFD166; - --text: #334155; - --text-light: #64748B; - --bg: #F8FAFC; - --bg-card: #FFFFFF; - --border: #E2E8F0; - --code-bg: #F1F5F9; -} - -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Inter', sans-serif; - background-color: var(--bg); - color: var(--text); - line-height: 1.6; - padding: 0; - margin: 0; -} - -.container { - max-width: 1100px; - margin: 0 auto; - padding: 0 20px; -} - -header { - background: linear-gradient(135deg, var(--primary), var(--secondary)); - color: white; - padding: 60px 0 80px; - position: relative; -} - -header::after { - content: ''; - position: absolute; - bottom: -2px; - left: 0; - right: 0; - height: 4px; - background: var(--accent); -} - -.logo { - font-size: 24px; - font-weight: 700; - display: flex; - align-items: center; - margin-bottom: 20px; -} - -.logo-icon { - margin-right: 10px; - font-size: 28px; -} - -h1, h2, h3, h4, h5, h6 { - font-weight: 600; - line-height: 1.3; - margin-bottom: 20px; - color: var(--text); -} - -h1 { - font-size: 2.5em; - margin-bottom: 15px; - color: white; -} - -h2 { - font-size: 1.8em; - padding-bottom: 10px; - border-bottom: 1px solid var(--border); - margin-top: 50px; -} - -h3 { - font-size: 1.4em; - margin-top: 30px; -} - -h4 { - font-size: 1.2em; - margin-top: 20px; -} - -p { - margin-bottom: 16px; -} - -a { - color: var(--primary); - text-decoration: none; - transition: color 0.2s ease; -} - -a:hover { - color: var(--primary-dark); - text-decoration: underline; -} - -.header-subtitle { - font-size: 1.2em; - color: rgba(255, 255, 255, 0.9); - max-width: 700px; -} - -.content { - padding: 60px 0; - position: relative; -} - -.toc { - background-color: var(--bg-card); - border-radius: 10px; - padding: 25px; - box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05); - margin-bottom: 40px; -} - -.toc-title { - font-size: 1.2em; - font-weight: 600; - margin-bottom: 15px; - color: var(--text); - display: flex; - align-items: center; -} - -.toc-title svg { - margin-right: 10px; -} - -.toc-list { - list-style-type: none; - columns: 2; - column-gap: 30px; -} - -.toc-list li { - margin-bottom: 10px; - break-inside: avoid; -} - -.toc-list a { - color: var(--text-light); - transition: color 0.2s; - display: flex; - align-items: center; -} - -.toc-list a:hover { - color: var(--primary); -} - -.toc-list a::before { - content: "•"; - margin-right: 8px; - color: var(--primary); - font-weight: bold; -} - -.section { - margin-bottom: 60px; -} - -ul, ol { - margin-left: 20px; - margin-bottom: 20px; -} - -li { - margin-bottom: 8px; -} - -code { - font-family: 'Monaco', 'Consolas', monospace; - background-color: var(--code-bg); - padding: 2px 6px; - border-radius: 4px; - font-size: 0.9em; -} - -pre { - background-color: var(--code-bg); - padding: 15px; - border-radius: 8px; - overflow-x: auto; - margin-bottom: 20px; - border-left: 4px solid var(--primary); -} - -pre code { - background: none; - padding: 0; - font-size: 0.9em; -} - -.feature-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); - gap: 20px; - margin-bottom: 30px; -} - -.feature-card { - background: var(--bg-card); - border-radius: 8px; - padding: 20px; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); - transition: transform 0.3s ease, box-shadow 0.3s ease; -} - -.feature-card:hover { - transform: translateY(-5px); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); -} - -.feature-icon { - font-size: 24px; - margin-bottom: 12px; - color: var(--primary); -} - -.note { - background-color: rgba(99, 102, 241, 0.1); - border-left: 4px solid var(--primary); - padding: 15px; - border-radius: 0 8px 8px 0; - margin-bottom: 20px; -} - -.warning { - background-color: rgba(255, 209, 102, 0.2); - border-left: 4px solid var(--accent); - padding: 15px; - border-radius: 0 8px 8px 0; - margin-bottom: 20px; -} - -.project-structure { - font-family: 'Monaco', 'Consolas', monospace; - background-color: var(--code-bg); - padding: 20px; - border-radius: 8px; - margin-bottom: 20px; - white-space: pre; - overflow-x: auto; - line-height: 1.4; - font-size: 0.85em; -} - -.code-filename { - color: var(--primary); - font-weight: 600; - margin-bottom: 5px; - font-size: 0.9em; -} - -.steps { - list-style-type: none; - counter-reset: step-counter; - margin-left: 0; -} - -.steps li { - counter-increment: step-counter; - margin-bottom: 15px; - position: relative; - padding-left: 45px; -} - -.steps li::before { - content: counter(step-counter); - background-color: var(--primary); - color: white; - width: 30px; - height: 30px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - position: absolute; - left: 0; - top: -1px; - font-weight: 600; - font-size: 0.9em; -} - -.table-container { - overflow-x: auto; - margin-bottom: 20px; -} - -table { - width: 100%; - border-collapse: collapse; - margin-bottom: 20px; -} - -th, td { - padding: 12px 15px; - text-align: left; - border-bottom: 1px solid var(--border); -} - -th { - background-color: var(--code-bg); - font-weight: 600; -} - -tr:hover { - background-color: rgba(0, 0, 0, 0.01); -} - -.badge { - display: inline-block; - background-color: var(--primary); - color: white; - border-radius: 20px; - padding: 3px 10px; - font-size: 0.75em; - font-weight: 600; - margin-right: 5px; -} - -.badge.secondary { - background-color: var(--secondary); -} - -.badge.accent { - background-color: var(--accent); - color: var(--text); -} - -.screenshot { - max-width: 100%; - border-radius: 8px; - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); - margin-bottom: 20px; -} - -footer { - background-color: var(--text); - color: white; - padding: 30px 0; - text-align: center; - margin-top: 100px; -} - -.back-to-top { - position: fixed; - bottom: 30px; - right: 30px; - background-color: var(--primary); - color: white; - width: 50px; - height: 50px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - text-decoration: none; - box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); - opacity: 0; - visibility: hidden; - transition: all 0.3s ease; -} - -.back-to-top.visible { - opacity: 1; - visibility: visible; -} - -.back-to-top:hover { - background-color: var(--primary-dark); - transform: translateY(-3px); -} - -@media (max-width: 768px) { - h1 { - font-size: 2em; - } - - h2 { - font-size: 1.5em; - } - - .toc-list { - columns: 1; - } - - .container { - padding: 0 15px; - } - - .feature-grid { - grid-template-columns: 1fr; - } -} \ No newline at end of file diff --git a/QuizzyTemplate/Doc/index.html b/QuizzyTemplate/Doc/index.html deleted file mode 100644 index 2629c61..0000000 --- a/QuizzyTemplate/Doc/index.html +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - QuizzyMind App Documentation - - - -
-
- -

QuizzyMind App Documentation

-

A comprehensive guide to installing, configuring, and customizing your React Native Expo quiz application.

-
-
- -
-
- - -
-

Introduction

- -

QuizzyMind is a fully functional quiz application built with React Native and Expo Router. This documentation will guide you through setting up and customizing the application to meet your specific needs.

- -

Key Features

- -
-
-
🧠
-

Multiple Quiz Categories

-

Extensive question bank with various categories

-
- -
-
🏆
-

Real-time Leaderboards

-

Compete with friends and track progress

-
- -
-
🎨
-

Modern UI

-

Clean design with smooth animations

-
- -
-
🧭
-

Expo Router

-

Optimized navigation experience

-
- -
-
📱
-

Cross-platform

-

Works on both iOS and Android

-
-
-
- -
-

Requirements

- -

Before you begin, ensure you have the following installed:

- -
    -
  • Node.js (v14.0.0 or newer)
  • -
  • npm (v6.0.0 or newer) or Yarn (v1.22.0 or newer)
  • -
  • Expo CLI (npm install -g expo-cli)
  • -
  • Android Studio (for Android development)
  • -
  • Xcode (for iOS development, macOS only)
  • -
  • Git
  • -
- -
-

Note: You can verify your Node.js and npm versions by running node -v and npm -v in your terminal.

-
-
- -
-

Installation

- -

Follow these steps to get the app up and running:

- -
    -
  1. - Clone or extract the project files -
    # If you downloaded as a zip, extract it
    -cd QuizzyMind-app
    -
  2. - -
  3. - Install dependencies -
    npm install
    -# or with yarn
    -yarn install
    -
  4. - -
  5. - Start the development server -
    npx expo start or npm start
    -
  6. - -
  7. - Run on device/simulator -
      -
    • Press i to open in iOS simulator
    • -
    • Press a to open in Android emulator
    • -
    • Scan QR code with Expo Go app on physical device
    • -
    -
  8. -
- -
-

Tip: If you encounter any issues during installation, refer to the Troubleshooting section.

-
-
- -
-

Project Structure

- -
QuizzyMind-app/ -├── app/ # Main application code using Expo Router -│ ├── (pages)/ # All screens inside this folder -│ ├────────── _layout.js # Root layout component -│ ├────────── CategoryScreen.jsx # Category Screen -│ ├────────── QuizScreen.jsx # QuizScreen Screen -│ ├────────── ResultScreen.jsx # ResultScreen Screen -│ ├── _layout.js # Root layout component -│ └── index.js # Home screen -├── assets/ # Static assets like images, fonts -├── components/ # Reusable UI components -│ ├── common/ # Shared components -│ ├── quiz/ # Quiz-related components -│ └── ui/ # UI elements (buttons, cards, etc.) -├── constants/ # App constants and theme settings -├── contexts/ # React contexts for state management -├── hooks/ # Custom React hooks -├── services/ # API services and external integrations -├── utils/ # Utility functions -├── app.json # Expo configuration -├── babel.config.js # Babel configuration -├── package.json # Dependencies and scripts -└── README.md # Basic readme
-
- -
-

Key Features

- -

Quiz Engine

- -

The quiz system supports:

-
    -
  • Multiple quiz categories
  • -
  • Various question types (multiple choice, true/false)
  • -
  • Timed quizzes
  • -
  • Score tracking and history
  • -
  • Difficulty levels
  • -
- -

User Interface

- -

The UI is built with:

-
    -
  • Custom components for consistent design
  • -
  • Smooth animations and transitions
  • -
  • Dark/light mode support
  • -
  • Responsive layouts for different device sizes
  • -
-
- -
-

Customization Guide

- -

Theme Customization

- -

Edit the theme variables in constants/Theme.js:

- -
constants/Theme.js
-
// Example theme customization
-export const COLORS = {
-  primary: '#6366F1',
-  secondary: '#8B5CF6',
-  accent: '#FFD166',
-  // Add your custom colors
-};
-
-export const FONTS = {
-  // Customize font families
-};
-
-export const SIZES = {
-  // Customize spacing and sizes
-};
- -

Content Customization

- -

Quiz questions are stored in data/quizData.js. Modify this file to add your own questions:

- -
data/quizData.js
-
export const QUIZ_CATEGORIES = [
-  {
-    id: 'general',
-    title: 'General Knowledge',
-    icon: 'brain',
-    questions: [
-      {
-        id: 'q1',
-        question: 'What is the capital of France?',
-        options: ['London', 'Berlin', 'Paris', 'Madrid'],
-        correctAnswer: 'Paris',
-        difficulty: 'easy'
-      },
-      // Add more questions here
-    ]
-  },
-  // Add more categories
-];
- -

Adding New Screens

- -

To add a new screen with Expo Router:

- -
    -
  1. Create a new file in the app directory, e.g., app/newScreen.js
  2. -
  3. Define your screen component:
  4. -
- -
app/newScreen.js
-
import { View, Text, StyleSheet } from 'react-native';
-import { useRouter } from 'expo-router';
-
-export default function NewScreen() {
-  const router = useRouter();
-  
-  return (
-    <View style={styles.container}>
-      <Text>New Screen Content</Text>
-    </View>
-  );
-}
-
-const styles = StyleSheet.create({
-  container: {
-    flex: 1,
-    alignItems: 'center',
-    justifyContent: 'center',
-  },
-});
-
- - -
-

Deployment

- -

Publishing to Expo

- -
    -
  1. Create an Expo account at expo.dev
  2. -
  3. Configure your app in app.json: -
      -
    • Update name, slug, and owner
    • -
    • Set appropriate version numbers
    • -
    • Configure splash screen and icons
    • -
    -
  4. -
  5. Build and publish: -
    expo build:android    # For Android APK/AAB
    -expo build:ios        # For iOS IPA
    -expo publish          # For Expo Go distribution
    -
  6. -
- -

Submitting to App Stores

- -

Android (Google Play)

- -
    -
  1. Generate a signed AAB: -
    eas build -p android --profile production
    -
  2. -
  3. Follow Google Play Console submission guidelines
  4. -
- -

iOS (App Store)

- -
    -
  1. Generate a signed IPA: -
    eas build -p ios --profile production
    -
  2. -
  3. Submit through App Store Connect
  4. -
-
- -
-

Troubleshooting

- -

Common Issues

- -

Metro Bundler Issues

-
# Clear cache and restart
-expo start -c
- -

Dependency Problems

-
# Reset node_modules
-rm -rf node_modules
-npm install
- -

Expo SDK Version Conflicts

-

Ensure all packages are compatible with your Expo SDK version in package.json.

- -
-

Tip: Most common issues can be resolved by clearing your cache and reinstalling dependencies.

-
-
- -
-

Support

- -

For additional support, please contact us at support@email.com or visit our support page on TemplateMonster.

-
-
-
- - - - - - - - - - - - \ No newline at end of file diff --git a/components/footer.html b/app/src/main/assets/components/footer.html similarity index 100% rename from components/footer.html rename to app/src/main/assets/components/footer.html diff --git a/components/header.html b/app/src/main/assets/components/header.html similarity index 100% rename from components/header.html rename to app/src/main/assets/components/header.html diff --git a/components/progress-bar.html b/app/src/main/assets/components/progress-bar.html similarity index 100% rename from components/progress-bar.html rename to app/src/main/assets/components/progress-bar.html diff --git a/css/fonts/inter.css b/app/src/main/assets/css/fonts/inter.css similarity index 100% rename from css/fonts/inter.css rename to app/src/main/assets/css/fonts/inter.css diff --git a/css/styles.css b/app/src/main/assets/css/styles.css similarity index 100% rename from css/styles.css rename to app/src/main/assets/css/styles.css diff --git a/czytanie.html b/app/src/main/assets/czytanie.html similarity index 100% rename from czytanie.html rename to app/src/main/assets/czytanie.html diff --git a/dyktando.html b/app/src/main/assets/dyktando.html similarity index 100% rename from dyktando.html rename to app/src/main/assets/dyktando.html diff --git a/dzielenie.html b/app/src/main/assets/dzielenie.html similarity index 100% rename from dzielenie.html rename to app/src/main/assets/dzielenie.html diff --git a/fonts/Inter-Bold.ttf b/app/src/main/assets/fonts/Inter-Bold.ttf similarity index 100% rename from fonts/Inter-Bold.ttf rename to app/src/main/assets/fonts/Inter-Bold.ttf diff --git a/fonts/Inter-ExtraBold.ttf b/app/src/main/assets/fonts/Inter-ExtraBold.ttf similarity index 100% rename from fonts/Inter-ExtraBold.ttf rename to app/src/main/assets/fonts/Inter-ExtraBold.ttf diff --git a/fonts/Inter-Medium.ttf b/app/src/main/assets/fonts/Inter-Medium.ttf similarity index 100% rename from fonts/Inter-Medium.ttf rename to app/src/main/assets/fonts/Inter-Medium.ttf diff --git a/fonts/Inter-Regular.ttf b/app/src/main/assets/fonts/Inter-Regular.ttf similarity index 100% rename from fonts/Inter-Regular.ttf rename to app/src/main/assets/fonts/Inter-Regular.ttf diff --git a/index.html b/app/src/main/assets/index.html similarity index 100% rename from index.html rename to app/src/main/assets/index.html diff --git a/js/app.js b/app/src/main/assets/js/app.js similarity index 100% rename from js/app.js rename to app/src/main/assets/js/app.js diff --git a/js/components.js b/app/src/main/assets/js/components.js similarity index 100% rename from js/components.js rename to app/src/main/assets/js/components.js diff --git a/js/czytanie.js b/app/src/main/assets/js/czytanie.js similarity index 100% rename from js/czytanie.js rename to app/src/main/assets/js/czytanie.js diff --git a/js/dyktando.js b/app/src/main/assets/js/dyktando.js similarity index 100% rename from js/dyktando.js rename to app/src/main/assets/js/dyktando.js diff --git a/js/dzielenie.js b/app/src/main/assets/js/dzielenie.js similarity index 100% rename from js/dzielenie.js rename to app/src/main/assets/js/dzielenie.js diff --git a/js/mnozenie.js b/app/src/main/assets/js/mnozenie.js similarity index 100% rename from js/mnozenie.js rename to app/src/main/assets/js/mnozenie.js diff --git a/js/nav.js b/app/src/main/assets/js/nav.js similarity index 100% rename from js/nav.js rename to app/src/main/assets/js/nav.js diff --git a/js/version.js b/app/src/main/assets/js/version.js similarity index 100% rename from js/version.js rename to app/src/main/assets/js/version.js diff --git a/json/dyktanda.json b/app/src/main/assets/json/dyktanda.json similarity index 100% rename from json/dyktanda.json rename to app/src/main/assets/json/dyktanda.json diff --git a/mnozenie.html b/app/src/main/assets/mnozenie.html similarity index 100% rename from mnozenie.html rename to app/src/main/assets/mnozenie.html diff --git a/styles.css b/app/src/main/assets/styles.css similarity index 100% rename from styles.css rename to app/src/main/assets/styles.css diff --git a/testy.html b/app/src/main/assets/testy.html similarity index 100% rename from testy.html rename to app/src/main/assets/testy.html