Toby Chui 7 mesi fa
parent
commit
6e1d6240e8
4 ha cambiato i file con 284 aggiunte e 6 eliminazioni
  1. 70 5
      web/components/quickstart.html
  2. 17 1
      web/index.html
  3. 81 0
      web/main.css
  4. 116 0
      web/script/quicksetup.js

+ 70 - 5
web/components/quickstart.html

@@ -13,10 +13,10 @@
             <div class="column">
                 <div class="serviceOption homepage" name="homepage">
                     <div class="titleWrapper">
-                        <p>Static Homepage</p>
+                        <p>Basic Homepage</p>
                     </div>
                     <div class="ui divider"></div>
-                    <p>Host a static personal homepage with HTML, CSS and JavaScript using your domain name.</p>
+                    <p>Host a static homepage with Zoraxy and point your domain name to your web server.</p>
                     <img class="themebackground ui small image" src="img/res/1F310.png">
                     <div class="activeOption">
                         <i class="ui white huge circle check icon"></i>
@@ -57,10 +57,13 @@
             </button>
         </div>
     </div>
-   
+    
 </div>
 <script>
     var currentQuickSetupClass = "";
+    var currentQuickSetupTourStep = 0;
+    //For tour logic, see quicksetup.js
+
 
     //Bind selecting events to serviceOption
     $("#quickstart .serviceOption").on("click", function(data){
@@ -74,9 +77,71 @@
         if (currentQuickSetupClass == ""){
             msgbox("No selected setup service tour", false);
             return;
+        }   
+        //Show the tour modal
+        $("#tourModal").show();
+        //Load the tour steps
+        if (tourSteps[currentQuickSetupClass] == undefined || tourSteps[currentQuickSetupClass].length == 0){
+            //This tour is not defined or empty
+            let notFound = tourStepFactory({
+                title: "😭 Tour not found",
+                desc: "Seems you are requesting a tour that has not been developed yet. Check back on later!"
+            });
+            notFound();
+
+            //Enable the finish button
+            $("#tourModal .nextStepAvaible").hide();
+            $("#tourModal .nextStepFinish").show();
+            return;
+        }else{
+            tourSteps[currentQuickSetupClass][0]();
+        }
+        
+        updateTourStepCount();
+        
+        //Disable the previous button
+        if (tourSteps[currentQuickSetupClass].length == 1){
+            //There are only 1 step in this tour
+            $("#tourModal .nextStepAvaible").hide();
+            $("#tourModal .nextStepFinish").show();
+        }else{
+            $("#tourModal .nextStepAvaible").show();
+            $("#tourModal .nextStepFinish").hide();
+        }
+        $("#tourModal .tourStepButtonPrevious").addClass("disabled");
+    }
+
+    function updateTourStepCount(){
+        let tourlistLength = tourSteps[currentQuickSetupClass]==undefined?1:tourSteps[currentQuickSetupClass].length;
+        $("#tourModal .tourStepCounter").text((currentQuickSetupTourStep + 1) + " / " + tourlistLength);
+    }
+
+    function nextStep(){
+        //Add one to the tour steps
+        currentQuickSetupTourStep++;
+        if (currentQuickSetupTourStep == tourSteps[currentQuickSetupClass].length - 1){
+            //Already the last step
+            $("#tourModal .nextStepAvaible").hide();
+            $("#tourModal .nextStepFinish").show();
         }
+        updateTourStepCount();
+        tourSteps[currentQuickSetupClass][currentQuickSetupTourStep]();
+        if (currentQuickSetupTourStep > 0){
+            $("#tourModal .tourStepButtonPrevious").removeClass("disabled");
+        }
+    }
 
-        alert(currentQuickSetupClass);
+    //End tour
+    function endTourFocus(){
+        $(".tourFocusObject").removeClass("tourFocusObject");
+        $(".serviceOption.active").removeClass("active");
+        currentQuickSetupClass = "";
+        currentQuickSetupTourStep = 0;
+        $("#tourModal").hide();
+        $("#tourModal .nextStepAvaible").show();
+        $("#tourModal .nextStepFinish").hide();
+        $("#tourModalOverlay").hide();
     }
 
-</script>
+</script>
+<script src="script/quicksetup.js"></script>

+ 17 - 1
web/index.html

@@ -37,7 +37,7 @@
             <div class="toolbar">
                 <div id="mainmenu" class="ui secondary vertical menu">
                     <a class="item" tag="qstart">
-                        <i class="simplistic magic icon"></i>Quick Setup
+                        <i class="simplistic magic icon"></i>Quick Start
                     </a>
                     <a class="item active" tag="status">
                         <i class="simplistic info circle icon"></i>Status
@@ -177,6 +177,22 @@
                 <div class="questionToConfirm">Confirm Exit?</div>
             </div>
         </div>
+
+        <div id="tourModal" class="nofocus" position="center">
+            <h4 class="tourStepTitle">Welcome to Zoraxy Tour</h4>
+            <p class="tourStepContent">This is a simplified tour to show some of what it can do.
+                Use your keyboard or click the next button to get going.</p>
+            <div class="ui divider"></div>
+            <div class="ui equal width grid" align="center">
+                <div class="column"><button class="ui basic small disabled button tourStepButtonBack">Back</button></div>
+                <div class="column"><p style="margin-top: 0.4em">Steps <span class="tourStepCounter">1 / 9</span></p></div>
+                <div class="column nextStepAvaible"><button onclick="nextStep();" class="ui basic right floated small button tourStepButtonNext">Next</button></div>
+                <div class="column nextStepFinish"><button onclick="endTourFocus();" class="ui right floated small button tourStepButtonFinish">Finish</button></div>
+            </div>
+            <button onclick="endTourFocus();" class="ui circular small icon button tourCloseButton"><i class="ui times icon"></i></button>
+        </div>
+        <div id="tourModalOverlay" style="display:none;"></div>
+
         <br><br>
         <script>
             $(".year").text(new Date().getFullYear());

+ 81 - 0
web/main.css

@@ -518,6 +518,14 @@ body{
     display:none;
   }
 
+/* 
+  Default Site
+*/
+
+#setroot{
+    border-radius: 0.6em;
+}
+
 /*
   HTTP Proxy & Virtual Directory
 */
@@ -784,4 +792,77 @@ body{
 #quickstart .finished.ui.button{
     background: var(--theme_green);
     color: white;
+}
+
+#tourModal{
+    background-color: white;
+    border-radius: 0.6em;
+    padding: 1.4em;
+    position: fixed;
+    z-index: 999;
+    width: 340px;
+    display:none;
+    border: 1px solid rgb(230, 230, 230);
+}
+
+/* Locations of tourModal */
+#tourModal[position="center"]{
+    top: 200px;
+    left: calc(50% - 170px);
+}
+
+#tourModal[position="topleft"]{
+    top: 4em;
+    left: 4em;
+}
+
+#tourModal[position="topright"]{
+    top: 4em;
+    right: 4em;
+}
+
+#tourModal[position="bottomleft"]{
+    bottom: 4em;
+    left: 4em;
+}
+
+#tourModal[position="bottomright"]{
+    bottom: 4em;
+    right: 4em;
+}
+
+
+#tourModal .tourStepButtonFinish{
+    background: var(--theme_green) !important;
+    color: white;
+}
+
+
+#tourModal .tourCloseButton{
+    position: absolute;
+    top: 0em;
+    right: 0em;
+    margin-top: -0.6em;
+    margin-right: -0.6em;
+}
+
+#tourModal .nextStepFinish{
+    display: none;
+}
+
+#tourModal.nofocus{
+    box-shadow: 0 0 0 max(100vh, 100vw) rgba(0, 0, 0, .3);
+}
+
+
+#tourModalOverlay{
+    position: fixed;
+    top: 10em;
+    left: 10em;
+    width: 300px;
+    height: 200px;
+    pointer-events: none;
+    z-index: 199;
+    border-radius: 0.6em;
+    box-shadow: 0 0 0 max(100vh, 100vw) rgba(0, 0, 0, .3);
 }

+ 116 - 0
web/script/quicksetup.js

@@ -0,0 +1,116 @@
+/* 
+    Quick Setup Tour
+
+    This script file contains all the required script
+    for quick setup tour and walkthrough
+*/
+
+//tourStepFactory generate a function that renders the steps in tourModal
+//Keys: element, title, desc, tab, zone, callback
+//      elements -> Elements to focus on
+//      tab -> Tab ID to switch pages
+//      pos -> Where to display the tour modal, {topleft, topright, bottomleft, bottomright, center}
+
+function adjustTourModalOverlayToElement(element){
+    $("#tourModalOverlay").css({
+        "top": $(element).offset().top,
+        "left": $(element).offset().left,
+        "width": $(element).width(),
+        "height": $(element).height(),
+    })
+}
+
+function tourStepFactory(config){
+    return function(){
+         //Check if this step require tab swap
+         if (config.tab != undefined && config.tab != ""){
+            //This tour require tab swap. call to openTabById
+            openTabById(config.tab);
+        }
+        
+        if (config.element == undefined){
+            //No focused element in this step.
+            $(".tourFocusObject").removeClass("tourFocusObject");
+            $("#tourModal").addClass("nofocus");
+            $("#tourModalOverlay").hide();
+        }else{
+            //Consists of focus element in this step
+            $(".tourFocusObject").removeClass("tourFocusObject");
+            $(config.element).addClass("tourFocusObject");
+            $("#tourModal").removeClass("nofocus");
+
+            //Match the overlay to element position and size
+            $(window).off("resize").on("resize", function(){
+                adjustTourModalOverlayToElement(config.element);
+            })
+            adjustTourModalOverlayToElement(config.element);
+            $("#tourModalOverlay").show();
+        }
+
+       
+
+        //Get the modal location of this step
+        let showupZone = "center";
+        if (config.pos != undefined){
+            showupZone = config.pos
+        }
+
+        $("#tourModal").attr("position", showupZone);
+
+        $("#tourModal .tourStepTitle").html(config.title);
+        $("#tourModal .tourStepContent").html(config.desc);
+        if (config.callback != undefined){
+            config.callback();
+        }
+    }
+}
+
+var tourSteps = {
+    //Homepage steps
+    "homepage": [
+        tourStepFactory({
+            title: "🎉 Congratulation on your first site!",
+            desc: "In this tour, you will be guided through the steps required to setup a basic static website using your own domain name with Zoraxy."
+        }),
+        tourStepFactory({
+            title: "Pointing your domain's DNS to Zoraxy's IP",
+            desc: `Setup a DNS A Record that points your domain name to this Zoraxy instances public IP address. <br>
+            Assume your public IP is 93.184.215.14, you should have an A record like this.
+            <table class="ui celled collapsing basic striped table">
+                <thead>
+                    <tr>
+                        <th>Name</th>
+                        <th>Type</th>
+                        <th>Value</th>
+                    </tr>   
+                </thead>
+                <tbody>
+                    <tr>
+                        <td>yourdomain.com</td>
+                        <td>A</td>
+                        <td>93.184.215.14</td>
+                    </tr>
+                </tbody>
+            </table>
+            <br>If the IP of Zoraxy start from 192.168, you might want to use your router's public IP address and setup port forward for both port 80 and 443 as well.`,
+            
+        }),
+        tourStepFactory({
+            title: "Setup Default Site",
+            desc: `If you already have an apache or nginx web server running, use "Reverse Proxy Target". <br>Otherwise, pick "Internal Static Web Server" and click "Apply Change"`,
+            tab: "setroot",
+            element: $("#setroot"),
+            pos: "bottomright"
+        })
+    ],
+
+    //Subdomains tour steps
+    "subdomain":[
+
+    ],
+
+    //TLS and ACME tour steps
+    "tls":[
+
+    ],
+}